├── .gitignore ├── .editorconfig ├── index.js ├── logo.png ├── test ├── sass │ ├── empty.scss │ ├── partial │ │ ├── empty.scss │ │ ├── sample-cr.scss │ │ ├── sample.scss │ │ └── sample-crlf.scss │ ├── overview.md │ ├── sample-cr.scss │ ├── sample.scss │ └── sample-crlf.scss ├── helper │ └── template-helper.js ├── render │ └── render.js ├── parser │ └── parser.js ├── const │ └── pattern.js └── frontnote.js ├── .istanbul.yml ├── template ├── assets │ ├── images │ │ ├── favicon.ico │ │ └── frontnote.png │ ├── fonts │ │ ├── FontAwesome.otf │ │ ├── fontawesome-webfont.eot │ │ ├── fontawesome-webfont.ttf │ │ └── fontawesome-webfont.woff │ ├── js │ │ ├── ripple-effect.js │ │ └── main.js │ ├── lib │ │ ├── jquery.mousewheel.js │ │ ├── highlight.pack.js │ │ └── jquery.js │ └── css │ │ └── style.css └── index.ejs ├── styleguide.md ├── codeclimate.yml ├── lib ├── helper │ └── template-helper.js ├── const │ ├── options.js │ └── pattern.js ├── render │ └── render.js ├── frontnote.js ├── generator │ └── generator.js └── parser │ └── parser.js ├── .travis.yml ├── .eslintrc ├── LICENSE ├── package.json ├── bin └── index.js ├── README.md └── CHANGELOG.md /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | guide 3 | coverage 4 | .idea -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | [*.js] 2 | indent_style = space 3 | indent_size = 4 4 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | module.exports = require('./lib/frontnote'); -------------------------------------------------------------------------------- /logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/frontainer/frontnote/HEAD/logo.png -------------------------------------------------------------------------------- /test/sass/empty.scss: -------------------------------------------------------------------------------- 1 | // empty 2 | .test { 3 | font-size: 14px; 4 | } -------------------------------------------------------------------------------- /test/sass/partial/empty.scss: -------------------------------------------------------------------------------- 1 | // empty 2 | .test { 3 | font-size: 14px; 4 | } -------------------------------------------------------------------------------- /.istanbul.yml: -------------------------------------------------------------------------------- 1 | instrumentation: 2 | excludes: ['node_modules'] 3 | reporting: 4 | #print: none 5 | reports: 6 | - html -------------------------------------------------------------------------------- /template/assets/images/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/frontainer/frontnote/HEAD/template/assets/images/favicon.ico -------------------------------------------------------------------------------- /template/assets/images/frontnote.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/frontainer/frontnote/HEAD/template/assets/images/frontnote.png -------------------------------------------------------------------------------- /styleguide.md: -------------------------------------------------------------------------------- 1 | # ![FrontNote](./assets/images/frontnote.png) 2 | 3 | Generated by [FrontNote](https://github.com/frontainer/frontnote) -------------------------------------------------------------------------------- /template/assets/fonts/FontAwesome.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/frontainer/frontnote/HEAD/template/assets/fonts/FontAwesome.otf -------------------------------------------------------------------------------- /template/assets/fonts/fontawesome-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/frontainer/frontnote/HEAD/template/assets/fonts/fontawesome-webfont.eot -------------------------------------------------------------------------------- /template/assets/fonts/fontawesome-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/frontainer/frontnote/HEAD/template/assets/fonts/fontawesome-webfont.ttf -------------------------------------------------------------------------------- /template/assets/fonts/fontawesome-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/frontainer/frontnote/HEAD/template/assets/fonts/fontawesome-webfont.woff -------------------------------------------------------------------------------- /test/sass/overview.md: -------------------------------------------------------------------------------- 1 | # title 2 | 3 | ## sub title 4 | 5 | overview text. 6 | 7 | ```js 8 | function() { 9 | alert(''); 10 | } 11 | ``` -------------------------------------------------------------------------------- /codeclimate.yml: -------------------------------------------------------------------------------- 1 | engines: 2 | eslint: 3 | enabled: true 4 | duplication: 5 | enabled: false 6 | config: 7 | languages: 8 | - javascript 9 | ratings: 10 | paths: 11 | - lib/** 12 | exclude_paths: 13 | - test/** 14 | -------------------------------------------------------------------------------- /test/sass/sample-cr.scss: -------------------------------------------------------------------------------- 1 | /* #overview sample.scss 改行コードCR overview comment */ /* #styleguide style title style comment. @depulicated @非推奨 @todo @your-attribute ``` sample code here. ``` */ /* #colors @primary #996600 @secondary #333 @color-name color-code */ -------------------------------------------------------------------------------- /test/sass/partial/sample-cr.scss: -------------------------------------------------------------------------------- 1 | /* #overview sample.scss 改行コードCR overview comment */ /* #styleguide style title style comment. @depulicated @非推奨 @todo @your-attribute ``` sample code here. ``` */ /* #colors @primary #996600 @secondary #333 @color-name color-code */ -------------------------------------------------------------------------------- /lib/helper/template-helper.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | const HELPER = { 3 | // currentファイルかどうか 4 | isCurrent(current,file) { 5 | return (current.file === file.file); 6 | }, 7 | // 指定した属性が含まれているかどうか 8 | hasAttribute(attributes,attr) { 9 | return (attributes.indexOf(attr) !== -1); 10 | } 11 | }; 12 | module.exports = HELPER; -------------------------------------------------------------------------------- /test/sass/sample.scss: -------------------------------------------------------------------------------- 1 | /* 2 | #overview 3 | sample.scss 4 | 5 | overview comment 6 | */ 7 | 8 | /* 9 | #styleguide 10 | style title 11 | 12 | style comment. 13 | 14 | @depulicated 15 | @非推奨 16 | @todo 17 | @your-attribute 18 | 19 | ``` 20 | sample code here. 21 | ``` 22 | */ 23 | 24 | /* 25 | #colors 26 | 27 | @primary #996600 28 | @secondary #333 29 | @color-name color-code 30 | */ -------------------------------------------------------------------------------- /lib/const/options.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | overview: __dirname + '/../../styleguide.md', 3 | template: __dirname + '/../../template/index.ejs', 4 | includeAssetPath: __dirname + '/../../template/assets/**/*', 5 | css: './style.css', 6 | script: null, 7 | out: './guide', 8 | title: 'StyleGuide', 9 | verbose: false, 10 | clean: false, 11 | params: {} 12 | }; -------------------------------------------------------------------------------- /test/sass/partial/sample.scss: -------------------------------------------------------------------------------- 1 | /* 2 | #overview 3 | sample.scss 4 | 5 | overview comment 6 | */ 7 | 8 | /* 9 | #styleguide 10 | style title 11 | 12 | style comment. 13 | 14 | @depulicated 15 | @非推奨 16 | @todo 17 | @your-attribute 18 | 19 | ``` 20 | sample code here. 21 | ``` 22 | */ 23 | 24 | /* 25 | #colors 26 | 27 | @primary #996600 28 | @secondary #333 29 | @color-name color-code 30 | */ -------------------------------------------------------------------------------- /test/sass/sample-crlf.scss: -------------------------------------------------------------------------------- 1 | /* 2 | #overview 3 | sample.scss 改行コードCRLF 4 | 5 | overview comment 6 | */ 7 | 8 | /* 9 | #styleguide 10 | style title 11 | 12 | style comment. 13 | 14 | @depulicated 15 | @非推奨 16 | @todo 17 | @your-attribute 18 | ``` 19 | 20 | sample code here. 21 | ``` 22 | */ 23 | 24 | /* 25 | #colors 26 | 27 | @primary #996600 28 | @secondary #333 29 | @color-name color-code 30 | */ -------------------------------------------------------------------------------- /test/sass/partial/sample-crlf.scss: -------------------------------------------------------------------------------- 1 | /* 2 | #overview 3 | sample.scss 改行コードCRLF 4 | 5 | overview comment 6 | */ 7 | 8 | /* 9 | #styleguide 10 | style title 11 | 12 | style comment. 13 | 14 | @depulicated 15 | @非推奨 16 | @todo 17 | @your-attribute 18 | ``` 19 | 20 | sample code here. 21 | ``` 22 | */ 23 | 24 | /* 25 | #colors 26 | 27 | @primary #996600 28 | @secondary #333 29 | @color-name color-code 30 | */ -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: false 2 | language: node_js 3 | node_js: 4 | - '7' 5 | - '6' 6 | - '5' 7 | addons: 8 | code_climate: 9 | repo_token: 3b1b8a63197add999a34a21b2ec13ae89f37338e4f9deba54c4d55ad445f3425 10 | after_script: 11 | - codeclimate < lcov.info 12 | notifications: 13 | slack: 14 | secure: U3U8YuPeFmE64C9W0eRW4z2Tnz7eOwVIvEAb0Fh6+Kfr3zKvqeyY1VItkEOUpZSP9M7Rw5TF/7yRpQgRTSfyW2Up+xYEOiSWq9NrOcGAgiLh9AwwRXoEUv12eCVsJvmg+XPAExc2O1eFKVlp0gMiyihFSPh+7ky23Ms0fs69M+8= 15 | -------------------------------------------------------------------------------- /lib/const/pattern.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | comment: /\/\*+\s*#styleguide([^*]|\*[^/])*\*+\//g, 3 | overview: /\/\*+\s*#overview([^*]|\*[^/])*\*+\//g, 4 | colors: /\/\*+\s*#colors([^*]|\*[^/])*\*+\//g, 5 | color: /@(.+)\s+(.+)$/, 6 | splitter: /\n|\r/, 7 | prefix: /(^\/\*+\s*\n*(#styleguide|#overview)?)|(\n*\s*\*+\/$)/gm, 8 | line: /^\s*$/gm, 9 | attr: /^\s*\t*@.+$/gm, 10 | attrPrefix: /^\s*\t*@/, 11 | code: /```(.|\s)+```/g, 12 | codeWrapper: /(```)\n?/g 13 | }; -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "node": true, 4 | "es6": true 5 | }, 6 | "rules": { 7 | "brace-style": [2, "1tbs", { "allowSingleLine": true }], 8 | "comma-dangle": [2, "never"], 9 | "comma-style": [2, "first", { 10 | "exceptions": { 11 | "ArrayExpression": true, 12 | "ObjectExpression": true 13 | } 14 | }], 15 | "complexity": [2, 6], 16 | "curly": 2, 17 | "eqeqeq": [2, "allow-null"], 18 | "max-statements": [2, 30], 19 | "no-shadow-restricted-names": 2, 20 | "no-undef": 2, 21 | "no-use-before-define": 2, 22 | "radix": 2, 23 | "semi": 2, 24 | "space-infix-ops": 2, 25 | "strict": 0 26 | }, 27 | "globals": { 28 | "AnalysisView": true, 29 | "PollingView": true, 30 | "Prism": true, 31 | "Spinner": true, 32 | "Timer": true, 33 | "moment": true 34 | } 35 | } -------------------------------------------------------------------------------- /test/helper/template-helper.js: -------------------------------------------------------------------------------- 1 | var assert = require('power-assert'); 2 | var Helper = require('../../lib/helper/template-helper'); 3 | 4 | module.exports = function() { 5 | describe('template-helper', function() { 6 | it('isCurrent', function() { 7 | var same = Helper.isCurrent({ 8 | file:'sample.scss' 9 | },{ 10 | file:'sample.scss' 11 | }); 12 | assert(same === true); 13 | var unsame = Helper.isCurrent({ 14 | file:'sample.scss' 15 | },{ 16 | file:'sample2.scss' 17 | }); 18 | assert(unsame === false); 19 | }); 20 | it ('hasAttribute', function() { 21 | var have = Helper.hasAttribute(['test'],'test'); 22 | assert(have === true); 23 | 24 | var noHave = Helper.hasAttribute(['test'],'test2'); 25 | assert(noHave === false); 26 | }); 27 | }); 28 | }; -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Frontainer 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /template/assets/js/ripple-effect.js: -------------------------------------------------------------------------------- 1 | $.fn.rippleEffect=function(){function t(t){if("touchstart"===t.type)r=!0;else if(r)return void(r=!1);var e=$(this),i=t.originalEvent,p=i.touches?i.touches[0].pageX:t.pageX,a=i.touches?i.touches[0].pageY:t.pageY,o=e.offset(),c=parseInt(p-o.left),n=parseInt(a-o.top),l=e.find("svg");if(0!==l.length){var s=l.data("ripple");s&&(s.stop(),l.data("ripple",null)),l.remove()}e.append('');var f=e.find("circle"),u=$({r:.8,op:1}).animate({r:e.outerWidth(),op:1},{easing:"swing",duration:250,step:function(t,e){"op"===e.prop?f.attr("fill-opacity",t):f.attr(e.prop,t)}});f.data("ripple",u)}function e(t){var e=$(this),i=e.find("svg.fn-ripple");if($circle=i.find("circle"),0!==$circle.length){{var r=$circle.data("ripple");parseInt($circle.attr("r"))}r.stop(!0,!1).animate({r:e.outerWidth(),op:0},{easing:"swing",duration:250,step:function(t,e){"op"===e.prop?$circle.attr("fill-opacity",t):$circle.attr(e.prop,t)},complete:function(){i.remove()}})}}var i=$(this);i.css({tapHighlightColor:"rgba(0,0,0,0)"});var r=!1;i.on("mousedown touchstart",t),i.on("mouseup touchend",e)}; -------------------------------------------------------------------------------- /test/render/render.js: -------------------------------------------------------------------------------- 1 | var assert = require('power-assert'); 2 | var Render = require('../../lib/render/render'); 3 | 4 | 5 | module.exports = function() { 6 | describe('render', function() { 7 | var render; 8 | beforeEach(function() { 9 | render = new Render(); 10 | }); 11 | it('generateIncludeCss', function() { 12 | assert(render.generateIncludeCss('main.css'),''); 13 | var css = render.generateIncludeCss([ 14 | 'main.css', 15 | 'style.css', 16 | 'sub.css' 17 | ]); 18 | assert(css == '\n\n'); 19 | }); 20 | it('generateIncludeScript', function() { 21 | assert(render.generateIncludeScript('main.js'),''); 22 | var js = render.generateIncludeScript([ 23 | 'main.js', 24 | 'style.js', 25 | 'sub.js' 26 | ]); 27 | assert(js == '\n\n'); 28 | }); 29 | }); 30 | }; -------------------------------------------------------------------------------- /template/assets/js/main.js: -------------------------------------------------------------------------------- 1 | !function(){function n(){$(this).attr("contentEditable",!1)}function o(n){n.preventDefault();var o=$(this).siblings(".fn-code");o.attr("contentEditable",!0),o.focus(),document.execCommand&&document.execCommand("selectAll",!1,null)}function e(){c.trigger("mousewheel"),r.on("blur",".fn-code",n),r.on("click",".fn-pre .fn-icon",o),$(".fn-menu, .fn-bars").rippleEffect(),$(".fn-drawer-trigger").on("click",function(n){n.preventDefault(),u.hasClass("fn-overflow")?t():s()}),$(".fn-content").on("touchstart mousedown",function(n){u.hasClass("fn-overflow")&&t()});var e=$('
');u.append(e),$(".fn-preview > *").on("mouseenter",function(n){this.className&&e.html(this.className)}).on("mousemove",function(n){this.className&&e.stop().fadeIn(i).css({top:n.clientY+f,left:n.clientX+l})}).on("mouseleave",function(n){e.stop().fadeOut(i)}),d.on("click",function(n){n.preventDefault(),d.removeClass("fn-show"),$("html,body").animate({scrollTop:0},a,"swing")}),hljs.initHighlightingOnLoad()}function t(){u.removeClass("fn-overflow")}function s(){u.addClass("fn-overflow")}var l=10,f=10,i=200,a=450,c=$(window),r=$(document),u=$(document.body),d=$(".fn-pagetop"),m=!1;c.on("resize",function(n){var o=c.width();o>680&&u.hasClass("fn-overflow")&&u.removeClass("fn-overflow")}),c.on("mousewheel",function(n){0!==c.scrollTop()?m||(d.addClass("fn-show"),m=!0):m&&(d.removeClass("fn-show"),m=!1)}),e()}(); -------------------------------------------------------------------------------- /lib/render/render.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const TemplateHelper = require('../helper/template-helper'); 4 | const ejs = require('ejs'); 5 | 6 | const CSS = ''; 7 | const SCRIPT = ''; 8 | 9 | class Render { 10 | render(template, params) { 11 | //EJSを使ってテンプレートレンダリング 12 | params.helpers = TemplateHelper; 13 | return ejs.render(template, params); 14 | } 15 | 16 | /** 17 | * HTMLに追加読み込みするファイルパスまたはパスが入った配列からタグを生成 18 | * @param type(css|script) 19 | * @param arr 20 | * @return {string|array} 21 | */ 22 | generateInclude(type, data) { 23 | if (!data) return ''; 24 | let template = SCRIPT; 25 | if (type === 'css') { 26 | template = CSS; 27 | } 28 | if (typeof data === 'string') { 29 | return ejs.render(template, {src: data}); 30 | } 31 | let result = data.map((d) => { 32 | return ejs.render(template, {src: d}); 33 | }); 34 | return result.join('\n'); 35 | } 36 | 37 | /** 38 | * HTMLに追加読み込みするCSSファイルパスまたはパスが入った配列からタグを生成 39 | * @param arr 40 | * @return {string|array} 41 | */ 42 | generateIncludeCss(arr) { 43 | return this.generateInclude('css', arr); 44 | } 45 | 46 | /** 47 | * HTMLに追加読み込みするJSファイルパスまたはパスが入った配列からタグを生成 48 | * @param arr {string|array} 49 | */ 50 | generateIncludeScript(arr) { 51 | return this.generateInclude('script', arr); 52 | } 53 | } 54 | module.exports = Render; -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "frontnote", 3 | "version": "2.0.5", 4 | "description": "StyleGuide Generator FrontNote", 5 | "license": "MIT", 6 | "repository": { 7 | "type": "git", 8 | "url": "git://github.com/frontainer/frontnote" 9 | }, 10 | "author": "frontainer (http://frontainer.com)", 11 | "engines": { 12 | "node": ">=5.0.0" 13 | }, 14 | "bin": { 15 | "frontnote": "./bin/index.js" 16 | }, 17 | "scripts": { 18 | "changelog": "conventional-changelog -p eslint -i CHANGELOG.md -w -s -r 0", 19 | "test": "./node_modules/.bin/istanbul cover ./node_modules/.bin/_mocha -- --require intelli-espower-loader -R spec ./test/frontnote.js" 20 | }, 21 | "keywords": [ 22 | "styleguide", 23 | "sass", 24 | "less", 25 | "stylus", 26 | "css", 27 | "ejs" 28 | ], 29 | "dependencies": { 30 | "chalk": "^1.1.3", 31 | "commander": "^2.9.0", 32 | "cpx": "^1.5.0", 33 | "ejs": "^2.5.2", 34 | "extend": "^3.0.0", 35 | "fs-extra": "^0.30.0", 36 | "gaze": "^1.1.2", 37 | "glob": "^7.1.0", 38 | "marked": "^0.3.6", 39 | "memory-cache": "^0.1.6", 40 | "ora": "^0.3.0", 41 | "rxjs": "^5.0.0-beta.12", 42 | "sanitizer": "^0.1.3" 43 | }, 44 | "devDependencies": { 45 | "conventional-changelog-cli": "^1.2.0", 46 | "espower-loader": "^1.0.1", 47 | "intelli-espower-loader": "^1.0.1", 48 | "istanbul": "^0.4.5", 49 | "mocha": "^3.1.0", 50 | "power-assert": "^1.4.1" 51 | }, 52 | "bugs": { 53 | "url": "https://github.com/frontainer/frontnote/issues" 54 | }, 55 | "homepage": "https://github.com/frontainer/frontnote", 56 | "main": "index.js" 57 | } 58 | -------------------------------------------------------------------------------- /bin/index.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 'use strict'; 3 | 4 | const extend = require('extend'); 5 | const program = require('commander'); 6 | const path = require('path'); 7 | const gaze = require('gaze'); 8 | const pkg = require('../package.json'); 9 | const DEFAULT_OPTION = require('../lib/const/options'); 10 | const frontnote = require('../lib/frontnote'); 11 | 12 | program._name = 'frontnote'; 13 | program 14 | .version(pkg.version) 15 | .description('Frontnote CLI') 16 | .usage(' [options]') 17 | .option('-C, --clean', 'clean dest directory') 18 | .option('-c, --config [path]', 'config file path') 19 | .option('-t, --template [path]', 'template file path') 20 | .option('-a, --assets [path]', 'assets file path') 21 | .option('-v, --verbose', 'verbose') 22 | .option('-o, --overview [path]', 'overview markdown file path') 23 | .option('-w, --watch', 'watch files'); 24 | program.parse(process.argv); 25 | 26 | let options = extend({},DEFAULT_OPTION); 27 | if (program.config) { 28 | let file = require(path.join(process.cwd(),program.config)); 29 | options = extend(options,file); 30 | } 31 | 32 | let args = program.args; 33 | if (args.length < 1) throw new Error('At least one argument'); 34 | if (args[1]) options.out = args[1]; 35 | if (program.clean) options.clean = program.clean; 36 | if (program.overview) options.overview = program.overview; 37 | if (program.template) options.template = program.template; 38 | if (program.assets) options.assets = program.assets; 39 | if (program.verbose) options.verbose = program.verbose; 40 | 41 | let fn = new frontnote(options); 42 | let pattern = path.join(process.cwd(), args[0]); 43 | 44 | if (program.watch) { 45 | gaze(pattern, (err, watcher) => { 46 | watcher.on('all', function(filepath) { 47 | fn.render(pattern).subscribe(() => { 48 | }, (e) => { 49 | console.error(e); 50 | }); 51 | }); 52 | }); 53 | } else { 54 | fn.render(pattern).subscribe((result) => { 55 | }, (e) => { 56 | console.error(e); 57 | }); 58 | } -------------------------------------------------------------------------------- /test/parser/parser.js: -------------------------------------------------------------------------------- 1 | var assert = require('power-assert'); 2 | var Parser = require('../../lib/parser/parser'); 3 | 4 | var sampleFile = '../test/sass/sample.scss'; 5 | var sampleText = '/*\n#styleguide\nstyle title\n\nstyle comment.\n\n@depulicated\n@非推奨\n@todo\n@your-attribute\n\n```\nsample code here.\n```\n*/\n\n/*\n#colors\n\n@primary #996600\n@secondary #333\n@color-name color-code\n*/'; 6 | 7 | var sampleFile2 = '../test/sass/sample2.scss'; 8 | var sampleText2 = '/*\n#overview\ntest\n\n## overview title\n*/'; 9 | 10 | module.exports = function() { 11 | describe('Parser', function() { 12 | var parser; 13 | beforeEach(function() { 14 | parser = new Parser(); 15 | }); 16 | it('parse', function() { 17 | var result = parser.parse(sampleFile,sampleText); 18 | assert(result.fileName === 'sample'); 19 | assert(result.url === 'test-sass-sample.html'); 20 | 21 | assert(result.ext === '.scss'); 22 | assert.deepEqual(result.dirs,['..','test','sass','sample.scss']); 23 | 24 | assert(result.sections[0].title === 'style title'); 25 | assert(result.sections[0].comment === 'style comment.'); 26 | assert(result.sections[0].code === 'sample code here.\n'); 27 | 28 | assert.deepEqual(result.sections[0].attributes, ["depulicated","非推奨","todo","your-attribute"]); 29 | 30 | assert(result.colors[0].name === 'primary'); 31 | assert(result.colors[0].color === '#996600'); 32 | 33 | assert(result.colors[1].name === 'secondary'); 34 | assert(result.colors[1].color === '#333'); 35 | }); 36 | 37 | it('parse overview', function() { 38 | var result = parser.parse(sampleFile2,sampleText2); 39 | assert(result.fileName === 'sample2'); 40 | assert(result.url === 'test-sass-sample2.html'); 41 | 42 | assert(result.ext === '.scss'); 43 | assert.deepEqual(result.dirs,['..','test','sass','sample2.scss']); 44 | 45 | assert(result.sections === null); 46 | 47 | assert(result.overview.title === 'test'); 48 | assert(result.overview.comment === '## overview title'); 49 | assert.deepEqual(result.overview.attributes,[]); 50 | assert(result.overview.code === null); 51 | 52 | assert(result.colors === null); 53 | }); 54 | }); 55 | }; -------------------------------------------------------------------------------- /template/assets/lib/jquery.mousewheel.js: -------------------------------------------------------------------------------- 1 | /*! Copyright (c) 2013 Brandon Aaron (http://brandon.aaron.sh) 2 | * Licensed under the MIT License (LICENSE.txt). 3 | * 4 | * Version: 3.1.12 5 | * 6 | * Requires: jQuery 1.2.2+ 7 | */ 8 | !function(e){"function"==typeof define&&define.amd?define(["jquery"],e):"object"==typeof exports?module.exports=e:e(jQuery)}(function(e){function t(t){var s=t||window.event,a=h.call(arguments,1),r=0,f=0,d=0,c=0,m=0,g=0;if(t=e.event.fix(s),t.type="mousewheel","detail"in s&&(d=-1*s.detail),"wheelDelta"in s&&(d=s.wheelDelta),"wheelDeltaY"in s&&(d=s.wheelDeltaY),"wheelDeltaX"in s&&(f=-1*s.wheelDeltaX),"axis"in s&&s.axis===s.HORIZONTAL_AXIS&&(f=-1*d,d=0),r=0===d?f:d,"deltaY"in s&&(d=-1*s.deltaY,r=d),"deltaX"in s&&(f=s.deltaX,0===d&&(r=-1*f)),0!==d||0!==f){if(1===s.deltaMode){var w=e.data(this,"mousewheel-line-height");r*=w,d*=w,f*=w}else if(2===s.deltaMode){var v=e.data(this,"mousewheel-page-height");r*=v,d*=v,f*=v}if(c=Math.max(Math.abs(d),Math.abs(f)),(!l||l>c)&&(l=c,i(s,c)&&(l/=40)),i(s,c)&&(r/=40,f/=40,d/=40),r=Math[r>=1?"floor":"ceil"](r/l),f=Math[f>=1?"floor":"ceil"](f/l),d=Math[d>=1?"floor":"ceil"](d/l),u.settings.normalizeOffset&&this.getBoundingClientRect){var p=this.getBoundingClientRect();m=t.clientX-p.left,g=t.clientY-p.top}return t.deltaX=f,t.deltaY=d,t.deltaFactor=l,t.offsetX=m,t.offsetY=g,t.deltaMode=0,a.unshift(t,r,f,d),o&&clearTimeout(o),o=setTimeout(n,200),(e.event.dispatch||e.event.handle).apply(this,a)}}function n(){l=null}function i(e,t){return u.settings.adjustOldDeltas&&"mousewheel"===e.type&&t%120===0}var o,l,s=["wheel","mousewheel","DOMMouseScroll","MozMousePixelScroll"],a="onwheel"in document||document.documentMode>=9?["wheel"]:["mousewheel","DomMouseScroll","MozMousePixelScroll"],h=Array.prototype.slice;if(e.event.fixHooks)for(var r=s.length;r;)e.event.fixHooks[s[--r]]=e.event.mouseHooks;var u=e.event.special.mousewheel={version:"3.1.12",setup:function(){if(this.addEventListener)for(var n=a.length;n;)this.addEventListener(a[--n],t,!1);else this.onmousewheel=t;e.data(this,"mousewheel-line-height",u.getLineHeight(this)),e.data(this,"mousewheel-page-height",u.getPageHeight(this))},teardown:function(){if(this.removeEventListener)for(var n=a.length;n;)this.removeEventListener(a[--n],t,!1);else this.onmousewheel=null;e.removeData(this,"mousewheel-line-height"),e.removeData(this,"mousewheel-page-height")},getLineHeight:function(t){var n=e(t),i=n["offsetParent"in e.fn?"offsetParent":"parent"]();return i.length||(i=e("body")),parseInt(i.css("fontSize"),10)||parseInt(n.css("fontSize"),10)||16},getPageHeight:function(t){return e(t).height()},settings:{adjustOldDeltas:!0,normalizeOffset:!0}};e.fn.extend({mousewheel:function(e){return e?this.bind("mousewheel",e):this.trigger("mousewheel")},unmousewheel:function(e){return this.unbind("mousewheel",e)}})}); -------------------------------------------------------------------------------- /test/const/pattern.js: -------------------------------------------------------------------------------- 1 | var assert = require('power-assert'); 2 | 3 | module.exports = function() { 4 | describe('Pattern', function() { 5 | var Pattern = require('../../lib/const/pattern'); 6 | it('comment', function() { 7 | assert('/*#styleguide*/'.search(Pattern.comment) !== -1); 8 | assert('/**#styleguide**/'.search(Pattern.comment) !== -1); 9 | assert('/** #styleguide **/'.search(Pattern.comment) !== -1); 10 | assert('/**\n#styleguide\n**/'.search(Pattern.comment) !== -1); 11 | }); 12 | it('overview', function() { 13 | assert('/*#overview*/'.search(Pattern.overview) !== -1); 14 | assert('/**#overview**/'.search(Pattern.overview) !== -1); 15 | assert('/** #overview **/'.search(Pattern.overview) !== -1); 16 | assert('/**\n#overview\n**/'.search(Pattern.overview) !== -1); 17 | }); 18 | 19 | it('colors', function() { 20 | assert('/*#colors*/'.search(Pattern.colors) !== -1); 21 | assert('/**#colors**/'.search(Pattern.colors) !== -1); 22 | assert('/** #colors **/'.search(Pattern.colors) !== -1); 23 | assert('/**\n#colors\n**/'.search(Pattern.colors) !== -1); 24 | }); 25 | 26 | it('color', function() { 27 | assert('@primary #996600'.search(Pattern.color) !== -1); 28 | assert('@primary #996600'.search(Pattern.color) !== -1); 29 | assert('@primary #996600'.search(Pattern.color) !== -1); 30 | assert(' @primary #996600'.search(Pattern.color) !== -1); 31 | }); 32 | 33 | it('spliltter', function() { 34 | assert('test\ntest'.split(Pattern.splitter).length === 2); 35 | assert('test\n\ntest'.split(Pattern.splitter).length === 3); 36 | assert('\ntest\ntest'.split(Pattern.splitter).length === 3); 37 | assert('test'.split(Pattern.splitter).length === 1); 38 | }); 39 | 40 | it('prefix', function() { 41 | assert('/*#styleguide*/'.replace(Pattern.prefix,'') === ''); 42 | assert('/**#styleguide**/'.replace(Pattern.prefix,'') === ''); 43 | assert('/** #styleguide **/'.replace(Pattern.prefix,'') === ''); 44 | assert('/**\n#styleguide\n**/'.replace(Pattern.prefix,'') === ''); 45 | }); 46 | 47 | it('line', function() { 48 | assert(' '.search(Pattern.line) !== -1); 49 | assert(' '.search(Pattern.line) !== -1); 50 | assert(' \n '.search(Pattern.line) !== -1); 51 | assert(' t '.search(Pattern.line) === -1); 52 | }); 53 | 54 | it('attr', function() { 55 | assert('@test'.search(Pattern.attr) !== -1); 56 | assert('test\n@attr'.search(Pattern.attr) !== -1); 57 | assert(' @test'.search(Pattern.attr) !== -1); 58 | assert(' @test'.search(Pattern.attr) !== -1); 59 | assert('test@test\ntest\naaa'.search(Pattern.attr) === -1); 60 | }); 61 | 62 | it('attrPrefix', function() { 63 | assert('@test'.search(Pattern.attrPrefix) !== -1); 64 | assert(' @attr'.search(Pattern.attr) !== -1); 65 | assert(' @attr'.search(Pattern.attr) !== -1); 66 | assert(' test'.search(Pattern.attr) === -1); 67 | }); 68 | 69 | it('code', function() { 70 | 71 | }); 72 | 73 | it('codeWrapper', function() { 74 | 75 | }); 76 | }) 77 | }; -------------------------------------------------------------------------------- /lib/frontnote.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | const path = require('path'), 3 | extend = require('extend'), 4 | Rx = require('rxjs'), 5 | glob = require('glob'), 6 | ora = require('ora'), 7 | chalk = require('chalk'), 8 | fs = require('fs-extra'); 9 | 10 | const Parser = require('./parser/parser'); 11 | const Generator = require('./generator/generator'); 12 | const DEFAULT_OPTIONS = require('./const/options'); 13 | 14 | /** 15 | * FrontNote 16 | * @param target {string|array} 解析するファイルのminimatch形式文字列またはminimatch形式文字列が入った配列 17 | * @param option {object} オプション 18 | * @param callback {callback} 全ての処理が正常に終了したときに実行するコールバック関数 19 | * @constructor 20 | */ 21 | class FrontNote { 22 | constructor(option) { 23 | this.options = extend({},DEFAULT_OPTIONS,option); 24 | this.options.out = path.resolve(this.options.out); 25 | this.Parser = new Parser(); 26 | } 27 | 28 | /** 29 | * render styleguide 30 | * @param target{String|Array} 31 | * @returns {Observable} 32 | */ 33 | render(target) { 34 | const spinner = ora('Loading files...').start(); 35 | let list = typeof target === 'string' ? glob.sync(target) : target.reduce((previous,current) => { 36 | return previous.concat(glob.sync(current)); 37 | },[]); 38 | let obs = this.readFiles(list).map((files) => { 39 | spinner.text = 'Parsing files...'; 40 | return this.parseFiles(files); 41 | }).flatMap((parsedFiles) => { 42 | spinner.text = 'Generating StyleGuide...'; 43 | return this.createStyleGuide(parsedFiles); 44 | }).share(); 45 | obs.take(1).subscribe((result) => { 46 | if (this.options.verbose) { 47 | result.forEach((filepath) => { 48 | console.log(chalk.green(`[w] ${filepath}`)); 49 | }); 50 | } 51 | spinner.text = 'Generated StyleGuide'; 52 | spinner.succeed(); 53 | }); 54 | return obs; 55 | } 56 | readFiles(fileList) { 57 | const observers = fileList.map((filepath) => { 58 | const readFileAsObservable = Rx.Observable.bindNodeCallback(fs.readFile); 59 | return readFileAsObservable(filepath, 'utf8').map((data) => { 60 | return { 61 | file: filepath, 62 | content: data 63 | }; 64 | }); 65 | }); 66 | if (observers.length === 0) { 67 | return Rx.Observable.create(observer => { 68 | observer.next([]); 69 | }); 70 | } 71 | return Rx.Observable.combineLatest(observers); 72 | } 73 | parseFiles(files) { 74 | return files.map((fileData) => { 75 | const value = this.Parser.parse(fileData.file,fileData.content); 76 | if (value) { 77 | return value; 78 | } 79 | }).filter((v) => { 80 | return (v !== undefined); 81 | }); 82 | } 83 | /** 84 | * スタイルガイド作成 85 | * @param data 86 | */ 87 | createStyleGuide(data) { 88 | return Rx.Observable.create(observer => { 89 | const gen = new Generator(data,this.options); 90 | gen.generate().subscribe(result => { 91 | let cwd = process.cwd(); 92 | result = Array.prototype.concat.apply([],result).filter((v) => { 93 | return (v); 94 | }).map((v) => { 95 | return path.relative(cwd,v); 96 | }); 97 | observer.next(result); 98 | },(e) => { 99 | observer.error(e); 100 | }); 101 | }); 102 | } 103 | } 104 | 105 | // プラグイン関数をエクスポート 106 | module.exports = FrontNote; -------------------------------------------------------------------------------- /lib/generator/generator.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | const Rx = require('rxjs'); 3 | const fs = require('fs-extra'); 4 | const cpx = require('cpx'); 5 | const path = require('path'); 6 | const md = require("marked"); 7 | const Render = require('../render/render'); 8 | const helpers = require('../helper/template-helper'); 9 | class Generator { 10 | constructor(data, options) { 11 | this.data = data; 12 | this.options = options; 13 | this.Render = new Render(); 14 | } 15 | 16 | generate() { 17 | return this.cleanOutputDir() 18 | .flatMap(() => { 19 | return this.readFile(this.options.template); 20 | }).flatMap((tmpl) => { 21 | return Rx.Observable.combineLatest( 22 | this.writeOverview(tmpl), 23 | this.writePages(tmpl), 24 | this.copyOtherFiles() 25 | ); 26 | }); 27 | } 28 | 29 | cleanOutputDir() { 30 | return Rx.Observable.create(observer => { 31 | if (!this.options.clean) return observer.next(); 32 | fs.remove(this.options.out, () => { 33 | observer.next(); 34 | }); 35 | }); 36 | } 37 | 38 | readFile(filepath) { 39 | const readFileAsObservable = Rx.Observable.bindNodeCallback(fs.readFile); 40 | return readFileAsObservable(filepath, 'utf8'); 41 | } 42 | writeFile(filepath,content) { 43 | const writeFileAsObservable = Rx.Observable.bindNodeCallback(fs.outputFile); 44 | return writeFileAsObservable(filepath, content).map(() => { 45 | return filepath; 46 | }); 47 | } 48 | copyFile(from,to) { 49 | const copyFileAsObservable = Rx.Observable.bindNodeCallback(cpx.copy); 50 | return copyFileAsObservable(from, to).map(() => { 51 | return to; 52 | }); 53 | } 54 | 55 | writeOverview(tmpl) { 56 | //styleguide.mdを読み込み 57 | return this.readFile(this.options.overview) 58 | .flatMap((file) => { 59 | const outputPath = this.options.out + '/index.html'; 60 | const rendered = this.Render.render(tmpl, { 61 | title: this.options.title, 62 | current: md.parse(file), 63 | files: this.data, 64 | overview: true, 65 | helpers: helpers, 66 | css: this.Render.generateIncludeCss(this.options.css), 67 | script: this.Render.generateIncludeScript(this.options.script), 68 | params: this.options.params || {} 69 | }); 70 | return this.writeFile(outputPath, rendered); 71 | }); 72 | } 73 | 74 | writePages(tmpl) { 75 | let observers = this.data.map((section) => { 76 | const outputPath = this.options.out + '/' + section.url; 77 | const rendered = this.Render.render(tmpl, { 78 | title: this.options.title, 79 | current: section, 80 | files: this.data, 81 | overview: false, 82 | helpers: helpers, 83 | css: this.Render.generateIncludeCss(this.options.css), 84 | script: this.Render.generateIncludeScript(this.options.script), 85 | params: this.options.params || {} 86 | }); 87 | return this.writeFile(outputPath, rendered); 88 | }); 89 | if (observers.length === 0) { 90 | return Rx.Observable.create(observer => { 91 | observer.next(); 92 | }); 93 | } 94 | return Rx.Observable.combineLatest(observers); 95 | } 96 | 97 | copyOtherFiles() { 98 | if (!this.options.includeAssetPath) { 99 | return Rx.Observable.create(observer => { 100 | observer.next([]); 101 | }); 102 | } 103 | let assets = typeof this.options.includeAssetPath === 'string' ? [this.options.includeAssetPath] : this.options.includeAssetPath; 104 | 105 | assets = assets.map((asset) => { 106 | return this.copyFile(asset,path.join(this.options.out,'assets')); 107 | }); 108 | return Rx.Observable.combineLatest(assets); 109 | } 110 | } 111 | module.exports = Generator; -------------------------------------------------------------------------------- /template/index.ejs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | <%=title%> - FrontNote 6 | 7 | 8 | <%- css %> 9 | 10 | 11 |
12 |
13 |

<%=title%>

14 |
15 |
16 | 30 | <% if(overview) {%> 31 |
32 | <%# index.htmlファイルのとき %> 33 | <%# currentにstyleguide.mdがHTMLとして格納されている %> 34 | <%-current%> 35 |
36 | <% } else { %> 37 |
38 |

39 | <% if (current.overview) { %> 40 | <%-current.overview.title%> 41 | <% } else { %> 42 | <%-current.fileName%> 43 | <% } %> 44 | <%-current.file%> 45 |

46 | <% if (current.overview) { %> 47 |

<%-current.overview.comment%>

48 | <% } %> 49 | 50 | <% if(current.colors) { %> 51 | <% current.colors.forEach(function(color) { %> 52 |
53 |

<%- color.name %>

54 |

<%- color.color %>

55 |
56 |
57 | <% }); %> 58 | <% } %> 59 | 60 | <% if(current.sections) { %> 61 | <% current.sections.forEach(function(section) { %> 62 |
63 |

<%- section.title %>

64 | <% if(section.attributes) { %> 65 |
    66 | <% section.attributes.forEach(function(attribute) {%> 67 | <% if(attribute.toLowerCase() === 'deprecated' || attribute === '非推奨') {%> 68 |
  • <%=attribute%>
  • 69 | <% } else if(attribute.toLowerCase() === 'todo') { %> 70 |
  • <%=attribute%>
  • 71 | <% } else { %> 72 |
  • <%=attribute%>
  • 73 | <% } %> 74 | <% }); %> 75 |
76 | <% } %> 77 |

<%- section.comment %>

78 | <% if(section.code) { %> 79 |
80 | <%- section.code %> 81 |
82 |
 選択<%= section.code %>
83 | <% } %> 84 |
85 | <% }) %> 86 | <% } %> 87 |
88 | 89 |
90 |
91 | <% } %> 92 |
93 | 94 | 95 | 96 | 97 | 98 | <%- script %> 99 | 100 | -------------------------------------------------------------------------------- /test/frontnote.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const assert = require('power-assert'); 4 | const fs = require('fs-extra'); 5 | 6 | const FrontNote = require('../lib/frontnote'); 7 | const files = [ 8 | './guide/index.html', 9 | './guide/test-sass-sample.html', 10 | './guide/assets/js/main.js', 11 | './guide/assets/js/ripple-effect.js', 12 | './guide/assets/css/style.css', 13 | './guide/assets/fonts/fontawesome-webfont.ttf', 14 | './guide/assets/fonts/fontawesome-webfont.eot', 15 | './guide/assets/fonts/FontAwesome.otf', 16 | './guide/assets/fonts/fontawesome-webfont.svg', 17 | './guide/assets/fonts/fontawesome-webfont.woff', 18 | './guide/assets/images/favicon.ico', 19 | './guide/assets/images/frontnote.png', 20 | './guide/assets/lib/highlight.pack.js', 21 | './guide/assets/lib/jquery.js', 22 | './guide/assets/lib/jquery.mousewheel.js' 23 | ]; 24 | const noAssertFiles = [ 25 | './guide/index.html', 26 | './guide/test-sass-sample.html' 27 | ]; 28 | require('./const/pattern')(); 29 | require('./parser/parser')(); 30 | require('./helper/template-helper')(); 31 | require('./render/render')(); 32 | 33 | describe('frontnote', function () { 34 | let frontnote; 35 | beforeEach(function () { 36 | frontnote = new FrontNote(); 37 | }); 38 | afterEach(function () { 39 | fs.remove('./guide'); 40 | }); 41 | it('init', function () { 42 | assert.deepEqual(frontnote.options, { 43 | overview: process.cwd() + '/lib/const/../../styleguide.md', 44 | template: process.cwd() + '/lib/const/../../template/index.ejs', 45 | includeAssetPath: process.cwd() + '/lib/const/../../template/assets/**/*', 46 | css: './style.css', 47 | script: null, 48 | out: process.cwd() + '/guide', 49 | title: 'StyleGuide', 50 | verbose: false, 51 | clean: false, 52 | params: {} 53 | }); 54 | }); 55 | 56 | it('default render', function (done) { 57 | frontnote.render('./test/sass/*.scss').subscribe(() => { 58 | for (var i = 0, len = files.length; i < len; i++) { 59 | assert(fs.existsSync(files[i])); 60 | } 61 | done(); 62 | }); 63 | }); 64 | 65 | it('cache render', function (done) { 66 | frontnote.render('./test/sass/*.scss').subscribe(() => { 67 | for (var i = 0, len = files.length; i < len; i++) { 68 | assert(fs.existsSync(files[i])); 69 | } 70 | done(); 71 | }); 72 | }); 73 | 74 | it('verbose & clean & array asset path', function (done) { 75 | frontnote = new FrontNote({ 76 | clean: true, 77 | verbose: true, 78 | includeAssetPath: ['template/assets/**/*'] 79 | }); 80 | frontnote.render('./test/sass/*.scss').subscribe(() => { 81 | for (var i = 0, len = files.length; i < len; i++) { 82 | assert(fs.existsSync(files[i])); 83 | } 84 | done(); 85 | }); 86 | }); 87 | 88 | it('no asset path', function (done) { 89 | frontnote = new FrontNote({ 90 | clean: true, 91 | includeAssetPath: null 92 | }); 93 | frontnote.render('./test/sass/*.scss').subscribe(() => { 94 | for (var i = 0, len = noAssertFiles.length; i < len; i++) { 95 | assert(fs.existsSync(files[i]) === true); 96 | } 97 | done(); 98 | }); 99 | }); 100 | 101 | it('render with overview', function (done) { 102 | frontnote = new FrontNote({ 103 | clean: true, 104 | overview: './test/sass/overview.md' 105 | }); 106 | frontnote.render('./test/sass/*.scss').subscribe(() => { 107 | for (var i = 0, len = files.length; i < len; i++) { 108 | assert(fs.existsSync(files[i]) === true); 109 | } 110 | done(); 111 | }); 112 | }); 113 | 114 | it('no src', function (done) { 115 | frontnote = new FrontNote({ 116 | clean: true, 117 | includeAssetPath: null 118 | }); 119 | frontnote.render('./none/*.scss').subscribe(() => { 120 | done(); 121 | }); 122 | }); 123 | 124 | it('multiple entrypoint', function (done) { 125 | frontnote = new FrontNote({ 126 | clean: true, 127 | includeAssetPath: null 128 | }); 129 | frontnote.render(['./test/sass/partial/**/*.scss', './test/sass/*.scss']).subscribe(() => { 130 | done(); 131 | }); 132 | }); 133 | }); -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # FrontNote 2 | [![GitHub version](https://badge.fury.io/gh/frontainer%2Ffrontnote.svg)](http://badge.fury.io/gh/frontainer%2Ffrontnote) 3 | [![Build Status](https://travis-ci.org/frontainer/frontnote.svg)](https://travis-ci.org/frontainer/frontnote) 4 | [![Code Climate](https://codeclimate.com/github/frontainer/frontnote/badges/gpa.svg)](https://codeclimate.com/github/frontainer/frontnote) 5 | 6 | ![FrontNote](http://frontainer.com/images/frontnote.png) 7 | 8 | StyleGuide Generator 9 | Node.jsを使ったスタイルガイドジェネレーター 10 | 11 | ## Usage - 使い方 12 | 13 | First, install `frontnote`: 14 | 15 | ```shell 16 | npm install frontnote --save-dev 17 | ``` 18 | 19 | ```js 20 | var FrontNote = require('frontnote'); 21 | var note = new FrontNote({ 22 | out: './docs' 23 | }); 24 | note.render('path/**/*.css').subscribe(function() { 25 | //callback 26 | }); 27 | ``` 28 | 29 | ## Plugins - プラグイン 30 | 31 | * Grunt - [grunt-frontnote](https://www.npmjs.org/package/grunt-frontnote) 32 | * Gulp - [gulp-frontnote](https://www.npmjs.org/package/gulp-frontnote) 33 | 34 | ## API 35 | 36 | ### FrontNote(options); 37 | 38 | #### options 39 | Type: `Object` 40 | Default value: `{}` 41 | 42 | Option. 43 | Please see options section for more information. 44 | 45 | オプション 46 | 詳しくはオプションの項をご覧ください。 47 | 48 | ### note.render(files,callback); 49 | 50 | #### files 51 | @Required 52 | Type: `String | Array` 53 | Pattern to be matched. 54 | Please see the [minimatch](https://github.com/isaacs/minimatch) documentation for more details. 55 | 56 | マッチさせたいパターン 57 | 詳しくは[minimatch](https://github.com/isaacs/minimatch)のドキュメントをご覧ください。 58 | 59 | #### callback 60 | Type: `Function` 61 | Default value: `null` 62 | 63 | Call this function when generated style guide. 64 | 65 | スタイルガイドが生成された後に実行するされる関数 66 | 67 | ## Option - オプション 68 | 69 | ### options.title 70 | Type: `String` 71 | Default value: `StyleGuide` 72 | 73 | Title of StyleGuide. 74 | 75 | スタイルガイドのタイトル 76 | 77 | ログを詳細に表示します 78 | 79 | ### options.overview 80 | Type: `String` 81 | Default value: `__dirname + '/styleguide.md''` 82 | 83 | StyleGuide overview file's path. 84 | Overview file is required Markdown format. 85 | 86 | index.htmlに表示するオーバービューファイル(マークダウン)のパス 87 | オーバービューファイルはマークダウン形式です。 88 | 89 | ### options.template 90 | Type: `String` 91 | Default value: `__dirname + '/template''` 92 | 93 | StyleGuide template path. 94 | 95 | スタイルガイドのテンプレートパス 96 | 97 | ### options.includeAssetPath 98 | Type: `String` 99 | Default value: `assets/**/*` 100 | 101 | The path of the file you want to copy the generated directory. 102 | 103 | 生成されたディレクトリにコピーしたいファイルパス 104 | 105 | ### options.out 106 | Type: `String` 107 | Default value: `./frontnote` 108 | 109 | Directory in which to generate a style guide. 110 | 111 | ### options.css 112 | Type: `String|Array` 113 | Default value: `./style.css` 114 | 115 | Path of CSS that you want to read in HTML. In the array or string. 116 | 117 | HTMLに読み込みたいCSSのパス。文字列または配列で指定します。 118 | 119 | ### options.script 120 | Type: `String|Array` 121 | Default value: `null` 122 | 123 | Path of JS that you want to read in HTML. In the array or string. 124 | 125 | HTMLに読み込みたいJSのパス。文字列または配列で指定します。 126 | 127 | ### options.clean 128 | Type: `Boolean` 129 | Default value: `false` 130 | 131 | Clean files and folder from options.out directory. 132 | 133 | 出力先ディレクトリとファイルを削除します。 134 | 135 | ### options.verbose 136 | Type: `Boolean` 137 | Default value: `false` 138 | 139 | Display a detailed log 140 | 141 | ログを詳細に表示します 142 | 143 | ### options.params 144 | Type: `Object` 145 | Default value: `{}` 146 | 147 | Custom variables for using ejs templates. 148 | 149 | ejsテンプレート内で使う任意の変数を定義できます。 150 | 151 | ## Template - テンプレート 152 | 153 | [frontnote-template](https://github.com/frontainer/frontnote-template) 154 | 155 | テンプレートはfrontnote-templateを参考にカスタマイズできます 156 | 157 | ## Comment Style - コメントの書き方 158 | 159 | ### File overview - ファイル概要 160 | 161 | Only 1 comment block in a file. 162 | 1ファイルに1つき1ブロックだけ記述できます。 163 | 164 | /* 165 | #overview 166 | fileoverview title 167 | 168 | fileoverview comment 169 | */ 170 | 171 | ### Section - セクション 172 | 173 | Section of style guide. 174 | '@' means attribute of this section. (ex. @deprecated @todo) 175 | 176 | 各スタイルごとに記述します。 177 | @をつけるとこのセクションに属性ラベルをつけることができます(例: @非推奨, @todo) 178 | 179 | /* 180 | #styleguide 181 | style title 182 | 183 | style comment. 184 | 185 | @deprecated 186 | @非推奨 187 | @todo 188 | @your-attribute 189 | 190 | ``` 191 | sample code here. 192 | ``` 193 | */ 194 | 195 | 196 | ### Color Pallet - カラーパレット 197 | 198 | Create color guide 199 | カラーガイドを作成します。 200 | 201 | /* 202 | #colors 203 | 204 | @primary #996600 205 | @secondary #333 206 | @color-name color-code 207 | */ 208 | 209 | ## Test 210 | 211 | ``` 212 | npm install 213 | npm test 214 | ``` -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | 2 | ## [2.0.5](https://github.com/frontainer/frontnote/compare/v2.0.4...v2.0.5) (2017-01-31) 3 | 4 | 5 | ### fix 6 | 7 | * render関数に*の含まれたパスを配列で渡すとエラーになる #11 ([e25abcfa9b883d9f62df0a4a6a8da219c5062747](https://github.com/frontainer/frontnote/commit/e25abcfa9b883d9f62df0a4a6a8da219c5062747)) 8 | * 使い方のfunction文の修正 ([9dd4a8d401aa4261fc13d960b0f26bb3e1e5f11f](https://github.com/frontainer/frontnote/commit/9dd4a8d401aa4261fc13d960b0f26bb3e1e5f11f)) 9 | * 属性ラベル名の例示を修正 ([a083c5b6866f214cc2dbb651176b954d3db1fa29](https://github.com/frontainer/frontnote/commit/a083c5b6866f214cc2dbb651176b954d3db1fa29)) 10 | 11 | 12 | 13 | 14 | ## [2.0.4](https://github.com/frontainer/frontnote/compare/v2.0.3...v2.0.4) (2016-10-08) 15 | 16 | 17 | ### fix 18 | 19 | * 対象のcssがない場合にpathエラーになる ([acd94b2b1bd3340459285dce57820f2fa9cacaec](https://github.com/frontainer/frontnote/commit/acd94b2b1bd3340459285dce57820f2fa9cacaec)) 20 | 21 | 22 | 23 | 24 | ## [2.0.3](https://github.com/frontainer/frontnote/compare/v2.0.2...v2.0.3) (2016-10-08) 25 | 26 | 27 | ### fix 28 | 29 | * verbose出力をcliではなくlib/frontnote.jsで ([bcabc34af550e6de20510ef890c304179ea80dea](https://github.com/frontainer/frontnote/commit/bcabc34af550e6de20510ef890c304179ea80dea)) 30 | 31 | 32 | 33 | 34 | ## [2.0.2](https://github.com/frontainer/frontnote/compare/v2.0.1...v2.0.2) (2016-10-08) 35 | 36 | 37 | ### fix 38 | 39 | * includeAssetPathがデフォルトだと正しく複製されない ([aa8d9f141106b9d0c61cbcf48281b6f0df41e406](https://github.com/frontainer/frontnote/commit/aa8d9f141106b9d0c61cbcf48281b6f0df41e406)) 40 | 41 | 42 | 43 | 44 | ## [2.0.1](https://github.com/frontainer/frontnote/compare/v2.0.0...v2.0.1) (2016-10-08) 45 | 46 | 47 | ### fix 48 | 49 | * render関数が配列を許容できるように ([db68cc249348e254a6e6a5826215a9a51c160cd4](https://github.com/frontainer/frontnote/commit/db68cc249348e254a6e6a5826215a9a51c160cd4)) 50 | 51 | 52 | 53 | 54 | # [2.0.0](https://github.com/frontainer/frontnote/compare/1.1.2...v2.0.0) (2016-10-08) 55 | 56 | 57 | ### add 58 | 59 | * CLIで実行できるように ([c9708bf30cc1de9ad49eb03e91b5082025e523ab](https://github.com/frontainer/frontnote/commit/c9708bf30cc1de9ad49eb03e91b5082025e523ab)) 60 | * ejsに任意の値を渡せるオプションparamsを追加 #7 ([c9e4b88f48fe7af01c4106320350296ad04dbfeb](https://github.com/frontainer/frontnote/commit/c9e4b88f48fe7af01c4106320350296ad04dbfeb)) 61 | 62 | ### breaking 63 | 64 | * 動作環境をNode.js 5以上に ([34a01c45deb4d9664d3bec63503459a56c7ee5c5](https://github.com/frontainer/frontnote/commit/34a01c45deb4d9664d3bec63503459a56c7ee5c5)) 65 | 66 | ### feat 67 | 68 | * 非同期処理をRxに置き換え、記法をES6に ([8d27e28f12f0288a35af1209d32adf5d2cad75d4](https://github.com/frontainer/frontnote/commit/8d27e28f12f0288a35af1209d32adf5d2cad75d4)) 69 | 70 | 71 | 72 | 73 | ## [1.1.1](https://github.com/frontainer/frontnote/compare/1.1.0...1.1.1) (2015-09-06) 74 | 75 | 76 | 77 | 78 | 79 | # [1.1.0](https://github.com/frontainer/frontnote/compare/1.0.2...1.1.0) (2015-06-29) 80 | 81 | 82 | 83 | 84 | 85 | ## [1.0.2](https://github.com/frontainer/frontnote/compare/1.0.1...1.0.2) (2015-06-23) 86 | 87 | 88 | 89 | 90 | 91 | ## [1.0.1](https://github.com/frontainer/frontnote/compare/1.0.0...1.0.1) (2015-05-12) 92 | 93 | 94 | 95 | 96 | 97 | # [1.0.0](https://github.com/frontainer/frontnote/compare/0.1.0...1.0.0) (2015-04-18) 98 | 99 | 100 | 101 | 102 | 103 | # [0.1.0](https://github.com/frontainer/frontnote/compare/0.0.12...0.1.0) (2014-09-14) 104 | 105 | 106 | 107 | 108 | 109 | ## [0.0.12](https://github.com/frontainer/frontnote/compare/0.0.10...0.0.12) (2014-08-26) 110 | 111 | 112 | 113 | 114 | 115 | ## [0.0.10](https://github.com/frontainer/frontnote/compare/0.0.9...0.0.10) (2014-08-25) 116 | 117 | 118 | 119 | 120 | 121 | ## [0.0.9](https://github.com/frontainer/frontnote/compare/0.0.8...0.0.9) (2014-08-25) 122 | 123 | 124 | 125 | 126 | 127 | ## [0.0.8](https://github.com/frontainer/frontnote/compare/0.0.7...0.0.8) (2014-08-24) 128 | 129 | 130 | 131 | 132 | 133 | ## [0.0.7](https://github.com/frontainer/frontnote/compare/0.0.6...0.0.7) (2014-08-22) 134 | 135 | 136 | 137 | 138 | 139 | ## [0.0.6](https://github.com/frontainer/frontnote/compare/0.0.5...0.0.6) (2014-08-22) 140 | 141 | 142 | 143 | 144 | 145 | ## [0.0.5](https://github.com/frontainer/frontnote/compare/0.0.4...0.0.5) (2014-08-20) 146 | 147 | 148 | 149 | 150 | 151 | ## [0.0.4](https://github.com/frontainer/frontnote/compare/0.0.3...0.0.4) (2014-08-19) 152 | 153 | 154 | 155 | 156 | 157 | ## [0.0.3](https://github.com/frontainer/frontnote/compare/0.0.2...0.0.3) (2014-08-18) 158 | 159 | 160 | 161 | 162 | 163 | ## [0.0.2](https://github.com/frontainer/frontnote/compare/0.0.1...0.0.2) (2014-08-17) 164 | 165 | 166 | 167 | 168 | 169 | ## 0.0.1 (2014-08-17) 170 | 171 | 172 | 173 | 174 | -------------------------------------------------------------------------------- /lib/parser/parser.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | const path = require('path'), 3 | sanitizer = require('sanitizer'); 4 | 5 | const PATTERNS = require('../const/pattern.js'); 6 | 7 | class Parser { 8 | parse(file, content) { 9 | let overview = content.match(PATTERNS.overview); 10 | if (overview) { 11 | overview = this.parseComments(overview); 12 | if (overview) { 13 | overview = overview[0]; 14 | } 15 | } 16 | let colors = content.match(PATTERNS.colors); 17 | if (colors) { 18 | colors = this.parseColors(colors); 19 | } 20 | let comments = content.match(PATTERNS.comment); 21 | if (comments) { 22 | comments = this.parseComments(comments); 23 | } 24 | if (overview || comments || colors) { 25 | let fileName = path.basename(file, path.extname(file)); 26 | let relPath = path.relative(__dirname, path.dirname(file)); 27 | if (relPath) { 28 | relPath = relPath.replace(/\.\.\//g, '').replace(/\.\.\\/g, '').replace(/\//g, '-').replace(/\\/g, '-') + '-'; 29 | } 30 | return { 31 | file: path.relative(process.cwd(),file), 32 | fileName: fileName, 33 | url: relPath + fileName + '.html', 34 | dirs: file.split(path.sep), 35 | ext: path.extname(file), 36 | sections: comments, 37 | overview: overview, 38 | colors: colors 39 | }; 40 | } 41 | return null; 42 | } 43 | 44 | /** 45 | * コメントの塊をパースする 46 | * @param comments 47 | * @returns {Array} 48 | */ 49 | parseComments(comments) { 50 | let result = []; 51 | for (let i = 0, len = comments.length; i < len; i++) { 52 | let com = this.parseComment(comments[i]); 53 | if (com) { 54 | result.push(com); 55 | } 56 | } 57 | return result; 58 | } 59 | 60 | /** 61 | * カラーコメントの塊をパースする 62 | * @param colors 63 | * @returns {Array} 64 | */ 65 | parseColors(colors) { 66 | let result = []; 67 | for (let i = 0, len = colors.length; i < len; i++) { 68 | let color = this.parseColor(colors[i]); 69 | if (color) { 70 | result = result.concat(color); 71 | } 72 | } 73 | return result; 74 | } 75 | 76 | /** 77 | * カラーコメントパースする 78 | * @param color 79 | * @returns {Array} 80 | */ 81 | parseColor(color) { 82 | let colors = this.filterPattern(color, PATTERNS.attr, false), 83 | result = []; 84 | for (let i = 0, len = colors.length; i < len; i++) { 85 | let matches = colors[i].match(PATTERNS.color); 86 | if (matches.length > 2) { 87 | result.push({ 88 | value: matches[0], 89 | name: matches[1], 90 | color: matches[2] 91 | }); 92 | } 93 | } 94 | return result; 95 | } 96 | 97 | /** 98 | * コメントをパースする 99 | * @param comment 100 | * @returns {{title: Array, comment: Array, attributes: (*|Array), markdown: *, html: *, code: *}} 101 | */ 102 | parseComment(comment) { 103 | comment = comment.replace(PATTERNS.prefix, ''); 104 | 105 | // 属性 106 | let attrs = this.filterPattern(comment, PATTERNS.attr, false); 107 | comment = comment.replace(PATTERNS.attr, ''); 108 | 109 | // サンプルコード領域 110 | let code = this.filterPattern(comment, PATTERNS.code); 111 | comment = comment.replace(PATTERNS.code, ''); 112 | 113 | return this.sanitize(attrs, code, comment); 114 | } 115 | 116 | /** 117 | * パースされた文字列をサニタイズする 118 | * @param attrs 119 | * @param code 120 | * @param comment 121 | * @returns {{title: Array, comment: Array, attributes: (*|Array), code: *}} 122 | */ 123 | sanitize(attrs, code, comment) { 124 | let result = { 125 | title: [], 126 | comment: [], 127 | attributes: attrs || [], 128 | code: code 129 | }; 130 | 131 | let lines = comment.split(PATTERNS.splitter), 132 | hasTitle = false, 133 | i = 0, 134 | len = 0; 135 | 136 | for (i = 0, len = lines.length; i < len; i++) { 137 | let line = lines[i]; 138 | if (!hasTitle) { 139 | if (line) { 140 | result.title.push(sanitizer.escape(line)); 141 | } else if (result.title.length !== 0) { 142 | hasTitle = true; 143 | } 144 | } else if (line) { 145 | result.comment.push(sanitizer.escape(line)); 146 | } 147 | } 148 | result.title = result.title.join('
'); 149 | result.comment = result.comment.join('
'); 150 | 151 | for (i = 0, len = result.attributes.length; i < len; i++) { 152 | result.attributes[i] = sanitizer.escape(result.attributes[i].replace(PATTERNS.attrPrefix, '')); 153 | } 154 | return result; 155 | } 156 | 157 | /** 158 | * 正規表現によって一致した文字列データを返却 159 | * @param str 160 | * @param pattern 161 | * @param trim 162 | * @returns {*} 163 | */ 164 | filterPattern(str, pattern, trim) { 165 | if (trim === false) { 166 | return str.match(pattern); 167 | } else { 168 | let match = str.match(pattern); 169 | if (match) { 170 | return match[0].replace(PATTERNS.codeWrapper, ''); 171 | } 172 | return null; 173 | } 174 | } 175 | } 176 | module.exports = Parser; -------------------------------------------------------------------------------- /template/assets/lib/highlight.pack.js: -------------------------------------------------------------------------------- 1 | var hljs=new function(){function e(e){return e.replace(/&/gm,"&").replace(//gm,">")}function t(e){return e.nodeName.toLowerCase()}function r(e,t){var r=e&&e.exec(t);return r&&0==r.index}function n(e){var t=(e.className+" "+(e.parentNode?e.parentNode.className:"")).split(/\s+/);return t=t.map(function(e){return e.replace(/^lang(uage)?-/,"")}),t.filter(function(e){return v(e)||/no(-?)highlight/.test(e)})[0]}function a(e,t){var r={};for(var n in e)r[n]=e[n];if(t)for(var n in t)r[n]=t[n];return r}function i(e){var r=[];return function n(e,a){for(var i=e.firstChild;i;i=i.nextSibling)3==i.nodeType?a+=i.nodeValue.length:1==i.nodeType&&(r.push({event:"start",offset:a,node:i}),a=n(i,a),t(i).match(/br|hr|img|input/)||r.push({event:"stop",offset:a,node:i}));return a}(e,0),r}function c(r,n,a){function i(){return r.length&&n.length?r[0].offset!=n[0].offset?r[0].offset"}function s(e){l+=""}function o(e){("start"==e.event?c:s)(e.node)}for(var u=0,l="",f=[];r.length||n.length;){var h=i();if(l+=e(a.substr(u,h[0].offset-u)),u=h[0].offset,h==r){f.reverse().forEach(s);do o(h.splice(0,1)[0]),h=i();while(h==r&&h.length&&h[0].offset==u);f.reverse().forEach(c)}else"start"==h[0].event?f.push(h[0].node):f.pop(),o(h.splice(0,1)[0])}return l+e(a.substr(u))}function s(e){function t(e){return e&&e.source||e}function r(r,n){return RegExp(t(r),"m"+(e.cI?"i":"")+(n?"g":""))}function n(i,c){if(!i.compiled){if(i.compiled=!0,i.k=i.k||i.bK,i.k){var s={},o=function(t,r){e.cI&&(r=r.toLowerCase()),r.split(" ").forEach(function(e){var r=e.split("|");s[r[0]]=[t,r[1]?Number(r[1]):1]})};"string"==typeof i.k?o("keyword",i.k):Object.keys(i.k).forEach(function(e){o(e,i.k[e])}),i.k=s}i.lR=r(i.l||/\b[A-Za-z0-9_]+\b/,!0),c&&(i.bK&&(i.b="\\b("+i.bK.split(" ").join("|")+")\\b"),i.b||(i.b=/\B|\b/),i.bR=r(i.b),i.e||i.eW||(i.e=/\B|\b/),i.e&&(i.eR=r(i.e)),i.tE=t(i.e)||"",i.eW&&c.tE&&(i.tE+=(i.e?"|":"")+c.tE)),i.i&&(i.iR=r(i.i)),void 0===i.r&&(i.r=1),i.c||(i.c=[]);var u=[];i.c.forEach(function(e){e.v?e.v.forEach(function(t){u.push(a(e,t))}):u.push("self"==e?i:e)}),i.c=u,i.c.forEach(function(e){n(e,i)}),i.starts&&n(i.starts,c);var l=i.c.map(function(e){return e.bK?"\\.?("+e.b+")\\.?":e.b}).concat([i.tE,i.i]).map(t).filter(Boolean);i.t=l.length?r(l.join("|"),!0):{exec:function(e){return null}}}}n(e)}function o(t,n,a,i){function c(e,t){for(var n=0;n";return i+=e+'">',i+t+c}function g(){if(!y.k)return e(x);var t="",r=0;y.lR.lastIndex=0;for(var n=y.lR.exec(x);n;){t+=e(x.substr(r,n.index-r));var a=h(y,n);a?(L+=a[1],t+=b(a[0],e(n[0]))):t+=e(n[0]),r=y.lR.lastIndex,n=y.lR.exec(x)}return t+e(x.substr(r))}function p(){if(y.sL&&!m[y.sL])return e(x);var t=y.sL?o(y.sL,x,!0,C):u(x);return y.r>0&&(L+=t.r),"continuous"==y.subLanguageMode&&(C=t.top),b(t.language,t.value,!1,!0)}function d(){return void 0!==y.sL?p():g()}function E(t,r){var n=t.cN?b(t.cN,"",!0):"";t.rB?(w+=n,x=""):t.eB?(w+=e(r)+n,x=""):(w+=n,x=r),y=Object.create(t,{parent:{value:y}})}function M(t,r){if(x+=t,void 0===r)return w+=d(),0;var n=c(r,y);if(n)return w+=d(),E(n,r),n.rB?0:r.length;var a=l(y,r);if(a){var i=y;i.rE||i.eE||(x+=r),w+=d();do y.cN&&(w+=""),L+=y.r,y=y.parent;while(y!=a.parent);return i.eE&&(w+=e(r)),x="",a.starts&&E(a.starts,""),i.rE?0:r.length}if(f(r,y))throw new Error('Illegal lexeme "'+r+'" for mode "'+(y.cN||"")+'"');return x+=r,r.length||1}var R=v(t);if(!R)throw new Error('Unknown language: "'+t+'"');s(R);for(var C,y=i||R,w="",A=y;A!=R;A=A.parent)A.cN&&(w=b(A.cN,"",!0)+w);var x="",L=0;try{for(var I,B,k=0;;){if(y.t.lastIndex=k,I=y.t.exec(n),!I)break;B=M(n.substr(k,I.index-k),I[0]),k=I.index+B}M(n.substr(k));for(var A=y;A.parent;A=A.parent)A.cN&&(w+="");return{r:L,value:w,language:t,top:y}}catch(S){if(-1!=S.message.indexOf("Illegal"))return{r:0,value:e(n)};throw S}}function u(t,r){r=r||N.languages||Object.keys(m);var n={r:0,value:e(t)},a=n;return r.forEach(function(e){if(v(e)){var r=o(e,t,!1);r.language=e,r.r>a.r&&(a=r),r.r>n.r&&(a=n,n=r)}}),a.language&&(n.second_best=a),n}function l(e){return N.tabReplace&&(e=e.replace(/^((<[^>]+>|\t)+)/gm,function(e,t,r,n){return t.replace(/\t/g,N.tabReplace)})),N.useBR&&(e=e.replace(/\n/g,"
")),e}function f(e){var t=n(e);if(!/no(-?)highlight/.test(t)){var r;N.useBR?(r=document.createElementNS("http://www.w3.org/1999/xhtml","div"),r.innerHTML=e.innerHTML.replace(/\n/g,"").replace(//g,"\n")):r=e;var a=r.textContent,s=t?o(t,a,!0):u(a),f=i(r);if(f.length){var h=document.createElementNS("http://www.w3.org/1999/xhtml","div");h.innerHTML=s.value,s.value=c(f,i(h),a)}s.value=l(s.value),e.innerHTML=s.value,e.className+=" hljs "+(!t&&s.language||""),e.result={language:s.language,re:s.r},s.second_best&&(e.second_best={language:s.second_best.language,re:s.second_best.r})}}function h(e){N=a(N,e)}function b(){if(!b.called){b.called=!0;var e=document.querySelectorAll("pre code");Array.prototype.forEach.call(e,f)}}function g(){addEventListener("DOMContentLoaded",b,!1),addEventListener("load",b,!1)}function p(e,t){var r=m[e]=t(this);r.aliases&&r.aliases.forEach(function(t){E[t]=e})}function d(){return Object.keys(m)}function v(e){return m[e]||m[E[e]]}var N={classPrefix:"hljs-",tabReplace:null,useBR:!1,languages:void 0},m={},E={};this.highlight=o,this.highlightAuto=u,this.fixMarkup=l,this.highlightBlock=f,this.configure=h,this.initHighlighting=b,this.initHighlightingOnLoad=g,this.registerLanguage=p,this.listLanguages=d,this.getLanguage=v,this.inherit=a,this.IR="[a-zA-Z][a-zA-Z0-9_]*",this.UIR="[a-zA-Z_][a-zA-Z0-9_]*",this.NR="\\b\\d+(\\.\\d+)?",this.CNR="(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)",this.BNR="\\b(0b[01]+)",this.RSR="!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~",this.BE={b:"\\\\[\\s\\S]",r:0},this.ASM={cN:"string",b:"'",e:"'",i:"\\n",c:[this.BE]},this.QSM={cN:"string",b:'"',e:'"',i:"\\n",c:[this.BE]},this.PWM={b:/\b(a|an|the|are|I|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such)\b/},this.CLCM={cN:"comment",b:"//",e:"$",c:[this.PWM]},this.CBCM={cN:"comment",b:"/\\*",e:"\\*/",c:[this.PWM]},this.HCM={cN:"comment",b:"#",e:"$",c:[this.PWM]},this.NM={cN:"number",b:this.NR,r:0},this.CNM={cN:"number",b:this.CNR,r:0},this.BNM={cN:"number",b:this.BNR,r:0},this.CSSNM={cN:"number",b:this.NR+"(%|em|ex|ch|rem|vw|vh|vmin|vmax|cm|mm|in|pt|pc|px|deg|grad|rad|turn|s|ms|Hz|kHz|dpi|dpcm|dppx)?",r:0},this.RM={cN:"regexp",b:/\//,e:/\/[gim]*/,i:/\n/,c:[this.BE,{b:/\[/,e:/\]/,r:0,c:[this.BE]}]},this.TM={cN:"title",b:this.IR,r:0},this.UTM={cN:"title",b:this.UIR,r:0}};hljs.registerLanguage("javascript",function(e){return{aliases:["js"],k:{keyword:"in if for while finally var new function do return void else break catch instanceof with throw case default try this switch continue typeof delete let yield const class",literal:"true false null undefined NaN Infinity",built_in:"eval isFinite isNaN parseFloat parseInt decodeURI decodeURIComponent encodeURI encodeURIComponent escape unescape Object Function Boolean Error EvalError InternalError RangeError ReferenceError StopIteration SyntaxError TypeError URIError Number Math Date String RegExp Array Float32Array Float64Array Int16Array Int32Array Int8Array Uint16Array Uint32Array Uint8Array Uint8ClampedArray ArrayBuffer DataView JSON Intl arguments require module console window document"},c:[{cN:"pi",b:/^\s*('|")use strict('|")/,r:10},e.ASM,e.QSM,e.CLCM,e.CBCM,e.CNM,{b:"("+e.RSR+"|\\b(case|return|throw)\\b)\\s*",k:"return throw case",c:[e.CLCM,e.CBCM,e.RM,{b:/;/,r:0,sL:"xml"}],r:0},{cN:"function",bK:"function",e:/\{/,eE:!0,c:[e.inherit(e.TM,{b:/[A-Za-z$_][0-9A-Za-z$_]*/}),{cN:"params",b:/\(/,e:/\)/,c:[e.CLCM,e.CBCM],i:/["'\(]/}],i:/\[|%/},{b:/\$[(.]/},{b:"\\."+e.IR,r:0}]}}),hljs.registerLanguage("css",function(e){var t="[a-zA-Z-][a-zA-Z0-9_-]*",r={cN:"function",b:t+"\\(",rB:!0,eE:!0,e:"\\("};return{cI:!0,i:"[=/|']",c:[e.CBCM,{cN:"id",b:"\\#[A-Za-z0-9_-]+"},{cN:"class",b:"\\.[A-Za-z0-9_-]+",r:0},{cN:"attr_selector",b:"\\[",e:"\\]",i:"$"},{cN:"pseudo",b:":(:)?[a-zA-Z0-9\\_\\-\\+\\(\\)\\\"\\']+"},{cN:"at_rule",b:"@(font-face|page)",l:"[a-z-]+",k:"font-face page"},{cN:"at_rule",b:"@",e:"[{;]",c:[{cN:"keyword",b:/\S+/},{b:/\s/,eW:!0,eE:!0,r:0,c:[r,e.ASM,e.QSM,e.CSSNM]}]},{cN:"tag",b:t,r:0},{cN:"rules",b:"{",e:"}",i:"[^\\s]",r:0,c:[e.CBCM,{cN:"rule",b:"[^\\s]",rB:!0,e:";",eW:!0,c:[{cN:"attribute",b:"[A-Z\\_\\.\\-]+",e:":",eE:!0,i:"[^\\s]",starts:{cN:"value",eW:!0,eE:!0,c:[r,e.CSSNM,e.QSM,e.ASM,e.CBCM,{cN:"hexcolor",b:"#[0-9A-Fa-f]+"},{cN:"important",b:"!important"}]}}]}]}]}}),hljs.registerLanguage("xml",function(e){var t="[A-Za-z0-9\\._:-]+",r={b:/<\?(php)?(?!\w)/,e:/\?>/,sL:"php",subLanguageMode:"continuous"},n={eW:!0,i:/]+/}]}]}]};return{aliases:["html","xhtml","rss","atom","xsl","plist"],cI:!0,c:[{cN:"doctype",b:"",r:10,c:[{b:"\\[",e:"\\]"}]},{cN:"comment",b:"",r:10},{cN:"cdata",b:"<\\!\\[CDATA\\[",e:"\\]\\]>",r:10},{cN:"tag",b:"|$)",e:">",k:{title:"style"},c:[n],starts:{e:"",rE:!0,sL:"css"}},{cN:"tag",b:"|$)",e:">",k:{title:"script"},c:[n],starts:{e:"",rE:!0,sL:"javascript"}},{b:"<%",e:"%>",sL:"vbscript"},r,{cN:"pi",b:/<\?\w+/,e:/\?>/,r:10},{cN:"tag",b:"",c:[{cN:"title",b:/[^ \/><\n\t]+/,r:0},n]}]}}); -------------------------------------------------------------------------------- /template/assets/css/style.css: -------------------------------------------------------------------------------- 1 | @charset "UTF-8";.fn-container,.fn-content,.fn-header{box-sizing:border-box}body,html{width:100%;height:100%;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%;text-size-adjust:100%}.fn-article,.fn-attribute,.fn-attribute-item,.fn-code,.fn-color-name,.fn-color-pallet,.fn-color-panel,.fn-comment,.fn-container,.fn-content,.fn-content img,.fn-copyright,.fn-drawer-trigger,.fn-header,.fn-heading2,.fn-heading3,.fn-icon,.fn-icon-link,.fn-link,.fn-menu,.fn-overview,.fn-overview blockquote,.fn-overview code,.fn-overview div,.fn-overview h1,.fn-overview h2,.fn-overview h3,.fn-overview h4,.fn-overview h5,.fn-overview h6,.fn-overview img,.fn-overview li,.fn-overview ol,.fn-overview p,.fn-overview pre,.fn-overview strong,.fn-overview ul,.fn-pagetop,.fn-pre,.fn-preview,.fn-reset,.fn-reset :hover,.fn-reset:after,.fn-reset:before,.fn-separate,.fn-sidebar,.fn-sub-heading,.fn-title,.fn-tooltip,body,html,svg.fn-ripple{margin:0;padding:0;border:0;font:inherit;font-family:"ヒラギノ角ゴ ProN W3","Hiragino Kaku Gothic ProN","メイリオ",Meiryo,sans-serif;font-size:14px;vertical-align:baseline;line-height:1;list-style:none;quotes:none;border-collapse:collapse;border-spacing:0;color:#333;text-decoration:none;background:0 0}.fn-article:after,.fn-article:before,.fn-attribute-item:after,.fn-attribute-item:before,.fn-attribute:after,.fn-attribute:before,.fn-code:after,.fn-code:before,.fn-color-name:after,.fn-color-name:before,.fn-color-pallet:after,.fn-color-pallet:before,.fn-color-panel:after,.fn-color-panel:before,.fn-comment:after,.fn-comment:before,.fn-container:after,.fn-container:before,.fn-content img:after,.fn-content img:before,.fn-content:after,.fn-content:before,.fn-copyright:after,.fn-copyright:before,.fn-drawer-trigger:after,.fn-drawer-trigger:before,.fn-header:after,.fn-header:before,.fn-heading2:after,.fn-heading2:before,.fn-heading3:after,.fn-heading3:before,.fn-icon-link:after,.fn-icon-link:before,.fn-icon:after,.fn-icon:before,.fn-link:after,.fn-link:before,.fn-menu:after,.fn-menu:before,.fn-overview blockquote:after,.fn-overview blockquote:before,.fn-overview code:after,.fn-overview code:before,.fn-overview div:after,.fn-overview div:before,.fn-overview h1:after,.fn-overview h1:before,.fn-overview h2:after,.fn-overview h2:before,.fn-overview h3:after,.fn-overview h3:before,.fn-overview h4:after,.fn-overview h4:before,.fn-overview h5:after,.fn-overview h5:before,.fn-overview h6:after,.fn-overview h6:before,.fn-overview img:after,.fn-overview img:before,.fn-overview li:after,.fn-overview li:before,.fn-overview ol:after,.fn-overview ol:before,.fn-overview p:after,.fn-overview p:before,.fn-overview pre:after,.fn-overview pre:before,.fn-overview strong:after,.fn-overview strong:before,.fn-overview ul:after,.fn-overview ul:before,.fn-overview:after,.fn-overview:before,.fn-pagetop:after,.fn-pagetop:before,.fn-pre:after,.fn-pre:before,.fn-preview:after,.fn-preview:before,.fn-reset :hover:after,.fn-reset :hover:before,.fn-reset:after,.fn-reset:before,.fn-separate:after,.fn-separate:before,.fn-sidebar:after,.fn-sidebar:before,.fn-sub-heading:after,.fn-sub-heading:before,.fn-title:after,.fn-title:before,.fn-tooltip:after,.fn-tooltip:before,body:after,body:before,html:after,html:before,svg.fn-ripple:after,svg.fn-ripple:before{content:'';content:none}.fn-article :hover,.fn-attribute :hover,.fn-attribute-item :hover,.fn-code :hover,.fn-color-name :hover,.fn-color-pallet :hover,.fn-color-panel :hover,.fn-comment :hover,.fn-container :hover,.fn-content :hover,.fn-copyright :hover,.fn-drawer-trigger :hover,.fn-header :hover,.fn-heading2 :hover,.fn-heading3 :hover,.fn-icon :hover,.fn-icon-link :hover,.fn-link :hover,.fn-menu :hover,.fn-overview :hover,.fn-pagetop :hover,.fn-pre :hover,.fn-preview :hover,.fn-reset :hover,.fn-reset:after :hover,.fn-reset:before :hover,.fn-separate :hover,.fn-sidebar :hover,.fn-sub-heading :hover,.fn-title :hover,.fn-tooltip :hover,body :hover,html :hover,svg.fn-ripple :hover{color:#333;text-decoration:none}article,aside,details,figcaption,figure,footer,header,hgroup,menu,nav,section{display:block}.fn-attribute:after,.fn-attribute:before,.fn-container:after,.fn-container:before,.fn-header:after,.fn-header:before{content:" ";display:table}.fn-attribute:after,.fn-container:after,.fn-header:after{clear:both}.fn-code,.fn-pre{font-size:14px;font-family:Consolas,'Liberation Mono',Courier,monospace;color:#333;background:#f8f8f8;border-radius:3px}.fn-pre{border:1px solid #ccc;word-wrap:break-word;line-height:19px;margin-bottom:20px}.fn-pre .fn-code{border:0;padding:0;margin:0;border-radius:0}.fn-pre .hljs{display:block;overflow-x:auto;padding:.5em;color:#333;background:#f8f8f8;-webkit-text-size-adjust:none}.fn-pre .diff .hljs-header,.fn-pre .hljs-comment,.fn-pre .hljs-javadoc,.fn-pre .hljs-template_comment{color:#998;font-style:italic}.fn-pre .css .rule .hljs-keyword,.fn-pre .hljs-keyword,.fn-pre .hljs-request,.fn-pre .hljs-status,.fn-pre .hljs-subst,.fn-pre .hljs-winutils,.fn-pre .javascript .hljs-title,.fn-pre .nginx .hljs-title{color:#333;font-weight:700}.fn-pre .hljs-hexcolor,.fn-pre .hljs-number,.fn-pre .ruby .hljs-constant{color:teal}.fn-pre .hljs-dartdoc,.fn-pre .hljs-phpdoc,.fn-pre .hljs-string,.fn-pre .hljs-tag .hljs-value,.fn-pre .tex .hljs-formula{color:#d14}.fn-pre .hljs-id,.fn-pre .hljs-title,.fn-pre .scss .hljs-preprocessor{color:#900;font-weight:700}.fn-pre .hljs-list .hljs-keyword,.fn-pre .hljs-subst,.fn-pre .javascript .hljs-title{font-weight:400}.fn-pre .hljs-class .hljs-title,.fn-pre .hljs-type,.fn-pre .tex .hljs-command,.fn-pre .vhdl .hljs-literal{color:#458;font-weight:700}.fn-pre .django .hljs-tag .hljs-keyword,.fn-pre .hljs-rules .hljs-property,.fn-pre .hljs-tag,.fn-pre .hljs-tag .hljs-title{color:navy;font-weight:400}.fn-pre .hljs-attribute,.fn-pre .hljs-variable,.fn-pre .lisp .hljs-body{color:teal}.fn-pre .hljs-regexp{color:#009926}.fn-pre .clojure .hljs-keyword,.fn-pre .hljs-prompt,.fn-pre .hljs-symbol,.fn-pre .lisp .hljs-keyword,.fn-pre .ruby .hljs-symbol .hljs-string,.fn-pre .scheme .hljs-keyword,.fn-pre .tex .hljs-special{color:#990073}.fn-pre .hljs-built_in{color:#0086b3}.fn-pre .hljs-cdata,.fn-pre .hljs-doctype,.fn-pre .hljs-pi,.fn-pre .hljs-pragma,.fn-pre .hljs-preprocessor,.fn-pre .hljs-shebang{color:#999;font-weight:700}.fn-pre .hljs-deletion{background:#fdd}.fn-pre .hljs-addition{background:#dfd}.fn-pre .diff .hljs-change{background:#0086b3}.fn-pre .hljs-chunk{color:#aaa}.fn-header{position:fixed;top:0;left:0;z-index:3;width:100%;background:#3e50b4;height:64px;padding:0 20px;box-shadow:0 5px 6px -3px rgba(0,0,0,.4)}.fn-header .fn-link{color:#fff}.fn-header .fn-title{color:#fff;letter-spacing:2px;line-height:64px;font-size:24px;float:left;margin:0}.fn-header .fn-title a{color:#fff;text-decoration:none}.fn-header .fn-copyright{color:#fff;float:right;line-height:64px;font-size:11px}.fn-header .fn-drawer-trigger{float:left;line-height:64px;color:#fff;font-size:20px;cursor:pointer}.fn-header .fn-icon-link{overflow:hidden;border-radius:50px;padding:20px;color:#fff}.fn-container{width:100%;height:100%;padding-top:64px;position:relative}.fn-container .fn-pagetop{position:fixed;right:15px;bottom:15px;-webkit-transform:scale(0,0);-ms-transform:scale(0,0);transform:scale(0,0);-webkit-transition:400ms cubic-bezier(.17,.67,.47,1.31)-webkit-transform;transition:400ms cubic-bezier(.17,.67,.47,1.31)transform}.fn-container .fn-pagetop .fn-icon{background:#fff;padding:15px;border-radius:50px;box-shadow:0 0 6px rgba(0,0,0,.4)}.fn-container .fn-pagetop .fn-icon:hover,.fn-sidebar{background:#f8f8f8}.fn-container .fn-pagetop.fn-show{-webkit-transform:scale(1,1);-ms-transform:scale(1,1);transform:scale(1,1)}.fn-sidebar{overflow:auto;padding-top:64px;width:250px;height:100%;position:fixed;z-index:2;top:0;left:0;box-shadow:1px 0 2px #eee;-webkit-transition:300ms cubic-bezier(.55,0,.1,1)margin;transition:300ms cubic-bezier(.55,0,.1,1)margin}.fn-sidebar .fn-menu{position:relative;padding:20px 12px;display:block;border-bottom:1px solid #ccc;box-shadow:0 1px 0 #fff}.fn-sidebar .fn-menu.fn-is-active{background:#eee}.fn-sidebar .fn-menu.fn-is-active::after{font-size:12px;font-family:fontawesome;content:"";position:absolute;right:1em}.fn-sidebar .fn-separate{padding:10px 0;border:0;display:block}.fn-content{width:100%;padding:20px 20px 20px 270px;-webkit-transition-duration:300ms;transition-duration:300ms;-webkit-transition-timing-function:cubic-bezier(.55,0,.1,1);transition-timing-function:cubic-bezier(.55,0,.1,1);-webkit-transition-property:margin,padding,-webkit-filter,margin,padding,filter;transition-property:margin,padding,filter}.fn-heading2{font-size:32px;margin:.5em 0 1em}.fn-heading2 .fn-sub-heading{font-size:14px;color:#666;word-break:break-all}.fn-heading3{font-size:24px;margin:2em 0 1em}.fn-attribute{display:block}.fn-attribute .fn-attribute-item{font-size:12px;display:inline-block;padding:4px 10px;border-radius:3px;box-shadow:rgba(0,0,0,.14902)0 1px 1px 0,rgba(0,0,0,.09804)0 1px 2px 0;margin-right:5px;background:#f8f8f8}.fn-attribute .fn-attribute-item.fn-attribute-deprecated{background:#cb4437;color:#fff}.fn-attribute .fn-attribute-item.fn-attribute-todo{background:#f4b400;color:#fff}.fn-comment{font-size:14px;margin:1em 0;line-height:1.4}.fn-preview{position:relative;padding:45px 20px 30px;border:1px solid #ccc;border-radius:2px;margin:2em 0}.fn-pre::after,.fn-preview::after{font-size:12px;color:#999;border-radius:0 0 3px}.fn-preview::after{content:'preview';background:#eee;padding:4px 10px;position:absolute;top:0;left:0}.fn-pre{position:relative;padding:34px 20px 22px;background:#fafafa}.fn-pre .fn-icon{position:absolute;top:.5em;right:1em;cursor:pointer}.fn-pre::after,svg.fn-ripple{position:absolute;top:0;left:0}.fn-pre .fn-code{display:block;line-height:1.4;overflow:auto}.fn-overflow,svg.fn-ripple{overflow:hidden}.fn-pre .fn-code:focus{outline:0}.fn-pre::after{content:'code';background:#eee;padding:4px 10px}svg.fn-ripple{pointer-events:none;width:100%;height:100%;z-index:-1}svg.fn-ripple circle{fill:rgba(255,255,255,.7)}.fn-mobile-visible{display:none}.fn-pc-visible{display:block}.fn-overflow .fn-sidebar{margin-left:0}.fn-overflow .fn-content{padding:20px;margin-left:250px;-webkit-filter:blur(5px);filter:blur(5px)}.fn-overflow .fn-content::after{content:'';position:absolute;top:-5px;left:-5px;right:-5px;bottom:-5px;background:rgba(255,255,255,.3)}.fn-tooltip{position:fixed;top:0;left:0;display:none;background:#fff;border-radius:3px;box-shadow:0 0 6px #999;padding:.25em 1em;font-size:16px}.fn-color-pallet{margin:0 12px 12px 0;display:inline-block}.fn-color-pallet .fn-color-name{font-size:16px;white-space:nowrap}.fn-color-pallet .fn-color-panel{display:block;height:100px;border:1px solid #ccc}.fn-overview blockquote,.fn-overview code,.fn-overview div,.fn-overview h1,.fn-overview h2,.fn-overview h3,.fn-overview h4,.fn-overview h5,.fn-overview h6,.fn-overview img,.fn-overview li,.fn-overview ol,.fn-overview p,.fn-overview pre,.fn-overview strong,.fn-overview ul{line-height:1.5}.fn-overview h1{font-size:3em}.fn-overview h2{font-size:2.25em}.fn-overview h3{font-size:2em}.fn-overview h4{font-size:1.5em}.fn-overview h5{font-size:1.3em}.fn-overview h6{font-size:1em}.fn-overview blockquote{position:relative;border:1px solid #eee;padding:30px;margin:10px 0}.fn-overview blockquote:after,.fn-overview blockquote:before{font-size:48px;position:absolute;color:#eee}.fn-overview blockquote:before{line-height:1;content:'“';top:5px;left:5px}.fn-overview blockquote:after{content:'”';bottom:5px;right:5px;line-height:0}.fn-overview pre{background:#f8f8f8;border:1px solid #ccc;margin:10px 0;padding:15px}.fn-overview b,.fn-overview strong{font-weight:700}.fn-overview ol,.fn-overview ul{margin-bottom:1em;padding-left:20px}.fn-overview ul,.fn-overview ul li{list-style-type:disc}.fn-overview ol,.fn-overview ol li{list-style-type:decimal}@media screen and (max-width:480px){.fn-copyright{display:none}}@font-face{font-family:FontAwesome;src:url(../fonts/fontawesome-webfont.eot?v=4.1.0);src:url(../fonts/fontawesome-webfont.eot?#iefix&v=4.1.0)format("embedded-opentype"),url(../fonts/fontawesome-webfont.woff?v=4.1.0)format("woff"),url(../fonts/fontawesome-webfont.ttf?v=4.1.0)format("truetype"),url(../fonts/fontawesome-webfont.svg?v=4.1.0#fontawesomeregular)format("svg");font-weight:400;font-style:normal}.fn-icon{position:relative;display:inline-block;font-family:FontAwesome;font-style:normal;font-weight:400;line-height:1}.fn-icon.fn-glass:before{content:""}.fn-icon.fn-music:before{content:""}.fn-icon.fn-search:before{content:""}.fn-icon.fn-envelope-o:before{content:""}.fn-icon.fn-heart:before{content:""}.fn-icon.fn-star:before{content:""}.fn-icon.fn-star-o:before{content:""}.fn-icon.fn-user:before{content:""}.fn-icon.fn-film:before{content:""}.fn-icon.fn-th-large:before{content:""}.fn-icon.fn-th:before{content:""}.fn-icon.fn-th-list:before{content:""}.fn-icon.fn-check:before{content:""}.fn-icon.fn-times:before{content:""}.fn-icon.fn-search-plus:before{content:""}.fn-icon.fn-search-minus:before{content:""}.fn-icon.fn-power-off:before{content:""}.fn-icon.fn-signal:before{content:""}.fn-icon.fn-cog:before,.fn-icon.fn-gear:before{content:""}.fn-icon.fn-trash-o:before{content:""}.fn-icon.fn-home:before{content:""}.fn-icon.fn-file-o:before{content:""}.fn-icon.fn-clock-o:before{content:""}.fn-icon.fn-road:before{content:""}.fn-icon.fn-download:before{content:""}.fn-icon.fn-arrow-circle-o-down:before{content:""}.fn-icon.fn-arrow-circle-o-up:before{content:""}.fn-icon.fn-inbox:before{content:""}.fn-icon.fn-play-circle-o:before{content:""}.fn-icon.fn-repeat:before,.fn-icon.fn-rotate-right:before{content:""}.fn-icon.fn-refresh:before{content:""}.fn-icon.fn-list-alt:before{content:""}.fn-icon.fn-lock:before{content:""}.fn-icon.fn-flag:before{content:""}.fn-icon.fn-headphones:before{content:""}.fn-icon.fn-volume-off:before{content:""}.fn-icon.fn-volume-down:before{content:""}.fn-icon.fn-volume-up:before{content:""}.fn-icon.fn-qrcode:before{content:""}.fn-icon.fn-barcode:before{content:""}.fn-icon.fn-tag:before{content:""}.fn-icon.fn-tags:before{content:""}.fn-icon.fn-book:before{content:""}.fn-icon.fn-bookmark:before{content:""}.fn-icon.fn-print:before{content:""}.fn-icon.fn-camera:before{content:""}.fn-icon.fn-font:before{content:""}.fn-icon.fn-bold:before{content:""}.fn-icon.fn-italic:before{content:""}.fn-icon.fn-text-height:before{content:""}.fn-icon.fn-text-width:before{content:""}.fn-icon.fn-align-left:before{content:""}.fn-icon.fn-align-center:before{content:""}.fn-icon.fn-align-right:before{content:""}.fn-icon.fn-align-justify:before{content:""}.fn-icon.fn-list:before{content:""}.fn-icon.fn-dedent:before,.fn-icon.fn-outdent:before{content:""}.fn-icon.fn-indent:before{content:""}.fn-icon.fn-video-camera:before{content:""}.fn-icon.fn-image:before,.fn-icon.fn-photo:before,.fn-icon.fn-picture-o:before{content:""}.fn-icon.fn-pencil:before{content:""}.fn-icon.fn-map-marker:before{content:""}.fn-icon.fn-adjust:before{content:""}.fn-icon.fn-tint:before{content:""}.fn-icon.fn-edit:before,.fn-icon.fn-pencil-square-o:before{content:""}.fn-icon.fn-share-square-o:before{content:""}.fn-icon.fn-check-square-o:before{content:""}.fn-icon.fn-arrows:before{content:""}.fn-icon.fn-step-backward:before{content:""}.fn-icon.fn-fast-backward:before{content:""}.fn-icon.fn-backward:before{content:""}.fn-icon.fn-play:before{content:""}.fn-icon.fn-pause:before{content:""}.fn-icon.fn-stop:before{content:""}.fn-icon.fn-forward:before{content:""}.fn-icon.fn-fast-forward:before{content:""}.fn-icon.fn-step-forward:before{content:""}.fn-icon.fn-eject:before{content:""}.fn-icon.fn-chevron-left:before{content:""}.fn-icon.fn-chevron-right:before{content:""}.fn-icon.fn-plus-circle:before{content:""}.fn-icon.fn-minus-circle:before{content:""}.fn-icon.fn-times-circle:before{content:""}.fn-icon.fn-check-circle:before{content:""}.fn-icon.fn-question-circle:before{content:""}.fn-icon.fn-info-circle:before{content:""}.fn-icon.fn-crosshairs:before{content:""}.fn-icon.fn-times-circle-o:before{content:""}.fn-icon.fn-check-circle-o:before{content:""}.fn-icon.fn-ban:before{content:""}.fn-icon.fn-arrow-left:before{content:""}.fn-icon.fn-arrow-right:before{content:""}.fn-icon.fn-arrow-up:before{content:""}.fn-icon.fn-arrow-down:before{content:""}.fn-icon.fn-mail-forward:before,.fn-icon.fn-share:before{content:""}.fn-icon.fn-expand:before{content:""}.fn-icon.fn-compress:before{content:""}.fn-icon.fn-plus:before{content:""}.fn-icon.fn-minus:before{content:""}.fn-icon.fn-asterisk:before{content:""}.fn-icon.fn-exclamation-circle:before{content:""}.fn-icon.fn-gift:before{content:""}.fn-icon.fn-leaf:before{content:""}.fn-icon.fn-fire:before{content:""}.fn-icon.fn-eye:before{content:""}.fn-icon.fn-eye-slash:before{content:""}.fn-icon.fn-exclamation-triangle:before,.fn-icon.fn-warning:before{content:""}.fn-icon.fn-plane:before{content:""}.fn-icon.fn-calendar:before{content:""}.fn-icon.fn-random:before{content:""}.fn-icon.fn-comment:before{content:""}.fn-icon.fn-magnet:before{content:""}.fn-icon.fn-chevron-up:before{content:""}.fn-icon.fn-chevron-down:before{content:""}.fn-icon.fn-retweet:before{content:""}.fn-icon.fn-shopping-cart:before{content:""}.fn-icon.fn-folder:before{content:""}.fn-icon.fn-folder-open:before{content:""}.fn-icon.fn-arrows-v:before{content:""}.fn-icon.fn-arrows-h:before{content:""}.fn-icon.fn-bar-chart-o:before{content:""}.fn-icon.fn-twitter-square:before{content:""}.fn-icon.fn-facebook-square:before{content:""}.fn-icon.fn-camera-retro:before{content:""}.fn-icon.fn-key:before{content:""}.fn-icon.fn-cogs:before,.fn-icon.fn-gears:before{content:""}.fn-icon.fn-comments:before{content:""}.fn-icon.fn-thumbs-o-up:before{content:""}.fn-icon.fn-thumbs-o-down:before{content:""}.fn-icon.fn-star-half:before{content:""}.fn-icon.fn-heart-o:before{content:""}.fn-icon.fn-sign-out:before{content:""}.fn-icon.fn-linkedin-square:before{content:""}.fn-icon.fn-thumb-tack:before{content:""}.fn-icon.fn-external-link:before{content:""}.fn-icon.fn-sign-in:before{content:""}.fn-icon.fn-trophy:before{content:""}.fn-icon.fn-github-square:before{content:""}.fn-icon.fn-upload:before{content:""}.fn-icon.fn-lemon-o:before{content:""}.fn-icon.fn-phone:before{content:""}.fn-icon.fn-square-o:before{content:""}.fn-icon.fn-bookmark-o:before{content:""}.fn-icon.fn-phone-square:before{content:""}.fn-icon.fn-twitter:before{content:""}.fn-icon.fn-facebook:before{content:""}.fn-icon.fn-github:before{content:""}.fn-icon.fn-unlock:before{content:""}.fn-icon.fn-credit-card:before{content:""}.fn-icon.fn-rss:before{content:""}.fn-icon.fn-hdd-o:before{content:""}.fn-icon.fn-bullhorn:before{content:""}.fn-icon.fn-bell:before{content:""}.fn-icon.fn-certificate:before{content:""}.fn-icon.fn-hand-o-right:before{content:""}.fn-icon.fn-hand-o-left:before{content:""}.fn-icon.fn-hand-o-up:before{content:""}.fn-icon.fn-hand-o-down:before{content:""}.fn-icon.fn-arrow-circle-left:before{content:""}.fn-icon.fn-arrow-circle-right:before{content:""}.fn-icon.fn-arrow-circle-up:before{content:""}.fn-icon.fn-arrow-circle-down:before{content:""}.fn-icon.fn-globe:before{content:""}.fn-icon.fn-wrench:before{content:""}.fn-icon.fn-tasks:before{content:""}.fn-icon.fn-filter:before{content:""}.fn-icon.fn-briefcase:before{content:""}.fn-icon.fn-arrows-alt:before{content:""}.fn-icon.fn-group:before,.fn-icon.fn-users:before{content:""}.fn-icon.fn-chain:before,.fn-icon.fn-link:before{content:""}.fn-icon.fn-cloud:before{content:""}.fn-icon.fn-flask:before{content:""}.fn-icon.fn-cut:before,.fn-icon.fn-scissors:before{content:""}.fn-icon.fn-copy:before,.fn-icon.fn-files-o:before{content:""}.fn-icon.fn-paperclip:before{content:""}.fn-icon.fn-floppy-o:before,.fn-icon.fn-save:before{content:""}.fn-icon.fn-square:before{content:""}.fn-icon.fn-bars:before,.fn-icon.fn-navicon:before,.fn-icon.fn-reorder:before{content:""}.fn-icon.fn-list-ul:before{content:""}.fn-icon.fn-list-ol:before{content:""}.fn-icon.fn-strikethrough:before{content:""}.fn-icon.fn-underline:before{content:""}.fn-icon.fn-table:before{content:""}.fn-icon.fn-magic:before{content:""}.fn-icon.fn-truck:before{content:""}.fn-icon.fn-pinterest:before{content:""}.fn-icon.fn-pinterest-square:before{content:""}.fn-icon.fn-google-plus-square:before{content:""}.fn-icon.fn-google-plus:before{content:""}.fn-icon.fn-money:before{content:""}.fn-icon.fn-caret-down:before{content:""}.fn-icon.fn-caret-up:before{content:""}.fn-icon.fn-caret-left:before{content:""}.fn-icon.fn-caret-right:before{content:""}.fn-icon.fn-columns:before{content:""}.fn-icon.fn-sort:before,.fn-icon.fn-unsorted:before{content:""}.fn-icon.fn-sort-desc:before,.fn-icon.fn-sort-down:before{content:""}.fn-icon.fn-sort-asc:before,.fn-icon.fn-sort-up:before{content:""}.fn-icon.fn-envelope:before{content:""}.fn-icon.fn-linkedin:before{content:""}.fn-icon.fn-rotate-left:before,.fn-icon.fn-undo:before{content:""}.fn-icon.fn-gavel:before,.fn-icon.fn-legal:before{content:""}.fn-icon.fn-dashboard:before,.fn-icon.fn-tachometer:before{content:""}.fn-icon.fn-comment-o:before{content:""}.fn-icon.fn-comments-o:before{content:""}.fn-icon.fn-bolt:before,.fn-icon.fn-flash:before{content:""}.fn-icon.fn-sitemap:before{content:""}.fn-icon.fn-umbrella:before{content:""}.fn-icon.fn-clipboard:before,.fn-icon.fn-paste:before{content:""}.fn-icon.fn-lightbulb-o:before{content:""}.fn-icon.fn-exchange:before{content:""}.fn-icon.fn-cloud-download:before{content:""}.fn-icon.fn-cloud-upload:before{content:""}.fn-icon.fn-user-md:before{content:""}.fn-icon.fn-stethoscope:before{content:""}.fn-icon.fn-suitcase:before{content:""}.fn-icon.fn-bell-o:before{content:""}.fn-icon.fn-coffee:before{content:""}.fn-icon.fn-cutlery:before{content:""}.fn-icon.fn-file-text-o:before{content:""}.fn-icon.fn-building-o:before{content:""}.fn-icon.fn-hospital-o:before{content:""}.fn-icon.fn-ambulance:before{content:""}.fn-icon.fn-medkit:before{content:""}.fn-icon.fn-fighter-jet:before{content:""}.fn-icon.fn-beer:before{content:""}.fn-icon.fn-h-square:before{content:""}.fn-icon.fn-plus-square:before{content:""}.fn-icon.fn-angle-double-left:before{content:""}.fn-icon.fn-angle-double-right:before{content:""}.fn-icon.fn-angle-double-up:before{content:""}.fn-icon.fn-angle-double-down:before{content:""}.fn-icon.fn-angle-left:before{content:""}.fn-icon.fn-angle-right:before{content:""}.fn-icon.fn-angle-up:before{content:""}.fn-icon.fn-angle-down:before{content:""}.fn-icon.fn-desktop:before{content:""}.fn-icon.fn-laptop:before{content:""}.fn-icon.fn-tablet:before{content:""}.fn-icon.fn-mobile-phone:before,.fn-icon.fn-mobile:before{content:""}.fn-icon.fn-circle-o:before{content:""}.fn-icon.fn-quote-left:before{content:""}.fn-icon.fn-quote-right:before{content:""}.fn-icon.fn-spinner:before{content:""}.fn-icon.fn-circle:before{content:""}.fn-icon.fn-mail-reply:before,.fn-icon.fn-reply:before{content:""}.fn-icon.fn-github-alt:before{content:""}.fn-icon.fn-folder-o:before{content:""}.fn-icon.fn-folder-open-o:before{content:""}.fn-icon.fn-smile-o:before{content:""}.fn-icon.fn-frown-o:before{content:""}.fn-icon.fn-meh-o:before{content:""}.fn-icon.fn-gamepad:before{content:""}.fn-icon.fn-keyboard-o:before{content:""}.fn-icon.fn-flag-o:before{content:""}.fn-icon.fn-flag-checkered:before{content:""}.fn-icon.fn-terminal:before{content:""}.fn-icon.fn-code:before{content:""}.fn-icon.fn-mail-reply-all:before,.fn-icon.fn-reply-all:before{content:""}.fn-icon.fn-star-half-empty:before,.fn-icon.fn-star-half-full:before,.fn-icon.fn-star-half-o:before{content:""}.fn-icon.fn-location-arrow:before{content:""}.fn-icon.fn-crop:before{content:""}.fn-icon.fn-code-fork:before{content:""}.fn-icon.fn-chain-broken:before,.fn-icon.fn-unlink:before{content:""}.fn-icon.fn-question:before{content:""}.fn-icon.fn-info:before{content:""}.fn-icon.fn-exclamation:before{content:""}.fn-icon.fn-superscript:before{content:""}.fn-icon.fn-subscript:before{content:""}.fn-icon.fn-eraser:before{content:""}.fn-icon.fn-puzzle-piece:before{content:""}.fn-icon.fn-microphone:before{content:""}.fn-icon.fn-microphone-slash:before{content:""}.fn-icon.fn-shield:before{content:""}.fn-icon.fn-calendar-o:before{content:""}.fn-icon.fn-fire-extinguisher:before{content:""}.fn-icon.fn-rocket:before{content:""}.fn-icon.fn-maxcdn:before{content:""}.fn-icon.fn-chevron-circle-left:before{content:""}.fn-icon.fn-chevron-circle-right:before{content:""}.fn-icon.fn-chevron-circle-up:before{content:""}.fn-icon.fn-chevron-circle-down:before{content:""}.fn-icon.fn-html5:before{content:""}.fn-icon.fn-css3:before{content:""}.fn-icon.fn-anchor:before{content:""}.fn-icon.fn-unlock-alt:before{content:""}.fn-icon.fn-bullseye:before{content:""}.fn-icon.fn-ellipsis-h:before{content:""}.fn-icon.fn-ellipsis-v:before{content:""}.fn-icon.fn-rss-square:before{content:""}.fn-icon.fn-play-circle:before{content:""}.fn-icon.fn-ticket:before{content:""}.fn-icon.fn-minus-square:before{content:""}.fn-icon.fn-minus-square-o:before{content:""}.fn-icon.fn-level-up:before{content:""}.fn-icon.fn-level-down:before{content:""}.fn-icon.fn-check-square:before{content:""}.fn-icon.fn-pencil-square:before{content:""}.fn-icon.fn-external-link-square:before{content:""}.fn-icon.fn-share-square:before{content:""}.fn-icon.fn-compass:before{content:""}.fn-icon.fn-caret-square-o-down:before,.fn-icon.fn-toggle-down:before{content:""}.fn-icon.fn-caret-square-o-up:before,.fn-icon.fn-toggle-up:before{content:""}.fn-icon.fn-caret-square-o-right:before,.fn-icon.fn-toggle-right:before{content:""}.fn-icon.fn-eur:before,.fn-icon.fn-euro:before{content:""}.fn-icon.fn-gbp:before{content:""}.fn-icon.fn-dollar:before,.fn-icon.fn-usd:before{content:""}.fn-icon.fn-inr:before,.fn-icon.fn-rupee:before{content:""}.fn-icon.fn-cny:before,.fn-icon.fn-jpy:before,.fn-icon.fn-rmb:before,.fn-icon.fn-yen:before{content:""}.fn-icon.fn-rouble:before,.fn-icon.fn-rub:before,.fn-icon.fn-ruble:before{content:""}.fn-icon.fn-krw:before,.fn-icon.fn-won:before{content:""}.fn-icon.fn-bitcoin:before,.fn-icon.fn-btc:before{content:""}.fn-icon.fn-file:before{content:""}.fn-icon.fn-file-text:before{content:""}.fn-icon.fn-sort-alpha-asc:before{content:""}.fn-icon.fn-sort-alpha-desc:before{content:""}.fn-icon.fn-sort-amount-asc:before{content:""}.fn-icon.fn-sort-amount-desc:before{content:""}.fn-icon.fn-sort-numeric-asc:before{content:""}.fn-icon.fn-sort-numeric-desc:before{content:""}.fn-icon.fn-thumbs-up:before{content:""}.fn-icon.fn-thumbs-down:before{content:""}.fn-icon.fn-youtube-square:before{content:""}.fn-icon.fn-youtube:before{content:""}.fn-icon.fn-xing:before{content:""}.fn-icon.fn-xing-square:before{content:""}.fn-icon.fn-youtube-play:before{content:""}.fn-icon.fn-dropbox:before{content:""}.fn-icon.fn-stack-overflow:before{content:""}.fn-icon.fn-instagram:before{content:""}.fn-icon.fn-flickr:before{content:""}.fn-icon.fn-adn:before{content:""}.fn-icon.fn-bitbucket:before{content:""}.fn-icon.fn-bitbucket-square:before{content:""}.fn-icon.fn-tumblr:before{content:""}.fn-icon.fn-tumblr-square:before{content:""}.fn-icon.fn-long-arrow-down:before{content:""}.fn-icon.fn-long-arrow-up:before{content:""}.fn-icon.fn-long-arrow-left:before{content:""}.fn-icon.fn-long-arrow-right:before{content:""}.fn-icon.fn-apple:before{content:""}.fn-icon.fn-windows:before{content:""}.fn-icon.fn-android:before{content:""}.fn-icon.fn-linux:before{content:""}.fn-icon.fn-dribbble:before{content:""}.fn-icon.fn-skype:before{content:""}.fn-icon.fn-foursquare:before{content:""}.fn-icon.fn-trello:before{content:""}.fn-icon.fn-female:before{content:""}.fn-icon.fn-male:before{content:""}.fn-icon.fn-gittip:before{content:""}.fn-icon.fn-sun-o:before{content:""}.fn-icon.fn-moon-o:before{content:""}.fn-icon.fn-archive:before{content:""}.fn-icon.fn-bug:before{content:""}.fn-icon.fn-vk:before{content:""}.fn-icon.fn-weibo:before{content:""}.fn-icon.fn-renren:before{content:""}.fn-icon.fn-pagelines:before{content:""}.fn-icon.fn-stack-exchange:before{content:""}.fn-icon.fn-arrow-circle-o-right:before{content:""}.fn-icon.fn-arrow-circle-o-left:before{content:""}.fn-icon.fn-caret-square-o-left:before,.fn-icon.fn-toggle-left:before{content:""}.fn-icon.fn-dot-circle-o:before{content:""}.fn-icon.fn-wheelchair:before{content:""}.fn-icon.fn-vimeo-square:before{content:""}.fn-icon.fn-try:before,.fn-icon.fn-turkish-lira:before{content:""}.fn-icon.fn-plus-square-o:before{content:""}.fn-icon.fn-space-shuttle:before{content:""}.fn-icon.fn-slack:before{content:""}.fn-icon.fn-envelope-square:before{content:""}.fn-icon.fn-wordpress:before{content:""}.fn-icon.fn-openid:before{content:""}.fn-icon.fn-bank:before,.fn-icon.fn-institution:before,.fn-icon.fn-university:before{content:""}.fn-icon.fn-graduation-cap:before,.fn-icon.fn-mortar-board:before{content:""}.fn-icon.fn-yahoo:before{content:""}.fn-icon.fn-google:before{content:""}.fn-icon.fn-reddit:before{content:""}.fn-icon.fn-reddit-square:before{content:""}.fn-icon.fn-stumbleupon-circle:before{content:""}.fn-icon.fn-stumbleupon:before{content:""}.fn-icon.fn-delicious:before{content:""}.fn-icon.fn-digg:before{content:""}.fn-icon.fn-pied-piper-square:before,.fn-icon.fn-pied-piper:before{content:""}.fn-icon.fn-pied-piper-alt:before{content:""}.fn-icon.fn-drupal:before{content:""}.fn-icon.fn-joomla:before{content:""}.fn-icon.fn-language:before{content:""}.fn-icon.fn-fax:before{content:""}.fn-icon.fn-building:before{content:""}.fn-icon.fn-child:before{content:""}.fn-icon.fn-paw:before{content:""}.fn-icon.fn-spoon:before{content:""}.fn-icon.fn-cube:before{content:""}.fn-icon.fn-cubes:before{content:""}.fn-icon.fn-behance:before{content:""}.fn-icon.fn-behance-square:before{content:""}.fn-icon.fn-steam:before{content:""}.fn-icon.fn-steam-square:before{content:""}.fn-icon.fn-recycle:before{content:""}.fn-icon.fn-automobile:before,.fn-icon.fn-car:before{content:""}.fn-icon.fn-cab:before,.fn-icon.fn-taxi:before{content:""}.fn-icon.fn-tree:before{content:""}.fn-icon.fn-spotify:before{content:""}.fn-icon.fn-deviantart:before{content:""}.fn-icon.fn-soundcloud:before{content:""}.fn-icon.fn-database:before{content:""}.fn-icon.fn-file-pdf-o:before{content:""}.fn-icon.fn-file-word-o:before{content:""}.fn-icon.fn-file-excel-o:before{content:""}.fn-icon.fn-file-powerpoint-o:before{content:""}.fn-icon.fn-file-image-o:before,.fn-icon.fn-file-photo-o:before,.fn-icon.fn-file-picture-o:before{content:""}.fn-icon.fn-file-archive-o:before,.fn-icon.fn-file-zip-o:before{content:""}.fn-icon.fn-file-audio-o:before,.fn-icon.fn-file-sound-o:before{content:""}.fn-icon.fn-file-movie-o:before,.fn-icon.fn-file-video-o:before{content:""}.fn-icon.fn-file-code-o:before{content:""}.fn-icon.fn-vine:before{content:""}.fn-icon.fn-codepen:before{content:""}.fn-icon.fn-jsfiddle:before{content:""}.fn-icon.fn-life-bouy:before,.fn-icon.fn-life-ring:before,.fn-icon.fn-life-saver:before,.fn-icon.fn-support:before{content:""}.fn-icon.fn-circle-o-notch:before{content:""}.fn-icon.fn-ra:before,.fn-icon.fn-rebel:before{content:""}.fn-icon.fn-empire:before,.fn-icon.fn-ge:before{content:""}.fn-icon.fn-git-square:before{content:""}.fn-icon.fn-git:before{content:""}.fn-icon.fn-hacker-news:before{content:""}.fn-icon.fn-tencent-weibo:before{content:""}.fn-icon.fn-qq:before{content:""}.fn-icon.fn-wechat:before,.fn-icon.fn-weixin:before{content:""}.fn-icon.fn-paper-plane:before,.fn-icon.fn-send:before{content:""}.fn-icon.fn-paper-plane-o:before,.fn-icon.fn-send-o:before{content:""}.fn-icon.fn-history:before{content:""}.fn-icon.fn-circle-thin:before{content:""}.fn-icon.fn-header:before{content:""}.fn-icon.fn-paragraph:before{content:""}.fn-icon.fn-sliders:before{content:""}.fn-icon.fn-share-alt:before{content:""}.fn-icon.fn-share-alt-square:before{content:""}.fn-icon.fn-bomb:before{content:""}@media screen and (max-width:680px){.fn-content{padding:20px}.fn-sidebar{margin-left:-250px}.fn-mobile-visible{display:block}.fn-pc-visible{display:none}} -------------------------------------------------------------------------------- /template/assets/lib/jquery.js: -------------------------------------------------------------------------------- 1 | /*! jQuery v1.11.1 | (c) 2005, 2014 jQuery Foundation, Inc. | jquery.org/license */ 2 | !function(e,t){"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(e,t){function n(e){var t=e.length,n=ie.type(e);return"function"===n||ie.isWindow(e)?!1:1===e.nodeType&&t?!0:"array"===n||0===t||"number"==typeof t&&t>0&&t-1 in e}function r(e,t,n){if(ie.isFunction(t))return ie.grep(e,function(e,r){return!!t.call(e,r,e)!==n});if(t.nodeType)return ie.grep(e,function(e){return e===t!==n});if("string"==typeof t){if(fe.test(t))return ie.filter(t,e,n);t=ie.filter(t,e)}return ie.grep(e,function(e){return ie.inArray(e,t)>=0!==n})}function i(e,t){do e=e[t];while(e&&1!==e.nodeType);return e}function o(e){var t=xe[e]={};return ie.each(e.match(be)||[],function(e,n){t[n]=!0}),t}function a(){he.addEventListener?(he.removeEventListener("DOMContentLoaded",s,!1),e.removeEventListener("load",s,!1)):(he.detachEvent("onreadystatechange",s),e.detachEvent("onload",s))}function s(){(he.addEventListener||"load"===event.type||"complete"===he.readyState)&&(a(),ie.ready())}function l(e,t,n){if(void 0===n&&1===e.nodeType){var r="data-"+t.replace(Ee,"-$1").toLowerCase();if(n=e.getAttribute(r),"string"==typeof n){try{n="true"===n?!0:"false"===n?!1:"null"===n?null:+n+""===n?+n:Ne.test(n)?ie.parseJSON(n):n}catch(i){}ie.data(e,t,n)}else n=void 0}return n}function u(e){var t;for(t in e)if(("data"!==t||!ie.isEmptyObject(e[t]))&&"toJSON"!==t)return!1;return!0}function c(e,t,n,r){if(ie.acceptData(e)){var i,o,a=ie.expando,s=e.nodeType,l=s?ie.cache:e,u=s?e[a]:e[a]&&a;if(u&&l[u]&&(r||l[u].data)||void 0!==n||"string"!=typeof t)return u||(u=s?e[a]=J.pop()||ie.guid++:a),l[u]||(l[u]=s?{}:{toJSON:ie.noop}),("object"==typeof t||"function"==typeof t)&&(r?l[u]=ie.extend(l[u],t):l[u].data=ie.extend(l[u].data,t)),o=l[u],r||(o.data||(o.data={}),o=o.data),void 0!==n&&(o[ie.camelCase(t)]=n),"string"==typeof t?(i=o[t],null==i&&(i=o[ie.camelCase(t)])):i=o,i}}function d(e,t,n){if(ie.acceptData(e)){var r,i,o=e.nodeType,a=o?ie.cache:e,s=o?e[ie.expando]:ie.expando;if(a[s]){if(t&&(r=n?a[s]:a[s].data)){ie.isArray(t)?t=t.concat(ie.map(t,ie.camelCase)):t in r?t=[t]:(t=ie.camelCase(t),t=t in r?[t]:t.split(" ")),i=t.length;for(;i--;)delete r[t[i]];if(n?!u(r):!ie.isEmptyObject(r))return}(n||(delete a[s].data,u(a[s])))&&(o?ie.cleanData([e],!0):ne.deleteExpando||a!=a.window?delete a[s]:a[s]=null)}}}function f(){return!0}function p(){return!1}function h(){try{return he.activeElement}catch(e){}}function m(e){var t=Oe.split("|"),n=e.createDocumentFragment();if(n.createElement)for(;t.length;)n.createElement(t.pop());return n}function g(e,t){var n,r,i=0,o=typeof e.getElementsByTagName!==Ce?e.getElementsByTagName(t||"*"):typeof e.querySelectorAll!==Ce?e.querySelectorAll(t||"*"):void 0;if(!o)for(o=[],n=e.childNodes||e;null!=(r=n[i]);i++)!t||ie.nodeName(r,t)?o.push(r):ie.merge(o,g(r,t));return void 0===t||t&&ie.nodeName(e,t)?ie.merge([e],o):o}function v(e){je.test(e.type)&&(e.defaultChecked=e.checked)}function y(e,t){return ie.nodeName(e,"table")&&ie.nodeName(11!==t.nodeType?t:t.firstChild,"tr")?e.getElementsByTagName("tbody")[0]||e.appendChild(e.ownerDocument.createElement("tbody")):e}function b(e){return e.type=(null!==ie.find.attr(e,"type"))+"/"+e.type,e}function x(e){var t=Ve.exec(e.type);return t?e.type=t[1]:e.removeAttribute("type"),e}function w(e,t){for(var n,r=0;null!=(n=e[r]);r++)ie._data(n,"globalEval",!t||ie._data(t[r],"globalEval"))}function T(e,t){if(1===t.nodeType&&ie.hasData(e)){var n,r,i,o=ie._data(e),a=ie._data(t,o),s=o.events;if(s){delete a.handle,a.events={};for(n in s)for(r=0,i=s[n].length;i>r;r++)ie.event.add(t,n,s[n][r])}a.data&&(a.data=ie.extend({},a.data))}}function C(e,t){var n,r,i;if(1===t.nodeType){if(n=t.nodeName.toLowerCase(),!ne.noCloneEvent&&t[ie.expando]){i=ie._data(t);for(r in i.events)ie.removeEvent(t,r,i.handle);t.removeAttribute(ie.expando)}"script"===n&&t.text!==e.text?(b(t).text=e.text,x(t)):"object"===n?(t.parentNode&&(t.outerHTML=e.outerHTML),ne.html5Clone&&e.innerHTML&&!ie.trim(t.innerHTML)&&(t.innerHTML=e.innerHTML)):"input"===n&&je.test(e.type)?(t.defaultChecked=t.checked=e.checked,t.value!==e.value&&(t.value=e.value)):"option"===n?t.defaultSelected=t.selected=e.defaultSelected:("input"===n||"textarea"===n)&&(t.defaultValue=e.defaultValue)}}function N(t,n){var r,i=ie(n.createElement(t)).appendTo(n.body),o=e.getDefaultComputedStyle&&(r=e.getDefaultComputedStyle(i[0]))?r.display:ie.css(i[0],"display");return i.detach(),o}function E(e){var t=he,n=Ze[e];return n||(n=N(e,t),"none"!==n&&n||(Ke=(Ke||ie("