├── .npmignore ├── node ├── savedAliases.json ├── savedTasks.json ├── tests │ ├── commands │ │ ├── grunt-test │ │ │ ├── src │ │ │ │ ├── B.js │ │ │ │ └── A.js │ │ │ ├── dist │ │ │ │ └── scripts.js │ │ │ └── Gruntfile.js │ │ ├── continues-with-params.js │ │ ├── continues.js │ │ ├── continues-fail.js │ │ ├── server.js │ │ ├── server-fail.js │ │ └── stdin-program.js │ └── tests.js ├── helpers │ └── CommandParser.js ├── TaskRunner.js └── index.js ├── .gitignore ├── chrome ├── devtools.html ├── img │ ├── icon128.png │ ├── icon16.png │ ├── icon16w.png │ ├── icon19.png │ ├── icon19w.png │ ├── icon38.png │ ├── icon48.ico │ ├── icon48.png │ ├── icon48w.ico │ ├── icon48w.png │ └── logo-big.jpg ├── devtools.js ├── css │ ├── fonts │ │ ├── neaHiVpEUkuPmSawsrNWSg.woff │ │ └── 77FXFjRbGzN4aCrSFhlh3j8E0i7KZn-EPnyo3HZu7kw.woff │ ├── font-awesome-4.1.0 │ │ ├── fonts │ │ │ ├── FontAwesome.otf │ │ │ ├── fontawesome-webfont.eot │ │ │ ├── fontawesome-webfont.ttf │ │ │ └── fontawesome-webfont.woff │ │ ├── less │ │ │ ├── fixed-width.less │ │ │ ├── core.less │ │ │ ├── bordered-pulled.less │ │ │ ├── rotated-flipped.less │ │ │ ├── larger.less │ │ │ ├── list.less │ │ │ ├── font-awesome.less │ │ │ ├── stacked.less │ │ │ ├── path.less │ │ │ ├── mixins.less │ │ │ ├── spinning.less │ │ │ └── variables.less │ │ ├── scss │ │ │ ├── _fixed-width.scss │ │ │ ├── _core.scss │ │ │ ├── _bordered-pulled.scss │ │ │ ├── _larger.scss │ │ │ ├── _rotated-flipped.scss │ │ │ ├── _list.scss │ │ │ ├── font-awesome.scss │ │ │ ├── _stacked.scss │ │ │ ├── _path.scss │ │ │ ├── _mixins.scss │ │ │ ├── _spinning.scss │ │ │ └── _variables.scss │ │ └── css │ │ │ └── font-awesome.min.css │ ├── font.css │ ├── status.css │ ├── nav.css │ ├── Yez.css │ ├── cwd.css │ ├── home.css │ ├── dark.css │ └── task.css ├── js │ ├── utils │ │ ├── misc.js │ │ ├── Extend.js │ │ ├── History.js │ │ └── Autocomplete.js │ ├── components │ │ ├── Status.js │ │ ├── Editor.js │ │ ├── Content.js │ │ ├── CWD.js │ │ ├── Nav.js │ │ ├── Home.js │ │ └── Task.js │ ├── content.js │ ├── background.js │ ├── vendors │ │ ├── ansi_up.js │ │ └── keypress-2.0.2.min.js │ └── Yez.js ├── manifest.json └── index.html ├── _design ├── banner.jpg └── banner.psd ├── LICENSE ├── package.json ├── README.md └── electron └── tray.js /.npmignore: -------------------------------------------------------------------------------- 1 | node_modules -------------------------------------------------------------------------------- /node/savedAliases.json: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /node/savedTasks.json: -------------------------------------------------------------------------------- 1 | [] -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .DS_Store -------------------------------------------------------------------------------- /node/tests/commands/grunt-test/src/B.js: -------------------------------------------------------------------------------- 1 | b -------------------------------------------------------------------------------- /chrome/devtools.html: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /_design/banner.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krasimir/yez/HEAD/_design/banner.jpg -------------------------------------------------------------------------------- /_design/banner.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krasimir/yez/HEAD/_design/banner.psd -------------------------------------------------------------------------------- /chrome/img/icon128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krasimir/yez/HEAD/chrome/img/icon128.png -------------------------------------------------------------------------------- /chrome/img/icon16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krasimir/yez/HEAD/chrome/img/icon16.png -------------------------------------------------------------------------------- /chrome/img/icon16w.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krasimir/yez/HEAD/chrome/img/icon16w.png -------------------------------------------------------------------------------- /chrome/img/icon19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krasimir/yez/HEAD/chrome/img/icon19.png -------------------------------------------------------------------------------- /chrome/img/icon19w.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krasimir/yez/HEAD/chrome/img/icon19w.png -------------------------------------------------------------------------------- /chrome/img/icon38.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krasimir/yez/HEAD/chrome/img/icon38.png -------------------------------------------------------------------------------- /chrome/img/icon48.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krasimir/yez/HEAD/chrome/img/icon48.ico -------------------------------------------------------------------------------- /chrome/img/icon48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krasimir/yez/HEAD/chrome/img/icon48.png -------------------------------------------------------------------------------- /chrome/img/icon48w.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krasimir/yez/HEAD/chrome/img/icon48w.ico -------------------------------------------------------------------------------- /chrome/img/icon48w.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krasimir/yez/HEAD/chrome/img/icon48w.png -------------------------------------------------------------------------------- /chrome/img/logo-big.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krasimir/yez/HEAD/chrome/img/logo-big.jpg -------------------------------------------------------------------------------- /node/tests/commands/grunt-test/src/A.js: -------------------------------------------------------------------------------- 1 | accccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc -------------------------------------------------------------------------------- /chrome/devtools.js: -------------------------------------------------------------------------------- 1 | chrome.devtools.panels.create( 2 | "Yez!", 3 | "img/icon16.png", 4 | "index.html", 5 | function() {} 6 | ); -------------------------------------------------------------------------------- /node/tests/commands/continues-with-params.js: -------------------------------------------------------------------------------- 1 | process.argv.shift(); 2 | process.argv.shift(); 3 | console.log(process.argv.join(',')); -------------------------------------------------------------------------------- /node/tests/commands/grunt-test/dist/scripts.js: -------------------------------------------------------------------------------- 1 | acccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc 2 | b -------------------------------------------------------------------------------- /chrome/css/fonts/neaHiVpEUkuPmSawsrNWSg.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krasimir/yez/HEAD/chrome/css/fonts/neaHiVpEUkuPmSawsrNWSg.woff -------------------------------------------------------------------------------- /chrome/css/font-awesome-4.1.0/fonts/FontAwesome.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krasimir/yez/HEAD/chrome/css/font-awesome-4.1.0/fonts/FontAwesome.otf -------------------------------------------------------------------------------- /chrome/css/font-awesome-4.1.0/fonts/fontawesome-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krasimir/yez/HEAD/chrome/css/font-awesome-4.1.0/fonts/fontawesome-webfont.eot -------------------------------------------------------------------------------- /chrome/css/font-awesome-4.1.0/fonts/fontawesome-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krasimir/yez/HEAD/chrome/css/font-awesome-4.1.0/fonts/fontawesome-webfont.ttf -------------------------------------------------------------------------------- /chrome/css/font-awesome-4.1.0/fonts/fontawesome-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krasimir/yez/HEAD/chrome/css/font-awesome-4.1.0/fonts/fontawesome-webfont.woff -------------------------------------------------------------------------------- /chrome/css/fonts/77FXFjRbGzN4aCrSFhlh3j8E0i7KZn-EPnyo3HZu7kw.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krasimir/yez/HEAD/chrome/css/fonts/77FXFjRbGzN4aCrSFhlh3j8E0i7KZn-EPnyo3HZu7kw.woff -------------------------------------------------------------------------------- /node/tests/commands/continues.js: -------------------------------------------------------------------------------- 1 | var i = 10; 2 | (function process() { 3 | if(i > 0) { 4 | i--; 5 | console.log('hello ' + i); 6 | setTimeout(process, 60); 7 | } 8 | })(); -------------------------------------------------------------------------------- /chrome/css/font-awesome-4.1.0/less/fixed-width.less: -------------------------------------------------------------------------------- 1 | // Fixed Width Icons 2 | // ------------------------- 3 | .@{fa-css-prefix}-fw { 4 | width: (18em / 14); 5 | text-align: center; 6 | } 7 | -------------------------------------------------------------------------------- /chrome/css/font-awesome-4.1.0/scss/_fixed-width.scss: -------------------------------------------------------------------------------- 1 | // Fixed Width Icons 2 | // ------------------------- 3 | .#{$fa-css-prefix}-fw { 4 | width: (18em / 14); 5 | text-align: center; 6 | } 7 | -------------------------------------------------------------------------------- /node/tests/commands/continues-fail.js: -------------------------------------------------------------------------------- 1 | var i = 10; 2 | (function process() { 3 | if(i > 0) { 4 | i--; 5 | console.log('hello ' + i); 6 | if(i == 4) { 7 | throw new Error('Ops!'); 8 | } 9 | setTimeout(process, 60); 10 | } 11 | })(); -------------------------------------------------------------------------------- /node/tests/commands/server.js: -------------------------------------------------------------------------------- 1 | var http = require('http'); 2 | http.createServer(function (req, res) { 3 | res.writeHead(200, {'Content-Type': 'text/plain'}); 4 | console.log('Processing request'); 5 | res.end('Hello World\n'); 6 | }).listen(1339, '127.0.0.1'); 7 | console.log('Server running at http://127.0.0.1:1339/'); -------------------------------------------------------------------------------- /node/tests/commands/server-fail.js: -------------------------------------------------------------------------------- 1 | var http = require('http'); 2 | http.createServer(function (req, res) { 3 | res.writeHead(200, {'Content-Type': 'text/plain'}); 4 | throw new Error('Ops!'); 5 | console.log('Processing request'); 6 | res.end('Hello World\n'); 7 | }).listen(1338, '127.0.0.1'); 8 | console.log('Server running at http://127.0.0.1:1338/'); -------------------------------------------------------------------------------- /chrome/css/font-awesome-4.1.0/less/core.less: -------------------------------------------------------------------------------- 1 | // Base Class Definition 2 | // ------------------------- 3 | 4 | .@{fa-css-prefix} { 5 | display: inline-block; 6 | font-family: FontAwesome; 7 | font-style: normal; 8 | font-weight: normal; 9 | line-height: 1; 10 | -webkit-font-smoothing: antialiased; 11 | -moz-osx-font-smoothing: grayscale; 12 | } 13 | -------------------------------------------------------------------------------- /chrome/css/font-awesome-4.1.0/scss/_core.scss: -------------------------------------------------------------------------------- 1 | // Base Class Definition 2 | // ------------------------- 3 | 4 | .#{$fa-css-prefix} { 5 | display: inline-block; 6 | font-family: FontAwesome; 7 | font-style: normal; 8 | font-weight: normal; 9 | line-height: 1; 10 | -webkit-font-smoothing: antialiased; 11 | -moz-osx-font-smoothing: grayscale; 12 | } 13 | -------------------------------------------------------------------------------- /node/tests/commands/stdin-program.js: -------------------------------------------------------------------------------- 1 | var fs = require('fs'); 2 | var readline = require('readline'); 3 | var rl = readline.createInterface({ 4 | input: process.stdin, 5 | output: process.stdout 6 | }); 7 | 8 | rl.question('Please type your name:', function(answer) { 9 | console.log('Hello ' + answer + '. It\'s nice to mee you.'); 10 | rl.close(); 11 | process.exit(); 12 | }); -------------------------------------------------------------------------------- /chrome/js/utils/misc.js: -------------------------------------------------------------------------------- 1 | var getId = function (prefix) { 2 | var d = new Date().getTime(); 3 | d += (parseInt(Math.random() * 100)).toString(); 4 | if (undefined === prefix) { 5 | prefix = 'uid-'; 6 | } 7 | d = prefix + d; 8 | return d; 9 | }; 10 | var normalizePath = function(p) { 11 | return p.replace(/\\/g, Yez.sep || '/'); 12 | } 13 | absurd = Absurd(); -------------------------------------------------------------------------------- /chrome/js/utils/Extend.js: -------------------------------------------------------------------------------- 1 | var extend = function() { 2 | var process = function(destination, source) { 3 | for (var key in source) { 4 | if (hasOwnProperty.call(source, key)) { 5 | destination[key] = source[key]; 6 | } 7 | } 8 | return destination; 9 | }; 10 | var result = arguments[0]; 11 | for(var i=1; i li { position: relative; } 9 | } 10 | .@{fa-css-prefix}-li { 11 | position: absolute; 12 | left: -@fa-li-width; 13 | width: @fa-li-width; 14 | top: (2em / 14); 15 | text-align: center; 16 | &.@{fa-css-prefix}-lg { 17 | left: -@fa-li-width + (4em / 14); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /chrome/css/font-awesome-4.1.0/scss/_rotated-flipped.scss: -------------------------------------------------------------------------------- 1 | // Rotated & Flipped Icons 2 | // ------------------------- 3 | 4 | .#{$fa-css-prefix}-rotate-90 { @include fa-icon-rotate(90deg, 1); } 5 | .#{$fa-css-prefix}-rotate-180 { @include fa-icon-rotate(180deg, 2); } 6 | .#{$fa-css-prefix}-rotate-270 { @include fa-icon-rotate(270deg, 3); } 7 | 8 | .#{$fa-css-prefix}-flip-horizontal { @include fa-icon-flip(-1, 1, 0); } 9 | .#{$fa-css-prefix}-flip-vertical { @include fa-icon-flip(1, -1, 2); } 10 | -------------------------------------------------------------------------------- /chrome/css/font-awesome-4.1.0/scss/_list.scss: -------------------------------------------------------------------------------- 1 | // List Icons 2 | // ------------------------- 3 | 4 | .#{$fa-css-prefix}-ul { 5 | padding-left: 0; 6 | margin-left: $fa-li-width; 7 | list-style-type: none; 8 | > li { position: relative; } 9 | } 10 | .#{$fa-css-prefix}-li { 11 | position: absolute; 12 | left: -$fa-li-width; 13 | width: $fa-li-width; 14 | top: (2em / 14); 15 | text-align: center; 16 | &.#{$fa-css-prefix}-lg { 17 | left: -$fa-li-width + (4em / 14); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /chrome/css/font-awesome-4.1.0/scss/font-awesome.scss: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome 4.1.0 by @davegandy - http://fontawesome.io - @fontawesome 3 | * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) 4 | */ 5 | 6 | @import "variables"; 7 | @import "mixins"; 8 | @import "path"; 9 | @import "core"; 10 | @import "larger"; 11 | @import "fixed-width"; 12 | @import "list"; 13 | @import "bordered-pulled"; 14 | @import "spinning"; 15 | @import "rotated-flipped"; 16 | @import "stacked"; 17 | @import "icons"; 18 | -------------------------------------------------------------------------------- /node/helpers/CommandParser.js: -------------------------------------------------------------------------------- 1 | var spawnargs = require('spawn-args'); 2 | module.exports = function(c) { 3 | var command = '', args = [], parts = c.split(' '); 4 | command = parts.shift(); 5 | args = spawnargs(parts.join(' ')); 6 | for(var i=0; i 1 ? ' retries' : ' retry') + ')'; 16 | } 17 | } 18 | }) -------------------------------------------------------------------------------- /chrome/css/font-awesome-4.1.0/less/font-awesome.less: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome 4.1.0 by @davegandy - http://fontawesome.io - @fontawesome 3 | * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) 4 | */ 5 | 6 | @import "variables.less"; 7 | @import "mixins.less"; 8 | @import "path.less"; 9 | @import "core.less"; 10 | @import "larger.less"; 11 | @import "fixed-width.less"; 12 | @import "list.less"; 13 | @import "bordered-pulled.less"; 14 | @import "spinning.less"; 15 | @import "rotated-flipped.less"; 16 | @import "stacked.less"; 17 | @import "icons.less"; 18 | -------------------------------------------------------------------------------- /chrome/css/font-awesome-4.1.0/less/stacked.less: -------------------------------------------------------------------------------- 1 | // Stacked Icons 2 | // ------------------------- 3 | 4 | .@{fa-css-prefix}-stack { 5 | position: relative; 6 | display: inline-block; 7 | width: 2em; 8 | height: 2em; 9 | line-height: 2em; 10 | vertical-align: middle; 11 | } 12 | .@{fa-css-prefix}-stack-1x, .@{fa-css-prefix}-stack-2x { 13 | position: absolute; 14 | left: 0; 15 | width: 100%; 16 | text-align: center; 17 | } 18 | .@{fa-css-prefix}-stack-1x { line-height: inherit; } 19 | .@{fa-css-prefix}-stack-2x { font-size: 2em; } 20 | .@{fa-css-prefix}-inverse { color: @fa-inverse; } 21 | -------------------------------------------------------------------------------- /chrome/css/font-awesome-4.1.0/scss/_stacked.scss: -------------------------------------------------------------------------------- 1 | // Stacked Icons 2 | // ------------------------- 3 | 4 | .#{$fa-css-prefix}-stack { 5 | position: relative; 6 | display: inline-block; 7 | width: 2em; 8 | height: 2em; 9 | line-height: 2em; 10 | vertical-align: middle; 11 | } 12 | .#{$fa-css-prefix}-stack-1x, .#{$fa-css-prefix}-stack-2x { 13 | position: absolute; 14 | left: 0; 15 | width: 100%; 16 | text-align: center; 17 | } 18 | .#{$fa-css-prefix}-stack-1x { line-height: inherit; } 19 | .#{$fa-css-prefix}-stack-2x { font-size: 2em; } 20 | .#{$fa-css-prefix}-inverse { color: $fa-inverse; } 21 | -------------------------------------------------------------------------------- /chrome/js/content.js: -------------------------------------------------------------------------------- 1 | chrome.extension.onMessage.addListener(function(command, sender, sendResponse) { 2 | switch(command.type) { 3 | case "click": 4 | var elements = document.querySelectorAll(command.data); 5 | if(elements && elements.length > 0) { 6 | elements[0].click(); 7 | sendResponse('Element clicked. There ' + (elements.length == 1 ? 'is one element' : elements.length + ' elements') + ' matching "' + command.data + '" selector.'); 8 | } else { 9 | sendResponse('There are no elements matching "' + command.data + '" selector.'); 10 | } 11 | break; 12 | } 13 | return true; 14 | }); -------------------------------------------------------------------------------- /chrome/css/status.css: -------------------------------------------------------------------------------- 1 | [data-component="status"] { 2 | padding: 5px 14px; 3 | float: right; 4 | color: #666; 5 | } 6 | 7 | [data-component="status"] .fa-flash { 8 | margin-right: 5px; 9 | color: #CC151A; 10 | } 11 | 12 | [data-component="status"].online .fa-flash { 13 | color: #26A430; 14 | } 15 | 16 | [data-component="status"] .info { 17 | position: absolute; 18 | font-size: 12px; 19 | width: 300px; 20 | line-height: 20px; 21 | text-align: right; 22 | display: block; 23 | background: #FFF; 24 | padding: 10px; 25 | border: solid 1px #DFD2B7; 26 | right: 14px; 27 | background: #fff6fa; 28 | top: 40px; 29 | } 30 | 31 | [data-component="status"].online .info { 32 | display: none; 33 | } 34 | -------------------------------------------------------------------------------- /chrome/css/font-awesome-4.1.0/scss/_path.scss: -------------------------------------------------------------------------------- 1 | /* FONT PATH 2 | * -------------------------- */ 3 | 4 | @font-face { 5 | font-family: 'FontAwesome'; 6 | src: url('#{$fa-font-path}/fontawesome-webfont.eot?v=#{$fa-version}'); 7 | src: url('#{$fa-font-path}/fontawesome-webfont.eot?#iefix&v=#{$fa-version}') format('embedded-opentype'), 8 | url('#{$fa-font-path}/fontawesome-webfont.woff?v=#{$fa-version}') format('woff'), 9 | url('#{$fa-font-path}/fontawesome-webfont.ttf?v=#{$fa-version}') format('truetype'), 10 | url('#{$fa-font-path}/fontawesome-webfont.svg?v=#{$fa-version}#fontawesomeregular') format('svg'); 11 | //src: url('#{$fa-font-path}/FontAwesome.otf') format('opentype'); // used when developing fonts 12 | font-weight: normal; 13 | font-style: normal; 14 | } 15 | -------------------------------------------------------------------------------- /chrome/css/font-awesome-4.1.0/less/path.less: -------------------------------------------------------------------------------- 1 | /* FONT PATH 2 | * -------------------------- */ 3 | 4 | @font-face { 5 | font-family: 'FontAwesome'; 6 | src: ~"url('@{fa-font-path}/fontawesome-webfont.eot?v=@{fa-version}')"; 7 | src: ~"url('@{fa-font-path}/fontawesome-webfont.eot?#iefix&v=@{fa-version}') format('embedded-opentype')", 8 | ~"url('@{fa-font-path}/fontawesome-webfont.woff?v=@{fa-version}') format('woff')", 9 | ~"url('@{fa-font-path}/fontawesome-webfont.ttf?v=@{fa-version}') format('truetype')", 10 | ~"url('@{fa-font-path}/fontawesome-webfont.svg?v=@{fa-version}#fontawesomeregular') format('svg')"; 11 | // src: url('@{fa-font-path}/FontAwesome.otf') format('opentype'); // used when developing fonts 12 | font-weight: normal; 13 | font-style: normal; 14 | } 15 | -------------------------------------------------------------------------------- /chrome/css/font-awesome-4.1.0/less/mixins.less: -------------------------------------------------------------------------------- 1 | // Mixins 2 | // -------------------------- 3 | 4 | .fa-icon-rotate(@degrees, @rotation) { 5 | filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=@rotation); 6 | -webkit-transform: rotate(@degrees); 7 | -moz-transform: rotate(@degrees); 8 | -ms-transform: rotate(@degrees); 9 | -o-transform: rotate(@degrees); 10 | transform: rotate(@degrees); 11 | } 12 | 13 | .fa-icon-flip(@horiz, @vert, @rotation) { 14 | filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=@rotation, mirror=1); 15 | -webkit-transform: scale(@horiz, @vert); 16 | -moz-transform: scale(@horiz, @vert); 17 | -ms-transform: scale(@horiz, @vert); 18 | -o-transform: scale(@horiz, @vert); 19 | transform: scale(@horiz, @vert); 20 | } 21 | -------------------------------------------------------------------------------- /chrome/css/font-awesome-4.1.0/scss/_mixins.scss: -------------------------------------------------------------------------------- 1 | // Mixins 2 | // -------------------------- 3 | 4 | @mixin fa-icon-rotate($degrees, $rotation) { 5 | filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=#{$rotation}); 6 | -webkit-transform: rotate($degrees); 7 | -moz-transform: rotate($degrees); 8 | -ms-transform: rotate($degrees); 9 | -o-transform: rotate($degrees); 10 | transform: rotate($degrees); 11 | } 12 | 13 | @mixin fa-icon-flip($horiz, $vert, $rotation) { 14 | filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=#{$rotation}); 15 | -webkit-transform: scale($horiz, $vert); 16 | -moz-transform: scale($horiz, $vert); 17 | -ms-transform: scale($horiz, $vert); 18 | -o-transform: scale($horiz, $vert); 19 | transform: scale($horiz, $vert); 20 | } 21 | -------------------------------------------------------------------------------- /node/tests/commands/grunt-test/Gruntfile.js: -------------------------------------------------------------------------------- 1 | module.exports = function(grunt) { 2 | 3 | grunt.initConfig({ 4 | // contcatenation 5 | concat: { 6 | // javascript 7 | js: { 8 | src: [ 9 | 'src/**/*.js' 10 | ], 11 | dest: 'dist/scripts.js', 12 | } 13 | }, 14 | watch: { 15 | js: { 16 | files: ['<%= concat.js.src %>'], 17 | tasks: ['concat:js'] 18 | } 19 | } 20 | }); 21 | 22 | // loading modules 23 | // grunt.loadNpmTasks('grunt-contrib-concat'); 24 | // grunt.loadNpmTasks('grunt-contrib-watch'); 25 | grunt.loadTasks(__dirname + '/../../../../node_modules/grunt-contrib-concat/tasks'); 26 | grunt.loadTasks(__dirname + '/../../../../node_modules/grunt-contrib-watch/tasks'); 27 | 28 | // grunt.registerTask('default', ['concat', 'less']); 29 | grunt.registerTask('default', ['concat', 'watch']); 30 | 31 | } -------------------------------------------------------------------------------- /chrome/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "manifest_version": 2, 3 | "name": "Yez", 4 | "description": "Task runner", 5 | "version": "0.2.0", 6 | "icons": { 7 | "16": "img/icon16.png", 8 | "48": "img/icon48.png", 9 | "128": "img/icon128.png" 10 | }, 11 | "permissions": [ 12 | "tabs", 13 | "debugger", 14 | "http://*/", 15 | "https://*/*", 16 | "webNavigation", 17 | "storage", 18 | "" 19 | ], 20 | "background": { 21 | "scripts": ["js/background.js"], 22 | "persistent": false 23 | }, 24 | "content_security_policy": "script-src 'self' 'unsafe-eval'; object-src 'self'", 25 | "devtools_page": "devtools.html", 26 | "content_scripts": [ 27 | { 28 | "matches": ["http://*/*", "https://*/*"], 29 | "js": ["js/content.js"] 30 | } 31 | ] 32 | } -------------------------------------------------------------------------------- /chrome/css/font-awesome-4.1.0/less/spinning.less: -------------------------------------------------------------------------------- 1 | // Spinning Icons 2 | // -------------------------- 3 | 4 | .@{fa-css-prefix}-spin { 5 | -webkit-animation: spin 2s infinite linear; 6 | -moz-animation: spin 2s infinite linear; 7 | -o-animation: spin 2s infinite linear; 8 | animation: spin 2s infinite linear; 9 | } 10 | 11 | @-moz-keyframes spin { 12 | 0% { -moz-transform: rotate(0deg); } 13 | 100% { -moz-transform: rotate(359deg); } 14 | } 15 | @-webkit-keyframes spin { 16 | 0% { -webkit-transform: rotate(0deg); } 17 | 100% { -webkit-transform: rotate(359deg); } 18 | } 19 | @-o-keyframes spin { 20 | 0% { -o-transform: rotate(0deg); } 21 | 100% { -o-transform: rotate(359deg); } 22 | } 23 | @keyframes spin { 24 | 0% { 25 | -webkit-transform: rotate(0deg); 26 | transform: rotate(0deg); 27 | } 28 | 100% { 29 | -webkit-transform: rotate(359deg); 30 | transform: rotate(359deg); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /chrome/css/font-awesome-4.1.0/scss/_spinning.scss: -------------------------------------------------------------------------------- 1 | // Spinning Icons 2 | // -------------------------- 3 | 4 | .#{$fa-css-prefix}-spin { 5 | -webkit-animation: spin 2s infinite linear; 6 | -moz-animation: spin 2s infinite linear; 7 | -o-animation: spin 2s infinite linear; 8 | animation: spin 2s infinite linear; 9 | } 10 | 11 | @-moz-keyframes spin { 12 | 0% { -moz-transform: rotate(0deg); } 13 | 100% { -moz-transform: rotate(359deg); } 14 | } 15 | @-webkit-keyframes spin { 16 | 0% { -webkit-transform: rotate(0deg); } 17 | 100% { -webkit-transform: rotate(359deg); } 18 | } 19 | @-o-keyframes spin { 20 | 0% { -o-transform: rotate(0deg); } 21 | 100% { -o-transform: rotate(359deg); } 22 | } 23 | @keyframes spin { 24 | 0% { 25 | -webkit-transform: rotate(0deg); 26 | transform: rotate(0deg); 27 | } 28 | 100% { 29 | -webkit-transform: rotate(359deg); 30 | transform: rotate(359deg); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /chrome/css/nav.css: -------------------------------------------------------------------------------- 1 | [data-component="nav"] { 2 | height: 26px; 3 | overflow: hidden; 4 | } 5 | 6 | [data-component="nav"] a { 7 | display: inline-block; 8 | text-decoration: none; 9 | padding: 5px 8px; 10 | color: #111; 11 | overflow: hidden; 12 | text-align: center; 13 | border: 0; 14 | background: transparent; 15 | } 16 | 17 | [data-component="nav"] a:hover { 18 | background: #D5D5D5; 19 | } 20 | 21 | [data-component="nav"] .task { 22 | box-sizing: border-box; 23 | } 24 | 25 | [data-component="nav"] .task.current { 26 | padding: 4px 7px 5px; 27 | border: 1px solid #ccc; 28 | border-bottom: 0; 29 | } 30 | 31 | [data-component="nav"] .toHome { 32 | padding: 4px 8px; 33 | display: block; 34 | width: 60px; 35 | float: left; 36 | } 37 | 38 | [data-component="nav"] .add { 39 | background: none; 40 | border-bottom: none; 41 | } 42 | 43 | [data-component="nav"] .add-task, 44 | [data-component="nav"] .add-terminal { 45 | float: right; 46 | } 47 | 48 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Krasimir Tsonev 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. -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "yez", 3 | "version": "2.1.0", 4 | "homepage": "https://github.com/krasimir/yez", 5 | "description": "Chrome extension which acts as task runner", 6 | "main": "./node/index.js", 7 | "author": { 8 | "name": "Krasimir Tsonev", 9 | "email": "info@krasimirtsonev.com", 10 | "url": "http://krasimirtsonev.com" 11 | }, 12 | "license": "MIT", 13 | "dependencies": { 14 | "electron-prebuilt": "0.37.6", 15 | "http-server": "0.9.0", 16 | "open": "0.0.5", 17 | "ps-tree": "0.0.3", 18 | "socket.io": "0.9.16", 19 | "spawn-args": "0.0.2", 20 | "yargs": "4.6.0" 21 | }, 22 | "devDependencies": { 23 | "expect.js": "0.3.1", 24 | "grunt": "0.4.1", 25 | "grunt-contrib-concat": "0.3.0", 26 | "grunt-contrib-watch": "0.4.4" 27 | }, 28 | "keywords": [ 29 | "chrome", 30 | "extension", 31 | "task", 32 | "runner" 33 | ], 34 | "repository": { 35 | "type": "git", 36 | "url": "https://github.com/krasimir/yez.git" 37 | }, 38 | "bin": { 39 | "yez": "./node/index.js" 40 | }, 41 | "scripts": { 42 | "test": "mocha ./node/tests --reporter spec", 43 | "start": "node ./node/index.js" 44 | } 45 | } -------------------------------------------------------------------------------- /chrome/js/components/Editor.js: -------------------------------------------------------------------------------- 1 | var Editor = absurd.component('Editor', { 2 | html: { 3 | '.dialog': { 4 | '.content': { 5 | '.info': ' <% title %>', 6 | '.inner.editor': [ 7 | { 'textarea' : '<% initialContent %>' } 8 | ], 9 | '.actions': [ 10 | { 'a[href="#" data-absurd-event="click:result:ok" class="button"]': ' OK'}, 11 | { 'a[href="#" data-absurd-event="click:result:cancel" class="button"]': ' Cancel'} 12 | ] 13 | } 14 | } 15 | }, 16 | result: function(e, res) { 17 | e.preventDefault(); 18 | if (this.callback && res === 'ok') this.callback(this.qs('textarea').value); 19 | document.querySelector('body').removeChild(this.populate().el); 20 | }, 21 | constructor: function(cb, content, title) { 22 | var self = this; 23 | this.initialContent = content; 24 | this.title = title; 25 | this.callback = cb; 26 | this.populate(); 27 | document.querySelector('body').appendChild(this.populate().el); 28 | setTimeout(function() { 29 | var ta = self.qs('textarea'); 30 | ta.focus(); 31 | ta.setSelectionRange(ta.value.length, ta.value.length); 32 | }, 400); 33 | } 34 | }); 35 | -------------------------------------------------------------------------------- /chrome/js/utils/History.js: -------------------------------------------------------------------------------- 1 | var TerminalHistory = { 2 | storage: {}, 3 | setup: function(f, id) { 4 | this.field = f; 5 | this.id = id; 6 | this.setIndexToTop(); 7 | }, 8 | off: function() { 9 | this.field = this.id = null; 10 | this.index = 0; 11 | }, 12 | store: function() { 13 | if(!this.field || !this.id) return; 14 | if(!this.storage[this.id]) this.storage[this.id] = []; 15 | this.storage[this.id].push(this.field.value); 16 | this.setIndexToTop(); 17 | }, 18 | pull: function(direction) { 19 | if(!this.field || !this.id) return; 20 | var arr = this.storage[this.id] ? this.storage[this.id] : [], res; 21 | res = arr[this.index] ? arr[this.index] : false; 22 | if(direction == 'up') { 23 | this.index = this.validateIndex(this.index - 1); 24 | } else { 25 | this.index = this.validateIndex(this.index + 1); 26 | } 27 | return res; 28 | }, 29 | validateIndex: function(current) { 30 | var max = this.storage[this.id] ? this.storage[this.id].length-1 : 0; 31 | if(current < 0) { 32 | return 0; 33 | } else if(current > max) { 34 | return max; 35 | } else { 36 | return current; 37 | } 38 | }, 39 | setIndexToTop: function() { 40 | this.index = this.storage[this.id] ? this.storage[this.id].length-1 : 0; 41 | } 42 | } -------------------------------------------------------------------------------- /chrome/css/Yez.css: -------------------------------------------------------------------------------- 1 | html, body { 2 | width: 100%; 3 | height: 100%; 4 | margin: 0; 5 | padding: 0; 6 | font-size: 12px; 7 | line-height: 16px; 8 | background: #fff; 9 | min-width: 400px; 10 | } 11 | 12 | html, input, textarea { 13 | font-family: 'Segoe UI', Tahoma, sans-serif; 14 | } 15 | 16 | a { 17 | text-decoration: none; 18 | color: #222; 19 | } 20 | 21 | .left { 22 | float: left; 23 | } 24 | 25 | .right { 26 | float: right; 27 | } 28 | 29 | code { 30 | border: solid 1px #D8D8D8; 31 | padding: 0 2px 0 2px; 32 | } 33 | 34 | .clear { 35 | clear: both; 36 | } 37 | 38 | .clearfix { 39 | clear: both; 40 | } 41 | 42 | .content { 43 | display: block; 44 | } 45 | 46 | header { 47 | background: #F3EEE4; 48 | border-bottom: solid 1px #DFD2B7; 49 | } 50 | 51 | header .logo { 52 | display: inline-block; 53 | vertical-align: top; 54 | margin: 0 5px; 55 | width: 18px; 56 | height: 18px; 57 | opacity: 0.6; 58 | background: url("../img/icon19.png"); 59 | } 60 | 61 | hr { 62 | border-top: none; 63 | border-bottom: dotted 1px #999; 64 | margin: 0 10px; 65 | } 66 | 67 | input, textarea { 68 | outline: 0; 69 | padding: 2px 3px; 70 | font-size: 12px; 71 | border-radius: 2px; 72 | border: 1px solid #999; 73 | } 74 | 75 | input[type=checkbox], 76 | input[type=radio] { 77 | width: 16px; 78 | height: 16px; 79 | vertical-align: sub; 80 | } 81 | 82 | [data-component="content"] { 83 | display: none; 84 | } 85 | 86 | .button { 87 | background: #E7E7E7; 88 | border: 1px solid #bbb; 89 | } 90 | 91 | .button:hover { 92 | 93 | background: #eee; 94 | } -------------------------------------------------------------------------------- /chrome/css/cwd.css: -------------------------------------------------------------------------------- 1 | .dialog { 2 | width: 100%; 3 | height: 100%; 4 | position: absolute; 5 | background: rgba(0, 0, 0, 0.5); 6 | top: 0; 7 | left: 0; 8 | } 9 | 10 | .dialog .content { 11 | position: absolute; 12 | width: 94%; 13 | height: 94%; 14 | padding: 10px; 15 | background: #F0F0F0; 16 | box-sizing: border-box; 17 | left: 2%; 18 | top: 2%; 19 | } 20 | 21 | .dialog .content .info { 22 | box-sizing: border-box; 23 | height: 60px; 24 | font-size: 14px; 25 | line-height: 16px; 26 | } 27 | 28 | .dialog .content .inner { 29 | overflow-x: hidden; 30 | overflow-y: scroll; 31 | height: calc(100% - 120px); 32 | box-sizing: border-box; 33 | line-height: 22px; 34 | } 35 | 36 | .dialog .content .inner a { 37 | display: block; 38 | text-decoration: none; 39 | padding: 0 0 0 4px; 40 | background: #D4D4D4; 41 | border-radius: 4px; 42 | font-size: 12px; 43 | margin: 0 0 2px 0; 44 | box-sizing: border-box; 45 | color: #000; 46 | } 47 | 48 | .dialog .content .inner a:hover { 49 | background: #C0C0C0; 50 | } 51 | 52 | .dialog .content .actions { 53 | margin: 20px 0 0 0; 54 | } 55 | 56 | .dialog .content .actions a { 57 | display: inline-block; 58 | text-decoration: none; 59 | padding: 4px 10px; 60 | background: #E7E7E7; 61 | border-bottom: solid 1px #919191; 62 | margin: 0 6px 0 0; 63 | color: #000; 64 | border-radius: 3px; 65 | } 66 | 67 | .dialog .content .actions a:hover { 68 | background: #D5D5D5; 69 | } 70 | 71 | .dialog .editor textarea { 72 | width: 100%; 73 | height: 100%; 74 | box-sizing: border-box; 75 | padding: 6px; 76 | border-radius: 4px; 77 | } 78 | 79 | -------------------------------------------------------------------------------- /chrome/js/components/Content.js: -------------------------------------------------------------------------------- 1 | var Content = absurd.component('Content', { 2 | html: '[data-component="content"]', 3 | current: null, 4 | constructor: function() { 5 | this.populate().getGitStatus(); 6 | }, 7 | append: function(component) { 8 | if(!component.el) { 9 | component.populate(); 10 | } 11 | this.el.innerHTML = ''; 12 | this.el.appendChild(component.el); 13 | if(component.appended) { 14 | component.appended(); 15 | } 16 | this.current = component; 17 | }, 18 | visible: function(v) { 19 | this.el.style.display = v ? 'block' : 'none'; 20 | }, 21 | passKeypressSignal: function(signal) { 22 | if(this.current && this.current[signal]) { 23 | this.current[signal](); 24 | } 25 | }, 26 | getGitStatus: function() { 27 | var self = this; 28 | if(this.current && this.current.data && this.current.data.cwd) { 29 | Yez.send({ 30 | action: 'git-status', 31 | cwd: this.current.data.cwd 32 | }, function(data) { 33 | var text = ''; 34 | if(typeof data.err == 'undefined' && data.data && data.data.length > 0) { 35 | var gitStatusResult = data.data.join('\n'); 36 | var lines = gitStatusResult.split("\n"); 37 | var branch = ''; 38 | var status = {}; 39 | for(var i=0; i= 2) { 46 | var type = parts.length == 2 ? parts[0] : parts[1]; 47 | if(!status[type]) status[type] = 0; 48 | status[type] += 1; 49 | } 50 | } 51 | } 52 | self.current.gitStatus && self.current.gitStatus({ 53 | branch: branch, 54 | status: status 55 | }); 56 | } 57 | }); 58 | } 59 | setTimeout(self.getGitStatus.bind(self), 1000); 60 | } 61 | }) -------------------------------------------------------------------------------- /chrome/js/components/CWD.js: -------------------------------------------------------------------------------- 1 | var CWD = absurd.component('CWD', { 2 | html: { 3 | '.dialog': { 4 | '.content': { 5 | '.info': ' <% cwd %>', 6 | '.inner': [ 7 | '<% for(var i=0; i', 8 | { 'a[href="#" data-absurd-event="click:change:<% i %>"]': ' <% links[i] %>'}, 9 | '<% } %>' 10 | ], 11 | '.actions': [ 12 | { 'a[href="#" class="button" data-absurd-event="click:result:ok"]': ' OK'}, 13 | { 'a[href="#" class="button" data-absurd-event="click:result:cancel"]': ' Cancel'} 14 | ] 15 | } 16 | } 17 | }, 18 | links: [], 19 | cwd: '', 20 | list: function(cwd) { 21 | this.cwd = cwd; 22 | Yez.send({ 23 | action: 'list', 24 | cwd: cwd 25 | }, function(data) { 26 | if(data.err) { 27 | if(typeof data.err == 'object') data.err = JSON.stringify(data.err); 28 | // alert(data.err); 29 | } else { 30 | this.links = ['..'].concat(data.files); 31 | this.populate(); 32 | } 33 | }.bind(this)); 34 | }, 35 | change: function(e, index) { 36 | e && e.preventDefault(); 37 | index = parseInt(index); 38 | if(index == 0) { 39 | var pathParts = normalizePath(this.cwd).split(Yez.sep); 40 | pathParts.pop(); 41 | var path = pathParts.join(Yez.sep); 42 | if(path.charAt(path.length-1) == ':') path = path + Yez.sep; 43 | this.list(path); 44 | } else { 45 | this.list(this.cwd + Yez.sep + this.links[index]); 46 | } 47 | }, 48 | result: function(e, res) { 49 | e.preventDefault(); 50 | this.callback ? this.callback(res === 'ok' ? this.cwd : false) : null; 51 | document.querySelector('body').removeChild(this.populate().el); 52 | }, 53 | constructor: function(cwd, cb, dom) { 54 | this.cwd = cwd; 55 | this.callback = cb; 56 | this.populate(); 57 | document.querySelector('body').appendChild(this.populate().el) 58 | this.list(cwd); 59 | } 60 | }); -------------------------------------------------------------------------------- /chrome/js/components/Nav.js: -------------------------------------------------------------------------------- 1 | var Nav = absurd.component('Nav', { 2 | html: { 3 | 'nav[data-component="nav"]': [ 4 | { 'a[href="#" data-absurd-event="click:addTask" class="button add add-task" title="New task"]': ' Task' }, 5 | { 'a[href="#" data-absurd-event="click:addTerminal" class="button add add-terminal" title="New terminal"]': ' Terminal' }, 6 | { 'a[href="#" data-absurd-event="click:toHome" class="button toHome task" title="Back to home"]': '' }, 7 | '<% for(var i=0; i', 11 | { 'a[href="#" data-absurd-event="click:openTask:<% id %>" class="button task <% id %>" title="<% name %>"]': '<% tasksRunning[i].name %>'}, 12 | '<% } %>' 13 | ] 14 | }, 15 | tabs: [], 16 | running: 0, 17 | tasksRunning: [], 18 | constructor: function(dom) { 19 | dom('[data-placeholder="nav"]').el.appendChild(this.populate().el); 20 | this.startCheckingTasks(); 21 | }, 22 | visible: function(s) { 23 | this.el.style.display = s ? 'block' : 'none'; 24 | }, 25 | startCheckingTasks: function() { 26 | var tasks = Yez.tasks, running = 0, self = this; 27 | this.tasksRunning = []; 28 | for(var id in tasks) { 29 | var t = tasks[id]; 30 | if(t.started) { 31 | running += 1; 32 | this.tasksRunning.push({id: id, name: t.data.name}); 33 | } 34 | } 35 | if(running != this.running) { 36 | this.running = running; 37 | this.populate(); 38 | } 39 | setTimeout(function() { 40 | self.startCheckingTasks(); 41 | }, 300); 42 | }, 43 | openTask: function(e, id) { 44 | this.removeClass('current', this.qs('.current')); 45 | this.addClass('current', e.target); 46 | e.preventDefault(); 47 | this.dispatch('open-task', {id: id}); 48 | }, 49 | toHome: function(e) { 50 | e.preventDefault(); 51 | this.removeClass('current', this.qs('.current')); 52 | this.dispatch('to-home'); 53 | }, 54 | addTerminal: function(e) { 55 | e.preventDefault(); 56 | this.dispatch('add-terminal'); 57 | }, 58 | addTask: function(e) { 59 | e.preventDefault(); 60 | this.dispatch('add-task'); 61 | } 62 | }); -------------------------------------------------------------------------------- /chrome/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Yez 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 |
19 |
20 | Status: disconnected (1 retry) 21 |
Connection to http://<% host %>:<% port %> failed.
It seems that yez Node.js module is missing.
Try running npm install -g yez.
When the installation finishes type yez and hit Enter.
22 |
23 |
24 |
25 |
26 |
27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Yez! 2 | 3 | > NodeJs app that kills the terminal and act as a task runner 4 | 5 | ## Installation 6 | 7 | * [Yez! Node.js module](https://github.com/krasimir/yez) `npm install -g yez` 8 | * [Yez! Chrome extension (optional)](https://chrome.google.com/webstore/detail/yez/acbhddemkmodoahhmnphpcfmcfgpjmap) 9 | 10 | ## Usage 11 | 12 | 1. Install the Yez! module by running `npm install -g yez` or
`npm install -g https://registry.npmjs.org/yez/-/yez-2.0.1.tgz`.
If you have problems installing the module please check out the [this thread](https://github.com/krasimir/yez/issues/1). 13 | 14 | 2. Run `yez` in your console 15 | 16 | 3. Open Chrome browser and install the [extension](https://chrome.google.com/webstore/detail/yez/acbhddemkmodoahhmnphpcfmcfgpjmap) 17 | 18 | 4. Open Chrome's DevTools and find the Yez! tab 19 | 20 | (Have in mind that when you run the backend of Yez! the app is available at http://localhost:9173/) 21 | 22 | ## Chrome extension shortcuts 23 | 24 | To open Yez! just press `Ctrl+Shift+I` which openes the DevTools console. Just after that press `Ctrl+]` till you reach the needed tab. 25 | 26 | * `Ctrl+l` - clearing the command output panel 27 | * `Ctrl+Enter` - restarting the task 28 | * `Ctrl+i` - bring the focus to the input field 29 | * `Ctrl+\` - opens a new terminal 30 | * `Ctrl+c` - stops the run tasks 31 | 32 | ## Running tests 33 | 34 | ```js 35 | npm test 36 | ``` 37 | 38 | ## Articles 39 | 40 | * [Sorry, Chrome killed the terminal](http://krasimirtsonev.com/blog/article/Sorry-Chrome-killed-the-terminal) 41 | * [Developing Node.js applications with Google Chrome](http://krasimirtsonev.com/blog/article/Developing-Nodejs-applications-with-Google-Chrome) 42 | 43 | ## Screenshots 44 | 45 | Using the extension as terminal 46 | 47 | ![Yez!](http://krasimirtsonev.com/blog/articles/ChromeKilledTheTerminal/imgs/yez_01.gif) 48 | 49 | Creating a simple task 50 | 51 | ![Yez!](http://krasimirtsonev.com/blog/articles/ChromeKilledTheTerminal/imgs/yez_02.gif) 52 | 53 | List of all added tasks 54 | 55 | ![Yez!](http://work.krasimirtsonev.com/git/yez/yez-screenshot-1.jpg) 56 | 57 | Creating a task which runs the Yez! tests 58 | 59 | ![Yez!](http://work.krasimirtsonev.com/git/yez/yez-screenshot-2.jpg) 60 | 61 | The result after runnning the task 62 | 63 | ![Yez!](http://work.krasimirtsonev.com/git/yez/yez-screenshot-5.jpg) 64 | 65 | Creating a task which opens Twitter and checks the latest news about #nodejs 66 | 67 | ![Yez!](http://work.krasimirtsonev.com/git/yez/yez-screenshot-3.jpg) 68 | 69 | The result after runnning the task 70 | 71 | ![Yez!](http://work.krasimirtsonev.com/git/yez/yez-screenshot-4.jpg) -------------------------------------------------------------------------------- /chrome/js/utils/Autocomplete.js: -------------------------------------------------------------------------------- 1 | var Autocomplete = { 2 | dictionary: {}, 3 | matchingWord: '', 4 | setup: function(f, h) { 5 | this.field = f; 6 | this.hint = h; 7 | this.check(); 8 | }, 9 | off: function() { 10 | this.field = this.hint = null; 11 | this.matchingWord = this.path = ''; 12 | }, 13 | check: function(cwd) { 14 | if(!this.field || !this.hint) return; 15 | var value = '', matches = []; 16 | this.hint.innerHTML = matchingWord = this.path = this.all = ''; 17 | if(this.field.value.match(/\//g)) { 18 | var vIntervals = this.field.value.split(/ /g); 19 | var lastVInterval = vIntervals.pop(); 20 | var vSlash = lastVInterval.split(/\//g); 21 | value = vSlash.pop(); 22 | this.path = vSlash.join(Yez.sep) + Yez.sep; 23 | this.all = vIntervals.join(' ') + (vIntervals.length > 0 ? ' ' : '') + vSlash.join(Yez.sep); 24 | } else { 25 | value = this.field.value; 26 | } 27 | if(value != '') { 28 | for(var word in this.dictionary) { 29 | var re = new RegExp("^" + value.toLowerCase().replace(/\./, '\\.') + "(.*)?"); 30 | if(word.toLowerCase().match(re)) { 31 | matches.push(word); 32 | } 33 | } 34 | if(matches.length > 0) { 35 | this.matchingWord = matches.shift(); 36 | var hintStr = ''; 37 | hintStr += (this.all != '' ? this.all + Yez.sep : '') + this.matchingWord; 38 | if(matches.length > 0) { 39 | hintStr += ', ' + matches.join(', '); 40 | } 41 | this.hint.innerHTML = hintStr; 42 | } 43 | if(cwd && typeof cwd == 'string') { 44 | this.checkFileSystemDictionary(cwd + Yez.sep + this.path); 45 | } 46 | } 47 | }, 48 | applyMatch: function() { 49 | if(this.matchingWord != '' && this.field) { 50 | this.field.value = (this.all != '' ? this.all + Yez.sep : '') + this.matchingWord; 51 | } 52 | }, 53 | checkFileSystemDictionary: function(cwd) { 54 | var self = this; 55 | Yez.send({ 56 | action: 'list', 57 | cwd: cwd, 58 | files: true 59 | }, function(data) { 60 | if(data.err) { 61 | if(typeof data.err == 'object') data.err = JSON.stringify(data.err); 62 | // alert(data.err); 63 | } else { 64 | self.dictionary = extend({}, self.getAliases()); 65 | for(var i=0; i 0) { 75 | preventEnding = true; 76 | } else { 77 | err.push(e); 78 | } 79 | }); 80 | processing.on('close', function (code) { 81 | // console.log('close code: ' + code); 82 | if(preventEnding) { 83 | c.command += pathExtWin.shift(); 84 | go(c); 85 | } else { 86 | api.ended = true; 87 | endcb && endcb(err.length > 0 ? err : false, out, code); 88 | } 89 | }); 90 | processing.on('disconnect', function (code) { 91 | // console.log('disconnect code: ' + code); 92 | api.ended = true; 93 | endcb && endcb(err.length > 0 ? err : false, out, code); 94 | }); 95 | processing.on('exit', function (code, signal) { 96 | // console.log('exit code: ' + code + ' signal: ' + signal); 97 | api.ended = true; 98 | exitcb && exitcb(code, signal); 99 | }); 100 | })(c); 101 | } catch(err) { 102 | // console.log('Error: ', err); 103 | api.ended = true; 104 | endcb && endcb(err, out, code); 105 | } 106 | 107 | return { 108 | data: function(cb) { outcb = cb; return this; }, 109 | err: function(cb) { errcb = cb; return this; }, 110 | end: function(cb) { endcb = cb; return this; }, 111 | exit: function(cb) { exitcb = cb; return this; } 112 | } 113 | 114 | } 115 | api.stop = function() { 116 | if(processing) { 117 | if(!isWin) { 118 | kill(processing.pid); 119 | } else { 120 | cp.exec('taskkill /PID ' + processing.pid + ' /T /F', function (error, stdout, stderr) { 121 | // console.log('stdout: ' + stdout); 122 | // console.log('stderr: ' + stderr); 123 | // if(error !== null) { 124 | // console.log('exec error: ' + error); 125 | // } 126 | }); 127 | } 128 | } 129 | } 130 | api.write = function(value) { 131 | if(processing) { 132 | processing.stdin.write(value + '\n'); 133 | } 134 | } 135 | return api; 136 | } -------------------------------------------------------------------------------- /chrome/js/components/Home.js: -------------------------------------------------------------------------------- 1 | var Home = absurd.component('Home', { 2 | trayChecked: false, 3 | theme: true, 4 | html: { 5 | 'div[data-component="home"]': [ 6 | { 'input[class="filter" placeholder="🔎" data-absurd-event="keyup:filter" autofocus]': ''}, 7 | { h1: '<% tasks.length > 0 ? "Your tasks:" : "" %>' }, 8 | '<% for(var i=0; i', 15 | { 16 | 'div[class="task<% started %><% group %><% grouped %>"]': { 17 | 'a[href="#" data-absurd-event="click:showTask:<% id %>" class="button" data-name="<% name %>"]': '"> <% tasks[i].name %>', 18 | 'a[href="#" data-absurd-event="click:runTask:<% id %>" class="button action"]': ' Run', 19 | 'a[href="#" data-absurd-event="click:stopTask:<% id %>" class="button action stop"]': ' Stop' 20 | } 21 | }, 22 | '<% } %>', 23 | { 'a[href="#" class="newtask" data-absurd-event="click:newTask"]': ' New task'}, 24 | { 'div[class="options"]':'Options: name="tray" data-absurd-event="click:trayClick"/ >Tray icon
Theme: value="light"/>Light value="dark"/>Dark'} 25 | ] 26 | }, 27 | tasks: [], 28 | setTasks: function(ts) { 29 | if(ts) { 30 | this.tasks = []; 31 | for(var i in ts) { 32 | if(!ts[i].data.terminal) { 33 | this.tasks.push({ id: ts[i].getId(), name: ts[i].data.name, started: ts[i].started, autorun: ts[i].data.autorun }); 34 | } 35 | } 36 | this.orderTasks(); 37 | } 38 | if(this.el) this.el.innerHTML = ''; 39 | this.populate(); 40 | return this; 41 | }, 42 | showTask: function(e, id) { 43 | if(id != -1) { 44 | var current = document.querySelector('.current'); 45 | if (current) current.classList.remove('current'); 46 | current = document.querySelector('.'+id); 47 | if (current) current.classList.add('current'); 48 | this.dispatch('show-task', id); 49 | } 50 | }, 51 | runTask: function(e, id) { 52 | e.preventDefault(); 53 | this.dispatch('run-task-silent', id); 54 | }, 55 | stopTask: function(e, id) { 56 | e.preventDefault(); 57 | this.dispatch('stop-task-silent', id); 58 | }, 59 | newTask: function(e) { 60 | e.preventDefault(); 61 | this.dispatch('new-task') 62 | }, 63 | filter: function(e, dom) { 64 | var value = e.target.value; 65 | var tasksElements = this.qsa('.task'); 66 | for(var i=0; i b.name.toLowerCase() ? 1 : -1; 80 | }); 81 | var word = '', arr = [], added = false; 82 | for(var i=0; i]/gm, function(str) { 46 | if (str == "&") return "&"; 47 | if (str == "<") return "<"; 48 | if (str == ">") return ">"; 49 | }); 50 | }; 51 | 52 | Ansi_Up.prototype.linkify = function (txt) { 53 | return txt.replace(/(https?:\/\/[^\s]+)/gm, function(str) { 54 | return "" + str + ""; 55 | }); 56 | }; 57 | 58 | Ansi_Up.prototype.ansi_to_html = function (txt, options) { 59 | 60 | var data4 = txt.split(/\033\[/); 61 | 62 | var first = data4.shift(); // the first chunk is not the result of the split 63 | 64 | var self = this; 65 | var data5 = data4.map(function (chunk) { 66 | return self.process_chunk(chunk, options); 67 | }); 68 | 69 | data5.unshift(first); 70 | 71 | var flattened_data = data5.reduce( function (a, b) { 72 | if (Array.isArray(b)) 73 | return a.concat(b); 74 | 75 | a.push(b); 76 | return a; 77 | }, []); 78 | 79 | var escaped_data = flattened_data.join(''); 80 | 81 | return escaped_data; 82 | }; 83 | 84 | Ansi_Up.prototype.process_chunk = function (text, options) { 85 | 86 | // Are we using classes or styles? 87 | options = typeof options == 'undefined' ? {} : options; 88 | var use_classes = typeof options.use_classes != 'undefined' && options.use_classes; 89 | var key = use_classes ? 'class' : 'color'; 90 | 91 | // Do proper handling of sequences (aka - injest vi split(';') into state machine 92 | //match,codes,txt = text.match(/([\d;]+)m(.*)/m); 93 | var matches = text.match(/([\d;]*)m([^]*)/m); 94 | 95 | if (!matches) return text; 96 | 97 | var orig_txt = matches[2]; 98 | var nums = matches[1].split(';'); 99 | 100 | var self = this; 101 | nums.map(function (num_str) { 102 | 103 | var num = parseInt(num_str); 104 | 105 | if (isNaN(num) || num === 0) { 106 | self.fg = self.bg = null; 107 | self.bright = 0; 108 | } else if (num === 1) { 109 | self.bright = 1; 110 | } else if ((num >= 30) && (num < 38)) { 111 | self.fg = ANSI_COLORS[self.bright][(num % 10)][key]; 112 | } else if ((num >= 40) && (num < 48)) { 113 | self.bg = ANSI_COLORS[0][(num % 10)][key]; 114 | } 115 | }); 116 | 117 | if ((self.fg === null) && (self.bg === null)) { 118 | return orig_txt; 119 | } else { 120 | var styles = classes = []; 121 | if (self.fg) { 122 | if (use_classes) { 123 | classes.push(self.fg + "-fg"); 124 | } else { 125 | styles.push("color:rgb(" + self.fg + ")"); 126 | } 127 | } 128 | if (self.bg) { 129 | if (use_classes) { 130 | classes.push(self.bg + "-bg"); 131 | } else { 132 | styles.push("background-color:rgb(" + self.bg + ")"); 133 | } 134 | } 135 | if (use_classes) { 136 | return ["", orig_txt, ""]; 137 | } else { 138 | return ["", orig_txt, ""]; 139 | } 140 | } 141 | }; 142 | 143 | // Module exports 144 | ansi_up = { 145 | 146 | escape_for_html: function (txt) { 147 | var a2h = new Ansi_Up(); 148 | return a2h.escape_for_html(txt); 149 | }, 150 | 151 | linkify: function (txt) { 152 | var a2h = new Ansi_Up(); 153 | return a2h.linkify(txt); 154 | }, 155 | 156 | ansi_to_html: function (txt, options) { 157 | var a2h = new Ansi_Up(); 158 | return a2h.ansi_to_html(txt, options); 159 | }, 160 | 161 | ansi_to_html_obj: function () { 162 | return new Ansi_Up(); 163 | } 164 | }; 165 | 166 | // CommonJS module is defined 167 | if (hasModule) { 168 | module.exports = ansi_up; 169 | } 170 | /*global ender:false */ 171 | if (typeof window !== 'undefined' && typeof ender === 'undefined') { 172 | window.ansi_up = ansi_up; 173 | } 174 | /*global define:false */ 175 | if (typeof define === "function" && define.amd) { 176 | define("ansi_up", [], function () { 177 | return ansi_up; 178 | }); 179 | } 180 | })(Date); -------------------------------------------------------------------------------- /node/tests/tests.js: -------------------------------------------------------------------------------- 1 | var expect = require('expect.js'); 2 | var TaskRunner = require('../TaskRunner'); 3 | var parser = require('../helpers/CommandParser'); 4 | var fs = require('fs'); 5 | 6 | describe("/ Command line parsing /", function() { 7 | it("should parse command without parameter", function(done) { 8 | var res = parser('node'); 9 | expect(res.command).to.be.equal('node'); 10 | expect(res.args.length).to.be.equal(0); 11 | done(); 12 | }); 13 | it("should parse command with one parameter", function(done) { 14 | var res = parser('node -v'); 15 | expect(res.command).to.be.equal('node'); 16 | expect(res.args.length).to.be.equal(1); 17 | expect(res.args[0]).to.be.equal('-v'); 18 | done(); 19 | }); 20 | it("should parse command with many parameter", function(done) { 21 | var res = parser('node -v -a -f'); 22 | expect(res.command).to.be.equal('node'); 23 | expect(res.args.length).to.be.equal(3); 24 | expect(res.args[0]).to.be.equal('-v'); 25 | expect(res.args[1]).to.be.equal('-a'); 26 | expect(res.args[2]).to.be.equal('-f'); 27 | done(); 28 | }); 29 | it("should clean up empty parameters", function(done) { 30 | var res = parser('node -v -a -f'); 31 | expect(res.command).to.be.equal('node'); 32 | expect(res.args.length).to.be.equal(3); 33 | expect(res.args[0]).to.be.equal('-v'); 34 | expect(res.args[1]).to.be.equal('-a'); 35 | expect(res.args[2]).to.be.equal('-f'); 36 | done(); 37 | }); 38 | it("should parse complex command", function(done) { 39 | var res = parser('git commit -am "Message here - with dash"'); 40 | expect(res.command).to.be.equal('git'); 41 | expect(res.args.length).to.be.equal(3); 42 | expect(res.args[0]).to.be.equal('commit'); 43 | expect(res.args[1]).to.be.equal('-am'); 44 | expect(res.args[2]).to.be.equal('Message here - with dash'); 45 | done(); 46 | }); 47 | }); 48 | 49 | describe("/ Running commands /", function(done) { 50 | it("should run a task", function(done) { 51 | var runner = TaskRunner(), data = []; 52 | runner.run('node -v') 53 | .data(function(d) { data.push(d); }) 54 | .end(function(err, d, code) { 55 | expect(code).to.equal(0); 56 | expect(err).to.equal(false); 57 | done(); 58 | }); 59 | }); 60 | it("should run unknown command", function(done) { 61 | var runner = TaskRunner(); 62 | runner.run('unknown command') 63 | .end(function(err, d, code) { 64 | expect(err).not.to.be(false); 65 | done(); 66 | }); 67 | }); 68 | it("should run a continues task", function(done) { 69 | var runner = TaskRunner(), data = []; 70 | runner.run('node ./node/tests/commands/continues.js') 71 | .data(function(d) { data.push(d); }) 72 | .end(function(err, d, code) { 73 | expect(code).to.equal(0); 74 | expect(err).to.equal(false); 75 | expect(data[0]).to.equal('hello 9\n'); 76 | expect(data.length).to.equal(10); 77 | done(); 78 | }); 79 | }); 80 | it("should run a continues task by passing a path", function(done) { 81 | var runner = TaskRunner(), data = []; 82 | runner.run('node continues.js', __dirname + '/commands') 83 | .data(function(d) { data.push(d); }) 84 | .end(function(err, d, code) { 85 | expect(code).to.equal(0); 86 | expect(err).to.equal(false); 87 | expect(data[0]).to.equal('hello 9\n'); 88 | expect(data.length).to.equal(10); 89 | done(); 90 | }); 91 | }); 92 | it("should run a continues task which fail", function(done) { 93 | var runner = TaskRunner(), data = []; 94 | runner.run('node ./node/tests/commands/continues-fail.js') 95 | .data(function(d) { data.push(d); }) 96 | .end(function(err, d, code) { 97 | expect(data[0]).to.equal('hello 9\n'); 98 | expect(data.length).to.equal(6); 99 | expect(err.join(',').indexOf('Ops!') > 0).to.equal(true); 100 | done(); 101 | }); 102 | }); 103 | it("should run a commands with parameters", function(done) { 104 | var runner = TaskRunner(), data = []; 105 | runner.run('node continues-with-params.js -v --reporter spec', __dirname + '/commands') 106 | .data(function(d) { data.push(d); }) 107 | .end(function(err, d, code) { 108 | expect(code).to.equal(0); 109 | expect(err).to.equal(false); 110 | expect(data[0]).to.equal('-v,--reporter,spec\n'); 111 | done(); 112 | }); 113 | }); 114 | it("should run a commands and stop it", function(done) { 115 | var runner = TaskRunner(), data = []; 116 | runner.run('node server.js', __dirname + '/commands') 117 | .data(function(d) { data.push(d); }) 118 | .end(function(err, d, code) { 119 | expect(err).to.equal(false); 120 | expect(data[0]).to.equal('Server running at http://127.0.0.1:1339/\n'); 121 | done(); 122 | }); 123 | setTimeout(function() { 124 | runner.stop(function(err, res) { 125 | expect(err).to.equal(null); 126 | expect(res).to.equal('Process stopped.'); 127 | }); 128 | }, 100); 129 | }); 130 | it("should run a commands with stdin", function(done) { 131 | var runner = TaskRunner(), data = []; 132 | runner.run('node stdin-program.js', __dirname + '/commands') 133 | .data(function(d) { 134 | data.push(d); 135 | if(d == 'Please type your name:') { 136 | runner.write('Yezzzy'); 137 | } 138 | }) 139 | .end(function(err, d, code) { 140 | expect(err).to.equal(false); 141 | expect(data[0]).to.equal('Please type your name:'); 142 | expect(data[1]).to.equal('Hello Yezzzy. It\'s nice to mee you.\n'); 143 | done(); 144 | }); 145 | }); 146 | it("should start and stop grunt", function(done) { 147 | this.timeout(5000); 148 | var runner = TaskRunner(), data = []; 149 | runner.run('grunt', __dirname + '/commands/grunt-test') 150 | .data(function(d) { 151 | // console.log(data.length); 152 | data.push(d); 153 | }) 154 | .end(function(err, d, code) { 155 | // console.log('\n\nend', err, code); 156 | }) 157 | .exit(function(code, signal) { 158 | // console.log('\n\nexit', code, signal); 159 | }); 160 | setTimeout(function() { 161 | runner.stop(); 162 | var totalResponses = data.length; 163 | var file = __dirname + '/commands/grunt-test/src/A.js'; 164 | var fileContent = fs.readFileSync(file); 165 | fs.writeFileSync(file, fileContent + 'c'); 166 | setTimeout(function() { 167 | expect(data.length).to.equal(totalResponses); 168 | done(); 169 | }, 1000); 170 | }, 1000); 171 | }); 172 | }) -------------------------------------------------------------------------------- /chrome/css/dark.css: -------------------------------------------------------------------------------- 1 | /*YEZ DARK THEME*/ 2 | 3 | .dark { 4 | color: #d5d5d5; 5 | background: #242424; 6 | } 7 | 8 | .dark input { 9 | color: #cecece; 10 | background: #242424; 11 | border: 1px solid #5c5c5c; 12 | } 13 | 14 | .dark header { 15 | background: #2a2a2a; 16 | border-bottom: solid 1px #444; 17 | } 18 | 19 | .dark header .logo { 20 | background: url("../img/icon19w.png"); 21 | } 22 | 23 | .dark [data-component] .button { 24 | color: #a5a5a5; 25 | background: #323232; 26 | border: 1px solid #444; 27 | } 28 | 29 | .dark [data-component] .button:hover, 30 | .dark [data-component] .button.current:hover { 31 | color: #fff; 32 | background: #3d3d3d; 33 | } 34 | 35 | .dark [data-component] .button.current { 36 | background: #222; 37 | } 38 | /* NAV */ 39 | 40 | .dark [data-component="nav"] .button { 41 | background: #2a2a2a; 42 | border: 0; 43 | } 44 | 45 | .dark [data-component="nav"] .toHome { 46 | color: #ddd; 47 | } 48 | 49 | .dark [data-component="nav"] .task.current { 50 | border: 1px solid #444; 51 | border-bottom: 0; 52 | } 53 | 54 | /* STATUS */ 55 | 56 | .dark [data-component="status"] .status { 57 | color: #999; 58 | } 59 | 60 | .dark [data-component="status"] .info { 61 | color: #ccc; 62 | background: #2c2c2c; 63 | } 64 | 65 | .dark [data-component="status"] code { 66 | color: #fff; 67 | font-family: monospace; 68 | background: #444; 69 | border: 1px solid #666; 70 | } 71 | /* HOME */ 72 | 73 | .dark [data-component="home"] .task a.button { 74 | color: #d5d5d5; 75 | } 76 | .dark [data-component="home"] .task a.button:hover { 77 | background: #3d3d3d; 78 | color: #fff; 79 | } 80 | 81 | .dark [data-component="home"] .task a.action { 82 | background: #3e9828; 83 | color: #fff; 84 | } 85 | .dark [data-component="home"] .task a.action:hover { 86 | background: #84DC6D; 87 | } 88 | 89 | .dark [data-component="home"] .task a.action.stop { 90 | background: #E83E3E; 91 | } 92 | .dark [data-component="home"] .task a.action.stop:hover { 93 | background: #ED6565; 94 | } 95 | 96 | .dark [data-component="home"] .task.group a.button { 97 | background: #242424; 98 | } 99 | .dark [data-component="home"] .task.group a.button:hover { 100 | background: #242424; 101 | color: #fff; 102 | } 103 | 104 | .dark [data-component="home"] .newtask { 105 | color: #cacaca; 106 | } 107 | 108 | .dark [data-component="home"] .newtask:hover { 109 | color: #eee; 110 | } 111 | 112 | .dark [data-component="home"] .grouped:before { 113 | border-bottom: solid 1px #ccc; 114 | border-left: solid 1px #ccc; 115 | } 116 | 117 | /* TASKS */ 118 | 119 | .dark .task-id .task-cwd { 120 | color: #eee; 121 | } 122 | 123 | .dark .task-id .git-status { 124 | color: #ccc; 125 | } 126 | 127 | .dark .task-id .edit { 128 | color: #fff; 129 | } 130 | 131 | .dark .task-id .edit { 132 | color: #fff; 133 | } 134 | 135 | .dark .task-id .edit .element a { 136 | background: #323232; 137 | color: #ccc; 138 | border: 1px solid #5a5a5a; 139 | } 140 | .dark .task-id .edit .element a:hover { 141 | background: #3d3d3d; 142 | color: #fff; 143 | } 144 | 145 | .dark .task-id .edit .element label { 146 | background: #444; 147 | border: 2px solid #444; 148 | border-right: solid 1px #666; 149 | } 150 | 151 | .dark .task-id .edit .element .field { 152 | background: #444; 153 | border: 2px solid #444; 154 | } 155 | 156 | 157 | .dark .task-id .edit .actions { 158 | border-bottom: 0; 159 | color: #ddd; 160 | } 161 | 162 | .dark .task-id .dashboard .log { 163 | background: #181818; 164 | color: #ccc; 165 | margin-bottom: -1px; 166 | border: 1px solid #444; 167 | } 168 | 169 | .dark .task-id .dashboard .log p { 170 | margin-bottom: -1px; 171 | line-height: 20px; 172 | border-radius: 0; 173 | } 174 | 175 | .dark .task-id .dashboard .log .log-command { 176 | background: #332b00; 177 | border-bottom: solid 1px #A29042; 178 | border-top: solid 1px #A29042; 179 | color: #ffdc9e; 180 | } 181 | 182 | .dark .task-id .dashboard .log .log-error { 183 | background: #290000; 184 | border-bottom: solid 1px #5b0000; 185 | border-top: solid 1px #5b0000; 186 | color: #ff8080; 187 | } 188 | 189 | .dark .task-id .dashboard .log .log-warning { 190 | background: #332b00; 191 | border-bottom: solid 1px #A29042; 192 | border-top: solid 1px #A29042; 193 | color: #ffdc9e; 194 | } 195 | 196 | .dark .task-id .dashboard .log .log-error-end { 197 | background: #290000; 198 | border-bottom: solid 1px #5b0000; 199 | border-top: solid 1px #5b0000; 200 | color: #ff8080; 201 | } 202 | 203 | .dark .task-id .dashboard .log .log-end { 204 | background: #222; 205 | color: #bbb; 206 | } 207 | 208 | .dark .task-id .dashboard .log .log-response { 209 | background: #222; 210 | border-bottom: solid 1px #222; 211 | border-top: solid 1px #222; 212 | color: #ddd; 213 | } 214 | 215 | .dark .task-id .dashboard .log .log-task-end { 216 | background: #193900; 217 | border-bottom: solid 1px #5b8b00; 218 | border-top: solid 1px #5b8b00; 219 | color: #cfff80; 220 | } 221 | 222 | .dark .task-id .dashboard .log .log-info { 223 | background: #C6E7E8; 224 | border-bottom: solid 1px #66BFC1; 225 | color: #2E7072; 226 | } 227 | 228 | .dark .task-id .dashboard .log .log-stdin { 229 | background: #333; 230 | border-bottom: solid 1px #777; 231 | border-top: solid 1px #777; 232 | color: #fff; 233 | } 234 | 235 | .dark .task-id .dashboard .stdin-field { 236 | background: #383838; 237 | border: solid 1px #555; 238 | color: #eee; 239 | } 240 | 241 | .dark .task-id .dashboard .clear-log { 242 | background: #323232; 243 | padding: 4px 10px; 244 | color: #a5a5a5; 245 | border-radius: 3px; 246 | border: 1px solid #444; 247 | } 248 | 249 | .dark .task-id .dashboard .clear-log:hover { 250 | background: #3d3d3d; 251 | color: #fff; 252 | } 253 | 254 | .dark .dialog .content { 255 | background: #333; 256 | color: #eee; 257 | } 258 | 259 | .dark .dialog .content .inner a, 260 | .dark .dialog .content .button { 261 | background: #444; 262 | color: #fff; 263 | border: 0; 264 | } 265 | .dark .dialog .content .inner a:hover, 266 | .dark .dialog .content .button:hover { 267 | background: #555; 268 | } 269 | 270 | .dark .dialog .editor textarea { 271 | background: #222; 272 | color: #ddd; 273 | border: solid 1px #555; 274 | } 275 | 276 | /* SCROLL */ 277 | 278 | .dark ::-webkit-scrollbar { 279 | background: #1c1c1c; 280 | border: 1px solid #2a2a2a; 281 | width: 14px; 282 | border-right: 0; 283 | } 284 | 285 | .dark ::-webkit-scrollbar-button { 286 | height: 0; 287 | } 288 | 289 | .dark ::-webkit-scrollbar-thumb { 290 | background: #262626; 291 | border: 1px solid #3d3d3d; 292 | border-right: 0; 293 | } -------------------------------------------------------------------------------- /chrome/css/task.css: -------------------------------------------------------------------------------- 1 | .task-id .task-cwd { 2 | position: absolute; 3 | font-size: 14px; 4 | bottom: 42px; 5 | left: 12px; 6 | color: #575757; 7 | cursor: pointer; 8 | max-width: 70%; 9 | white-space: nowrap; 10 | overflow: hidden; 11 | } 12 | 13 | .task-id .git-status { 14 | position: absolute; 15 | font-size: 14px; 16 | bottom: 42px; 17 | right: 12px; 18 | color: #444; 19 | max-width: calc(30% - 30px); 20 | white-space: nowrap; 21 | overflow: hidden; 22 | } 23 | 24 | .task-id .git-changed { 25 | color: #ED6565; 26 | } 27 | .task-id .git-unchanged { 28 | color: #26A430; 29 | } 30 | .task-id .fa-git { 31 | vertical-align: text-bottom; 32 | } 33 | 34 | .task-id .edit { 35 | box-sizing: border-box; 36 | padding: 10px; 37 | display: none; 38 | } 39 | .task-id.edit .edit { 40 | display: block; 41 | clear: both; 42 | } 43 | .task-id .edit .element { 44 | box-sizing: border-box; 45 | margin: 5px 0px; 46 | position: relative; 47 | height: 26px; 48 | } 49 | 50 | .task-id .edit .element.autorun { 51 | float: right; 52 | } 53 | .task-id .edit .element label { 54 | width: 30%; 55 | padding: 5px 10px; 56 | box-sizing: border-box; 57 | background: #EDE9E0; 58 | float: left; 59 | border-top-left-radius: 3px; 60 | border-bottom-left-radius: 3px; 61 | text-align: right; 62 | border-right: solid 1px #DECAB6; 63 | border: solid 1px #ccc; 64 | overflow: hidden; 65 | border-right: 0; 66 | white-space: nowrap; 67 | } 68 | 69 | .task-id .edit .element .field { 70 | width: 70%; 71 | float: left; 72 | box-sizing: border-box; 73 | background: #F8F5EF; 74 | border-top-right-radius: 3px; 75 | border-bottom-right-radius: 3px; 76 | border: 1px solid #ccc; 77 | } 78 | 79 | .task-id .edit .element .field input { 80 | border: none; 81 | background: none; 82 | box-sizing: border-box; 83 | width: 100%; 84 | padding: 5px 10px; 85 | } 86 | 87 | .task-id .edit .element a { 88 | padding: 4px 10px; 89 | border-radius: 3px; 90 | width: 32px; 91 | text-align: center; 92 | box-sizing: border-box; 93 | color: #222; 94 | } 95 | 96 | .task-id .edit .element .sub-left { 97 | top: 2px; 98 | left: 2px; 99 | position: absolute; 100 | } 101 | 102 | .task-id .edit .element .sub-left:hover { 103 | background: #D5CCBB; 104 | } 105 | 106 | .task-id .edit .element .sub-independent { 107 | top: 2px; 108 | left: 36px; 109 | position: absolute; 110 | } 111 | 112 | .task-id .edit .element .sub-independent:hover { 113 | background: #D5CCBB; 114 | } 115 | 116 | .task-id .edit .element .sub-right { 117 | position: absolute; 118 | top: 2px; 119 | right: 2px; 120 | } 121 | 122 | .task-id .edit .element .sub-right:hover { 123 | background: #E6DBC4; 124 | } 125 | 126 | .task-id .edit .actions { 127 | margin: 0 0 0 30%; 128 | padding: 6px 0 0 0; 129 | clear: both; 130 | } 131 | 132 | .task-id .edit .actions a { 133 | display: inline-block; 134 | text-decoration: none; 135 | padding: 4px 10px; 136 | border-radius: 3px; 137 | margin: 0 6px 0 0; 138 | } 139 | 140 | .task-id .edit .actions .cancel { 141 | opacity: 0.4; 142 | } 143 | 144 | .task-id .edit .actions .cancel:hover { 145 | opacity: 1; 146 | } 147 | 148 | .task-id .dashboard { 149 | box-sizing: border-box; 150 | padding: 10px; 151 | display: block; 152 | } 153 | .task-id.edit .dashboard { 154 | display: none; 155 | } 156 | 157 | .task-id .dashboard h1 { 158 | margin: 20px 0 20px 0; 159 | padding: 0; 160 | font-size: 30px; 161 | } 162 | 163 | .task-id .dashboard .log { 164 | box-sizing: border-box; 165 | position: absolute; 166 | padding: 10px; 167 | background: #eee; 168 | width: calc(100% - 18px); 169 | height: calc(100% - 181px); 170 | font-size: 12px; 171 | line-height: 16px; 172 | border-radius: 3px; 173 | overflow-x: hidden; 174 | overflow-y: scroll; 175 | top: 107px; 176 | left: 10px; 177 | border: 1px solid #bbb; 178 | } 179 | 180 | .task-id .dashboard .log p { 181 | padding: 0 4px; 182 | margin: 0 0 1px 0; 183 | border-radius: 3px; 184 | } 185 | 186 | .task-id .dashboard .log .log-command { 187 | background: #C0DFE7; 188 | border-bottom: solid 1px #E1E1E1; 189 | } 190 | 191 | .task-id .dashboard .log .log-error { 192 | background: #F39C9C; 193 | border-bottom: solid 1px #E1E1E1; 194 | } 195 | 196 | .task-id .dashboard .log .log-warning { 197 | background: #F3E29C; 198 | border-bottom: solid 1px #E1E1E1; 199 | } 200 | 201 | .task-id .dashboard .log .log-error-end { 202 | background: #F8C2C2; 203 | border-bottom: solid 1px #E1E1E1; 204 | } 205 | 206 | .task-id .dashboard .log .log-end { 207 | text-align: right; 208 | padding: 0; 209 | line-height: 16px; 210 | } 211 | 212 | .task-id .dashboard .log .log-response { 213 | line-height: 16px; 214 | } 215 | 216 | .task-id .dashboard .log .log-task-end { 217 | background: #87E789; 218 | border-bottom: solid 1px #E1E1E1; 219 | } 220 | 221 | .task-id .dashboard .log .log-info { 222 | background: #C6E7E8; 223 | border-bottom: solid 1px #66BFC1; 224 | border-radius: 3px; 225 | color: #2E7072; 226 | } 227 | 228 | .task-id .dashboard .log .log-stdin { 229 | background: #C6E7E8; 230 | border-bottom: solid 1px #66BFC1; 231 | border-radius: 3px; 232 | color: #2E7072; 233 | } 234 | 235 | .task-id .dashboard .stdin-field { 236 | box-sizing: border-box; 237 | position: absolute; 238 | padding: 4px 4px 4px 18px; 239 | border-radius: 3px; 240 | width: calc(100% - 17px); 241 | background: none; 242 | bottom: 8px; 243 | right: 8px; 244 | } 245 | 246 | .task-id .dashboard .autocomplete { 247 | box-sizing: border-box; 248 | position: absolute; 249 | padding: 4px 4px 4px 18px; 250 | border-radius: 3px; 251 | width: calc(100% - 17px); 252 | font-size: 13px; 253 | overflow: hidden; 254 | height: 38px; 255 | bottom: 1px; 256 | right: 7px; 257 | color: #B8B8B8; 258 | } 259 | 260 | .task-id .dashboard .stdin-field-tooltip { 261 | position: absolute; 262 | bottom: 14px; 263 | left: 18px; 264 | color: #999; 265 | } 266 | 267 | .task-id .dashboard .clear-log { 268 | float: right; 269 | color: #666; 270 | } 271 | 272 | .task-id .dashboard .clear-log:hover { 273 | color: #000; 274 | } 275 | 276 | .task-id .dashboard .aliases { 277 | font-size: 18px; 278 | position: absolute; 279 | text-decoration: none; 280 | color: #ACACAC; 281 | bottom: 11px; 282 | right: 15px; 283 | } 284 | 285 | .task-id .dashboard .aliases:hover { 286 | color: #E83E3E; 287 | } 288 | 289 | .task-id .sub-nav { 290 | padding: 10px 0 0 10px; 291 | float: left; 292 | } 293 | 294 | .task-id .sub-nav .operation { 295 | display: inline-block; 296 | text-decoration: none; 297 | padding: 4px 10px; 298 | border-radius: 3px; 299 | margin: 0 6px 0 0; 300 | } 301 | 302 | .task-id .sub-nav .hidden { 303 | display: none; 304 | } 305 | -------------------------------------------------------------------------------- /chrome/js/Yez.js: -------------------------------------------------------------------------------- 1 | var Yez = absurd.component('Yez', { 2 | host: 'localhost', 3 | port: 9172, 4 | connected: false, 5 | tasks: {}, 6 | beacons: {}, 7 | defaultCWD: '', 8 | retry: 1, 9 | sep: '/', 10 | ready: function() { 11 | var self = this, showTask; 12 | 13 | this.populate(); 14 | 15 | // initializing the main components 16 | this.status = Status(this.host, this.port); 17 | this.nav = Nav(); 18 | this.content = Content(); 19 | this.home = Home(); 20 | 21 | // setting listeners of the navigation 22 | this.nav 23 | .on('open-task', function(data) { 24 | showTask(data.id); 25 | }) 26 | .on('add-task', function() { 27 | newTask(); 28 | }) 29 | .on('add-terminal', this.addTerminal = function(data) { 30 | var newTask = self.initializeTask({ 31 | terminal: true, 32 | name: 'Terminal', 33 | cwd: self.defaultCWD, 34 | commands: [''], 35 | id: getId() 36 | }); 37 | self.content.append(newTask); 38 | newTask.setMode('dashboard'); 39 | newTask.started = true; 40 | self.tasks[newTask.getId()] = newTask; 41 | }) 42 | .on('to-home', this.showHome.bind(this)); 43 | 44 | // setting listeners of the home page 45 | this.home 46 | .on('show-task', showTask = function(id) { 47 | if(self.tasks[id]) { 48 | var t = self.tasks[id]; 49 | t.setMode('dashboard'); 50 | self.content.append(t); 51 | } 52 | }) 53 | .on('run-task', function(id) { 54 | if(self.tasks[id]) { 55 | var t = self.tasks[id]; 56 | self.content.append(t); 57 | t.startTasks(); 58 | } 59 | }) 60 | .on('run-task-silent', function(id) { 61 | if(self.tasks[id]) { 62 | self.tasks[id].startTasks(); 63 | self.dispatch('tasks-updated'); 64 | } 65 | }) 66 | .on('stop-task', function(id) { 67 | if(self.tasks[id]) { 68 | var t = self.tasks[id]; 69 | self.content.append(t); 70 | t.stopTasks(); 71 | } 72 | }) 73 | .on('stop-task-silent', function(id) { 74 | if(self.tasks[id]) { 75 | self.tasks[id].stopTasks(); 76 | self.dispatch('tasks-updated'); 77 | } 78 | }) 79 | .on('new-task', newTask = function() { 80 | var newTask = self.initializeTask(); 81 | self.content.append(newTask); 82 | newTask.goToEditMode(); 83 | }); 84 | this.connect(); 85 | }, 86 | 87 | connect: function() { 88 | 89 | if(this.connected) { return; } 90 | 91 | var self = this; 92 | 93 | try { 94 | self.ipc = require('electron').ipcRenderer; 95 | self.ipc.on('theme', function(event, data) { 96 | self.socket.emit('data', {action: 'theme', theme: data, id: 'ipc'}); 97 | }); 98 | self.ipc.on('tray', function(event, data) { 99 | self.socket.emit('data', {action: 'tray', show: data, id: 'ipc'}); 100 | console.log('ipc tray', {action: 'tray', show: data, id: 'ipc'}); 101 | }); 102 | } catch (error) { 103 | // console.log('this is not an electron window'); 104 | } 105 | this.socket = io.connect('http://' + this.host + ':' + this.port, { 106 | 'force new connection': true 107 | }); 108 | this.socket.on('connect', function (data) { 109 | self.retry = 1; 110 | self.connected = true; 111 | self.status.setStatus(true); 112 | self.nav.visible(true); 113 | self.content.visible(true); 114 | }); 115 | this.socket.on('disconnect', function() { 116 | self.connected = false; 117 | self.status.setStatus(false, self.retry); 118 | self.nav.visible(false); 119 | self.content.visible(false); 120 | self.connect(); 121 | }); 122 | this.socket.on('initial', function(data) { 123 | self.sep = data.sep; 124 | self.savedAliases = data.aliases || ''; 125 | self.defaultCWD = normalizePath(data.cwd); 126 | self.setTasks(data); 127 | if (data.tray) { 128 | self.toggleTray({show: 'true'}); 129 | } 130 | if (data.dark) { 131 | self.setTheme({theme: 'dark'}); 132 | } 133 | }); 134 | this.socket.on('response', function(data) { 135 | if(self.tasks[data.id]) { 136 | self.tasks[data.id].response(data); 137 | } 138 | }); 139 | this.socket.on('beacon-response', function(data) { 140 | if(self.beacons[data.id]) { 141 | self.beacons[data.id](data); 142 | } 143 | }); 144 | this.socket.on('tray', function(data) { 145 | if (Yez.ipc) Yez.ipc.send('data', data); 146 | self.toggleTray(data); 147 | }); 148 | this.socket.on('theme', function(data) { 149 | if (Yez.ipc) Yez.ipc.send('data', data); 150 | self.setTheme(data); 151 | }); 152 | this.socket.on('updateTasks', function(data) { 153 | self.setTasks(data); 154 | }); 155 | this.socket.on('updateAliases', function(data) { 156 | this.savedAliases = data.aliases; 157 | }); 158 | setTimeout(function() { 159 | if(!self.connected) { 160 | self.retry += 1; 161 | self.status.setStatus(false, self.retry); 162 | self.connect(); 163 | } 164 | }, 5000); 165 | // showing home page and enabling the key binding 166 | this.showHome().initializeKeyPress(); 167 | return this; 168 | }, 169 | toggleTray: function (data) { 170 | var checked = Boolean(data.checked) || Boolean(data.show); 171 | this.qs('input[name=tray]').checked = checked; 172 | this.home.trayChecked = checked; 173 | }, 174 | setTheme: function (data) { 175 | this.qs('input[name=theme][value=dark]').checked = (data.theme == 'dark'); 176 | this.qs('input[name=theme][value=light]').checked = (data.theme == 'light'); 177 | this.home.theme = (data.theme == 'light'); 178 | document.body.className = data.theme; 179 | }, 180 | initializeTask: function(data) { 181 | var self = this; 182 | var t = Task(data || { 183 | name: 'Task', 184 | cwd: this.defaultCWD, 185 | commands: [''], 186 | id: getId() 187 | }); 188 | t.on('data', function(data) { 189 | delete data.target; 190 | if(self.socket && self.connected) { 191 | self.socket.emit('data', data); 192 | } else { 193 | t.response({ action: 'error', msg: 'No back-end!' }); 194 | } 195 | }) 196 | .on('save', function() { 197 | self.tasks[t.getId()] = t; 198 | self.dispatch('tasks-updated'); 199 | }) 200 | .on('home', this.showHome.bind(this)) 201 | .on('delete-task', function() { 202 | delete self.tasks[t.data.id]; 203 | self.dispatch('tasks-updated').showHome(); 204 | }) 205 | .on('ended', function() { 206 | self.dispatch('tasks-updated') 207 | }); 208 | return t; 209 | }, 210 | showHome: function() { 211 | this.content.append(this.home.setTasks(this.tasks)); 212 | return this; 213 | }, 214 | setTasks: function(data) { 215 | this.tasks = []; 216 | var ts = JSON.parse(data.tasks); 217 | for(var i=0; i 0) { 223 | for(var i=0; ii.call(a,"cmd")?!1:!0};g.prototype._prevent_default=function(a,c){if((c||this.should_suppress_event_defaults)&&!this.should_force_event_defaults)if(a.preventDefault?a.preventDefault():a.returnValue=!1,a.stopPropagation)return a.stopPropagation()};g.prototype._get_active_combos= 10 | function(a){var c,b;c=[];b=w(this._keys_down,function(b){return b!==a});b.push(a);this._match_combo_arrays(b,function(a){return function(b){if(a._cmd_bug_check(b.keys))return c.push(b)}}(this));this._fuzzy_match_combo_arrays(b,function(a){return function(b){if(!(0<=i.call(c,b))&&!b.is_solitary&&a._cmd_bug_check(b.keys))return c.push(b)}}(this));return c};g.prototype._get_potential_combos=function(a){var c,b,d,e,f;b=[];f=this._registered_combos;d=0;for(e=f.length;dl;e=0<=l?++j:--j)if((c=this._active_combos[e])&&c.is_exclusive&&a.is_exclusive){c=c.keys;if(!h){g=0;for(n=c.length;gi.call(a.keys,b)){h=!1;break}}if(f&&!h){m=a.keys;g=0;for(n=m.length;gi.call(c, 12 | b)){f=!0;break}}h&&(d?(c=this._active_combos.splice(e,1)[0],null!=c&&c.reset()):(c=this._active_combos.splice(e,1,a)[0],null!=c&&c.reset(),d=!0),f=!1)}}f&&this._active_combos.unshift(a);return h||f};g.prototype._remove_from_active_combos=function(a){var c,b,d,e;b=d=0;for(e=this._active_combos.length;0<=e?de;b=0<=e?++d:--d)if(c=this._active_combos[b],c===a){a=this._active_combos.splice(b,1)[0];a.reset();break}};g.prototype._get_possible_sequences=function(){var a,c,b,d,e,f,h,j,g,n,l,m;d=[];n= 13 | this._registered_combos;f=0;for(g=n.length;f=l;c=1<=l?++h:--h)if(e=this._sequence.slice(-c),a.is_sequence){if(0>i.call(a.keys,"shift")&&(e=w(e,function(a){return"shift"!==a}),!e.length))continue;c=j=0;for(m=e.length;0<=m?jm;c=0<=m?++j:--j)if(a.keys[c]===e[c])b=!0;else{b=!1;break}b&&d.push(a)}}return d};g.prototype._add_key_to_sequence=function(a,c){var b,d,e,f;this._sequence.push(a);d=this._get_possible_sequences();if(d.length){e=0; 14 | for(f=d.length;e=m;b=1<=m?++g:--g)if(f=w(this._sequence,function(a){return 0<= 15 | i.call(c.keys,"shift")?!0:"shift"!==a}).slice(-b),c.keys.length===f.length){b=u=0;for(k=f.length;0<=k?uk;b=0<=k?++u:--u)if(e=f[b],!(0>i.call(c.keys,"shift")&&"shift"===e)&&!("shift"===a&&0>i.call(c.keys,"shift")))if(c.keys[b]===e)d=!0;else{d=!1;break}}if(d)return c}return!1};g.prototype._receive_input=function(a,c){var b;if(this._prevent_capture)this._keys_down.length&&(this._keys_down=[]);else if(b=y(a.keyCode),(c||this._keys_down.length||!("alt"===b||b===k))&&b)return c?this._key_down(b,a): 16 | this._key_up(b,a)};g.prototype._fire=function(a,c,b,d){"function"===typeof c["on_"+a]&&this._prevent_default(b,!0!==c["on_"+a].call(c["this"],b,c.count,d));"release"===a&&(c.count=0);if("keyup"===a)return c.keyup_fired=!0};g.prototype._match_combo_arrays=function(a,c){var b,d,e,f;f=this._registered_combos;d=0;for(e=f.length;df;b=0<=f?++d:--d)this._keys_down[b]===e&&this._keys_down.splice(b,1)}d=this._get_active_combos(a);e=this._get_potential_combos(a);f=0;for(h=d.length;fi.call(this._keys_down,a)&&this._keys_down.push(a)};g.prototype._handle_combo_down=function(a,c,b, 19 | d){var e,f,h,g,k;if(0>i.call(a.keys,b))return!1;this._prevent_default(d,a&&a.prevent_default);e=!1;if(0<=i.call(this._keys_down,b)&&(e=!0,!a.allows_key_repeat()))return!1;h=this._add_to_active_combos(a,b);b=a.keyup_fired=!1;if(a.is_exclusive){g=0;for(k=c.length;ga.keys.length){b=!0;break}}if(!b&&(a.is_counting&&"function"===typeof a.on_keydown&&(a.count+=1),h))return this._fire("keydown",a,d,e)};g.prototype._key_up=function(a,c){var b,d,e,f,h,g;b=a;(e= 20 | z(a,c))&&(a=e);e=s[b];c.shiftKey?e&&0<=i.call(this._keys_down,e)||(a=b):b&&0<=i.call(this._keys_down,b)||(a=e);(f=this._get_sequence(a))&&this._fire("keyup",f,c);if(0>i.call(this._keys_down,a))return!1;f=h=0;for(g=this._keys_down.length;0<=g?hg;f=0<=g?++h:--h)if((d=this._keys_down[f])===a||d===e||d===b){this._keys_down.splice(f,1);break}d=this._active_combos.length;e=[];g=this._active_combos;f=0;for(h=g.length;fd;b=0<=d?++c:--c)if(a===g._registered_combos[b]){g._registered_combos.splice(b,1);break}else e.push(void 0);return e}; 24 | if(a.keys)return b(a);f=this._registered_combos;d=0;for(e=f.length;de;b=0<=e?++d:--d)if(a[b]!==c[b])return!1;return!0};D=function(a,c){var b,d,e;d=0;for(e=a.length;di.call(c,b))return!1;return!0};E=function(a,c){var b,d,e,f;e=d=0;for(f=a.length;e=d)d=b;else return!1;return!0};o=function(){if(p.debug)return console.log.apply(console,arguments)};F=function(a){var c,b,d;c=!1;for(d in r)if(b=r[d],a===b){c=!0;break}if(!c)for(d in s)if(b=s[d],a===b){c=!0;break}return c};H=function(a){var c,b,d,e,f,g,j;f=!0;a.keys.length|| 27 | o("You're trying to bind a combo with no keys:",a);b=g=0;for(j=a.keys.length;0<=j?gj;b=0<=j?++g:--g)d=a.keys[b],(c=G[d])&&(d=a.keys[b]=c),"meta"===d&&a.keys.splice(b,1,k),"cmd"===d&&o('Warning: use the "meta" key rather than "cmd" for Windows compatibility');j=a.keys;c=0;for(g=j.length;c",",":"<","'":'"',";":":","[":"{","]":"}","\\":"|","`":"~","=":"+","-":"_",1:"!",2:"@",3:"#",4:"$",5:"%",6:"^",7:"&",8:"*",9:"(","0":")"};r={"0":"\\",8:"backspace",9:"tab",12:"num",13:"enter",16:"shift",17:"ctrl",18:"alt",19:"pause",20:"caps",27:"esc",32:"space",33:"pageup",34:"pagedown",35:"end",36:"home",37:"left",38:"up",39:"right",40:"down",44:"print",45:"insert",46:"delete",48:"0",49:"1",50:"2",51:"3",52:"4",53:"5",54:"6",55:"7",56:"8",57:"9", 30 | 65:"a",66:"b",67:"c",68:"d",69:"e",70:"f",71:"g",72:"h",73:"i",74:"j",75:"k",76:"l",77:"m",78:"n",79:"o",80:"p",81:"q",82:"r",83:"s",84:"t",85:"u",86:"v",87:"w",88:"x",89:"y",90:"z",91:"cmd",92:"cmd",93:"cmd",96:"num_0",97:"num_1",98:"num_2",99:"num_3",100:"num_4",101:"num_5",102:"num_6",103:"num_7",104:"num_8",105:"num_9",106:"num_multiply",107:"num_add",108:"num_enter",109:"num_subtract",110:"num_decimal",111:"num_divide",124:"print",144:"num",145:"scroll",186:";",187:"=",188:",",189:"-",190:".", 31 | 191:"/",192:"`",219:"[",220:"\\",221:"]",222:"'",223:"`",224:"cmd",225:"alt",57392:"ctrl",63289:"num"};-1!==navigator.userAgent.indexOf("Mac OS X")&&(k="cmd");-1!==navigator.userAgent.indexOf("Opera")&&(r["17"]="cmd");"function"===typeof define&&define.amd?define([],function(){return p}):window.keypress=p}).call(this); 32 | -------------------------------------------------------------------------------- /node/index.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | var app = require('http').createServer(), 4 | io = require('socket.io').listen(app), 5 | fs = require('fs'), 6 | yezBackendPort = 9172, 7 | httpPort = 9173, 8 | TaskRunner = require('./TaskRunner'), 9 | path = require('path'), 10 | defaultCWD = path.normalize(process.cwd()), 11 | runners = {}, 12 | lastActive = 0, 13 | electron = require('electron-prebuilt'), 14 | proc = require('child_process'), 15 | argv = require('yargs').argv, 16 | httpServer = require('http-server'); 17 | 18 | app.listen(yezBackendPort); 19 | 20 | httpServer.createServer({root: path.normalize(__dirname+'/../chrome')}).listen(httpPort); 21 | 22 | var getCurrentRunnersIds = function() { 23 | cleaningRunners(); 24 | var res = []; 25 | if(runners) { 26 | for(var id in runners) { 27 | res.push({id: id}); 28 | } 29 | } 30 | return res; 31 | }; 32 | var cleaningRunners = function() { 33 | var res = {}; 34 | if(runners) { 35 | for(var id in runners) { 36 | var stillRunning = false; 37 | for(var i=0; i= 0) { 70 | this.data.independent.splice(i, 1); 71 | } else { 72 | this.data.independent.push(index); 73 | } 74 | } 75 | this.populate(); 76 | }, 77 | changeCommand: function(e, index) { 78 | index = parseInt(index); 79 | this.data.commands[index] = e.target.value.replace(/"/g, '"'); 80 | e.target.setAttribute('value', e.target.value); 81 | }, 82 | changeCommandName: function(e) { 83 | this.data.name = e.target.value; 84 | }, 85 | changeCWD: function(e) { 86 | this.data.cwd = e.target.value; 87 | }, 88 | autorunClick: function(e) { console.log(e.target.checked); 89 | this.data.autorun = e.target.checked; 90 | }, 91 | saveCommand: function(e) { 92 | e.preventDefault(); 93 | this.setMode('dashboard'); 94 | this.dispatch('save'); 95 | }, 96 | deleteTask: function(e) { 97 | if(confirm('Are you sure?')) { 98 | this.dispatch('delete-task'); 99 | } 100 | }, 101 | chooseCWD: function(e) { 102 | e.preventDefault(); 103 | CWD(this.data.cwd, function(cwd) { 104 | if(cwd) { 105 | this.data.cwd = cwd; 106 | this.populate(); 107 | } 108 | }.bind(this)); 109 | }, 110 | openCwd: function (e) { 111 | this.chooseCWD(e); 112 | }, 113 | // *********************************************** dashboard mode 114 | startTasks: function(e) { 115 | e && e.preventDefault(); 116 | if(this.started) return; 117 | this.setMode('dashboard'); 118 | this.started = true; 119 | this.endedCommands = 0; 120 | this.commandsToProcess = this.data.commands.slice(0); 121 | this.populate(); 122 | this.processTask(); 123 | this.dispatch('save'); 124 | this.endedCommands = 0; 125 | }, 126 | stopTasks: function(e) { 127 | e && e.preventDefault(); 128 | this.setMode('dashboard'); 129 | this.dispatch('data', { 130 | id: this.data.id, 131 | action: 'stop-command' 132 | }); 133 | this.commandsToProcess = []; 134 | this.endedCommands = -2; 135 | this.log('

stopping ...

'); 136 | }, 137 | restartTasks: function(e) { 138 | e && e.preventDefault(); 139 | this.restart = true; 140 | this.stopTasks(e); 141 | }, 142 | // Loop that sends the commands 143 | processTask: function() { 144 | if(!this.commandsToProcess || this.commandsToProcess.length == 0) { 145 | if(this.endedCommands >= this.data.commands.length || this.endedCommands == -1) { 146 | this.started = false; 147 | this.populate(); 148 | this.log('

task finished

'); 149 | this.dispatch('save'); 150 | this.dispatch('ended'); 151 | if(this.restart) { 152 | this.restart = false; 153 | this.clearLog().startTasks(); 154 | } 155 | } 156 | return; 157 | } 158 | var index = this.data.commands.length - this.commandsToProcess.length; 159 | var command = this.commandsToProcess.shift(); 160 | // ********************************************************* chrome 161 | if(command.indexOf('chrome:') === 0) { 162 | var parts = command.split(':'), self = this; 163 | parts.shift(); 164 | chrome.runtime.sendMessage({ 165 | type: parts.shift(), 166 | data: parts.join(':') 167 | }, function(res) { 168 | if(res) { 169 | self.response({ action: 'data', data: typeof res == 'object' ? JSON.stringify(res): res }); 170 | } 171 | self.response({ action: 'end', err: false, code: 'none'}); 172 | }); 173 | this.log('

' + command + '

'); 174 | 175 | // ********************************************************* nodejs 176 | } else { 177 | this.log('

' + command + '

'); 178 | this.dispatch('data', { 179 | id: this.data.id, 180 | action: 'run-command', 181 | command: command.replace(/"/g, '"'), 182 | cwd: this.data.cwd 183 | }); 184 | } 185 | // check if it is locked to the chain 186 | if(this.data.independent && this.data.independent.indexOf(index) >= 0) { 187 | this.processTask(); 188 | } 189 | }, 190 | // process the response from the Node.js part 191 | response: function(data) { 192 | var filterResponse = function(str) { 193 | str = str.replace(//g, '>'); 195 | return str; 196 | } 197 | switch(data.action) { 198 | case 'err': 199 | if(data.msg.toLowerCase().indexOf('warning') === 0) { 200 | this.log('

' + filterResponse(data.msg) + '

'); 201 | } else { 202 | this.log('

' + filterResponse(data.msg) + '

'); 203 | } 204 | break; 205 | case 'data': 206 | this.log('

' + filterResponse(data.data) + '

'); 207 | break; 208 | case 'end': 209 | var allErrors = ''; 210 | if(data.err != false) { 211 | allErrors += '
'; 212 | for(var i=0; iError: ' : ''; 215 | if(typeof err == 'object') err = JSON.stringify(err); 216 | allErrors += errDesc + err + '
'; 217 | } 218 | allErrors = ''; 219 | } 220 | this.log('

end (code: ' + data.code + ')' + filterResponse(allErrors) + '

'); 221 | this.endedCommands += 1; 222 | this.processTask(); 223 | break; 224 | case 'exit': 225 | this.log('

exit (code: ' + data.code + ', signal: ' + data.signal + ')

'); 226 | break; 227 | } 228 | }, 229 | log: function(msg, dom) { 230 | var html = ansi_up.ansi_to_html(msg); 231 | html = html.replace(/\n/g, '
'); 232 | if(!this.logElement) { this.logElement = dom('.dashboard .log').el; } 233 | if(this.logElement) { 234 | this.logElement.innerHTML = this.logElement.innerHTML + html; 235 | this.logElement.scrollTop = this.logElement.scrollHeight; 236 | } 237 | this.logContent = this.logElement.innerHTML; 238 | }, 239 | clearLog: function() { 240 | this.logContent = ''; 241 | this.populate(); 242 | return this; 243 | }, 244 | stdinKeyUp: function(e) { 245 | var historyValue = ''; 246 | e && e.preventDefault(); 247 | e && e.stopPropagation(); 248 | if(e.keyCode === 13) { // enter 249 | Autocomplete.clear(); 250 | var input = e.target.value, self = this; 251 | TerminalHistory.store(input); 252 | input = this.applyAliases(input); 253 | this.log('

' + input + '

'); 254 | e.target.value = ''; 255 | if(input.indexOf(' && ') >= 0) { 256 | this.commandsToProcess = input.split(' && '); 257 | this.processTask(); 258 | return; 259 | } 260 | if(input.split(/ /g)[0].toLowerCase() == 'cd') { 261 | var pathToAppend = input.split(/ /g), 262 | loc, 263 | appendOnlyIf = [Yez.sep]; 264 | pathToAppend.shift(); 265 | loc = pathToAppend.join(' '); 266 | Yez.send({ 267 | action: 'cd', 268 | id: this.getId(), 269 | dir: appendOnlyIf.indexOf(loc.charAt(0)) >= 0 ? loc : this.data.cwd + Yez.sep + loc 270 | }, function(data) { 271 | if(data.err) { 272 | self.log('

' + data.err.msg + '

'); 273 | } else if(data.dir) { 274 | self.data.cwd = normalizePath(data.dir); 275 | self.populate(); 276 | } 277 | }); 278 | } else if (input.toLowerCase() == 'dir') { 279 | var cwd = this.data.cwd; 280 | Yez.send({ 281 | action: 'list', 282 | id: this.getId(), 283 | cwd: cwd, 284 | }, function(data) { 285 | if(data.err) { 286 | self.log('

' + data.err.msg + '

'); 287 | } else { 288 | var folders = data.files.join('

'); 289 | self.log('

'+cwd+'

'+folders+'

'); 290 | } 291 | }); 292 | } else { 293 | Yez.send({ 294 | // action: this.data.terminal ? 'terminal' : 'stdin-input', 295 | action: 'run-command', 296 | id: this.getId(), 297 | command: input, 298 | cwd: this.data.cwd 299 | }, function(data) { 300 | // no need to process the result 301 | }.bind(this)); 302 | } 303 | } else if(e.keyCode === 27) { // escape 304 | e.target.value = ''; 305 | } else if(e.keyCode === 38) { // up 306 | if(historyValue = TerminalHistory.pull('up')) { 307 | e.target.value = historyValue; 308 | } 309 | } else if(e.keyCode === 40) { // down 310 | if(historyValue = TerminalHistory.pull('down')) { 311 | e.target.value = historyValue; 312 | } 313 | } else { 314 | Autocomplete.check(this.data.cwd); 315 | } 316 | }, 317 | stdinKeyDown: function(e) { 318 | if(e.keyCode === 9) { 319 | e.preventDefault(); 320 | Autocomplete.applyMatch(); 321 | } 322 | }, 323 | stdinFocused: function(e) { 324 | Autocomplete.setup(this.qs('.stdin-field'), this.qs('.autocomplete')); 325 | TerminalHistory.setup(this.qs('.stdin-field'), this.getId()); 326 | }, 327 | stdinBlured: function(e) { 328 | Autocomplete.off(); 329 | TerminalHistory.off(); 330 | }, 331 | // *********************************************** terminal 332 | terminalInit: function() { 333 | this.html['div[class="task-id task-<% getId() %>"]']['.sub-nav'] = [ 334 | { 'a[href="#" class="button operation" data-absurd-event="click:stopTasks"]': ' Stop all processes'}, 335 | { 'a[href="#" class="button operation" data-absurd-event="click:deleteTask"]': ' Close'} 336 | ]; 337 | }, 338 | gitStatus: function(value) { 339 | if(!this.gitStatusHolder) { 340 | this.gitStatusHolder = this.qs('.git-status'); 341 | } 342 | if(!value) { 343 | this.gitStatusHolder.innerHTML = ''; 344 | } else { 345 | var str = '', changes = ''; 346 | for(var i in value.status) { 347 | changes += i + value.status[i] + ' '; 348 | } 349 | str += ' ' + value.branch; 350 | str += changes != '' ? '/' + changes : ''; 351 | this.gitStatusHolder.innerHTML = str; 352 | } 353 | return this; 354 | }, 355 | editAliases: function() { 356 | Editor(Yez.aliases.bind(Yez), Yez.aliases(), 'Edit your aliases. Type one per line in the format "[regex]:[replacement]".'); 357 | }, 358 | applyAliases: function(input) { 359 | var aliases = Yez.aliases().split(/\n/g); 360 | for(var i=0; i" data-absurd-event="click:startTasks"]': ' Start'}, 390 | { 'a[href="#" class="button operation<% started ? "" : " hidden" %>" data-absurd-event="click:restartTasks"]': ' Restart'}, 391 | { 'a[href="#" class="button operation<% started ? "" : " hidden" %>" data-absurd-event="click:stopTasks"]': ' Stop'}, 392 | { 'a[href="#" class="button operation" data-absurd-event="click:goToEditMode"]': ' Edit'}, 393 | { 'a[href="#" class="button operation" data-absurd-event="click:deleteTask"]': ' Delete'} 394 | ], 395 | '.edit': [ 396 | { 397 | '.element': { 398 | 'label': 'Name', 399 | '.field': { 400 | 'input[type="text" name="name" value="<% data.name %>" data-absurd-event="keyup:changeCommandName"]': '' 401 | } 402 | } 403 | }, 404 | { 405 | '.element': { 406 | 'label': 'Working directory', 407 | '.field': { 408 | 'input[type="text" name="cwd" value="<% data.cwd %>" data-absurd-event="change:changeCWD"]': '' 409 | }, 410 | 'a.sub-right[href="#" data-absurd-event="click:chooseCWD:<% i %>"]': '' 411 | } 412 | }, 413 | '<% for(var i=0; i= 0 ? "fa-unlock" : "fa-lock"; \ 416 | var tip = indIcon == "fa-lock" ? "Run it independently" : "Lock the command to the chain"; \ 417 | %>', 418 | { 419 | '.element': { 420 | 'label': ' <% i+1 %>', 421 | '.field': { 422 | 'input[type="text" value="<% c %>" data-absurd-event="keyup:changeCommand:<% i %>"]': '' 423 | }, 424 | 'a.sub-left[href="#" title="Add new command" data-absurd-event="click:addCommand:<% i %>"]': '', 425 | 'a.sub-right[href="#" title="Remove the command" data-absurd-event="click:removeCommand:<% i %>"]': '', 426 | 'a.sub-independent[href="#" title="<% tip %>" data-absurd-event="click:independentCommand:<% i %>"]': '' 427 | } 428 | }, 429 | '<% } %>', 430 | { 431 | '.element.autorun': [ 432 | { 'span': 'Autorun name="autorun" data-absurd-event="click:autorunClick">' } 433 | ] 434 | }, 435 | { 436 | '.actions': [ 437 | { 'a[href="#" class="button operation" data-absurd-event="click:saveCommand"]': ' Save' } 438 | ] 439 | } 440 | ], 441 | '.dashboard': [ 442 | { 'a[href="#" class="clear-log" data-absurd-event="click:clearLog"]': ' Clear'}, 443 | { '.log': '<% logContent %>' }, 444 | { '.autocomplete': ''}, 445 | { 'input[class="stdin-field" data-absurd-event="keyup:stdinKeyUp,keydown:stdinKeyDown,focus:stdinFocused,blur:stdinBlured"]': ''}, 446 | { '.stdin-field-tooltip': ''}, 447 | { '.task-cwd[data-absurd-event="click:openCwd"]': ' <% data.cwd %>' }, 448 | { '.git-status': '' }, 449 | { 'a[href="#" class="aliases" data-absurd-event="click:editAliases"]': ''} 450 | ] 451 | } 452 | } 453 | } 454 | -------------------------------------------------------------------------------- /chrome/css/font-awesome-4.1.0/less/variables.less: -------------------------------------------------------------------------------- 1 | // Variables 2 | // -------------------------- 3 | 4 | @fa-font-path: "../fonts"; 5 | //@fa-font-path: "//netdna.bootstrapcdn.com/font-awesome/4.1.0/fonts"; // for referencing Bootstrap CDN font files directly 6 | @fa-css-prefix: fa; 7 | @fa-version: "4.1.0"; 8 | @fa-border-color: #eee; 9 | @fa-inverse: #fff; 10 | @fa-li-width: (30em / 14); 11 | 12 | @fa-var-adjust: "\f042"; 13 | @fa-var-adn: "\f170"; 14 | @fa-var-align-center: "\f037"; 15 | @fa-var-align-justify: "\f039"; 16 | @fa-var-align-left: "\f036"; 17 | @fa-var-align-right: "\f038"; 18 | @fa-var-ambulance: "\f0f9"; 19 | @fa-var-anchor: "\f13d"; 20 | @fa-var-android: "\f17b"; 21 | @fa-var-angle-double-down: "\f103"; 22 | @fa-var-angle-double-left: "\f100"; 23 | @fa-var-angle-double-right: "\f101"; 24 | @fa-var-angle-double-up: "\f102"; 25 | @fa-var-angle-down: "\f107"; 26 | @fa-var-angle-left: "\f104"; 27 | @fa-var-angle-right: "\f105"; 28 | @fa-var-angle-up: "\f106"; 29 | @fa-var-apple: "\f179"; 30 | @fa-var-archive: "\f187"; 31 | @fa-var-arrow-circle-down: "\f0ab"; 32 | @fa-var-arrow-circle-left: "\f0a8"; 33 | @fa-var-arrow-circle-o-down: "\f01a"; 34 | @fa-var-arrow-circle-o-left: "\f190"; 35 | @fa-var-arrow-circle-o-right: "\f18e"; 36 | @fa-var-arrow-circle-o-up: "\f01b"; 37 | @fa-var-arrow-circle-right: "\f0a9"; 38 | @fa-var-arrow-circle-up: "\f0aa"; 39 | @fa-var-arrow-down: "\f063"; 40 | @fa-var-arrow-left: "\f060"; 41 | @fa-var-arrow-right: "\f061"; 42 | @fa-var-arrow-up: "\f062"; 43 | @fa-var-arrows: "\f047"; 44 | @fa-var-arrows-alt: "\f0b2"; 45 | @fa-var-arrows-h: "\f07e"; 46 | @fa-var-arrows-v: "\f07d"; 47 | @fa-var-asterisk: "\f069"; 48 | @fa-var-automobile: "\f1b9"; 49 | @fa-var-backward: "\f04a"; 50 | @fa-var-ban: "\f05e"; 51 | @fa-var-bank: "\f19c"; 52 | @fa-var-bar-chart-o: "\f080"; 53 | @fa-var-barcode: "\f02a"; 54 | @fa-var-bars: "\f0c9"; 55 | @fa-var-beer: "\f0fc"; 56 | @fa-var-behance: "\f1b4"; 57 | @fa-var-behance-square: "\f1b5"; 58 | @fa-var-bell: "\f0f3"; 59 | @fa-var-bell-o: "\f0a2"; 60 | @fa-var-bitbucket: "\f171"; 61 | @fa-var-bitbucket-square: "\f172"; 62 | @fa-var-bitcoin: "\f15a"; 63 | @fa-var-bold: "\f032"; 64 | @fa-var-bolt: "\f0e7"; 65 | @fa-var-bomb: "\f1e2"; 66 | @fa-var-book: "\f02d"; 67 | @fa-var-bookmark: "\f02e"; 68 | @fa-var-bookmark-o: "\f097"; 69 | @fa-var-briefcase: "\f0b1"; 70 | @fa-var-btc: "\f15a"; 71 | @fa-var-bug: "\f188"; 72 | @fa-var-building: "\f1ad"; 73 | @fa-var-building-o: "\f0f7"; 74 | @fa-var-bullhorn: "\f0a1"; 75 | @fa-var-bullseye: "\f140"; 76 | @fa-var-cab: "\f1ba"; 77 | @fa-var-calendar: "\f073"; 78 | @fa-var-calendar-o: "\f133"; 79 | @fa-var-camera: "\f030"; 80 | @fa-var-camera-retro: "\f083"; 81 | @fa-var-car: "\f1b9"; 82 | @fa-var-caret-down: "\f0d7"; 83 | @fa-var-caret-left: "\f0d9"; 84 | @fa-var-caret-right: "\f0da"; 85 | @fa-var-caret-square-o-down: "\f150"; 86 | @fa-var-caret-square-o-left: "\f191"; 87 | @fa-var-caret-square-o-right: "\f152"; 88 | @fa-var-caret-square-o-up: "\f151"; 89 | @fa-var-caret-up: "\f0d8"; 90 | @fa-var-certificate: "\f0a3"; 91 | @fa-var-chain: "\f0c1"; 92 | @fa-var-chain-broken: "\f127"; 93 | @fa-var-check: "\f00c"; 94 | @fa-var-check-circle: "\f058"; 95 | @fa-var-check-circle-o: "\f05d"; 96 | @fa-var-check-square: "\f14a"; 97 | @fa-var-check-square-o: "\f046"; 98 | @fa-var-chevron-circle-down: "\f13a"; 99 | @fa-var-chevron-circle-left: "\f137"; 100 | @fa-var-chevron-circle-right: "\f138"; 101 | @fa-var-chevron-circle-up: "\f139"; 102 | @fa-var-chevron-down: "\f078"; 103 | @fa-var-chevron-left: "\f053"; 104 | @fa-var-chevron-right: "\f054"; 105 | @fa-var-chevron-up: "\f077"; 106 | @fa-var-child: "\f1ae"; 107 | @fa-var-circle: "\f111"; 108 | @fa-var-circle-o: "\f10c"; 109 | @fa-var-circle-o-notch: "\f1ce"; 110 | @fa-var-circle-thin: "\f1db"; 111 | @fa-var-clipboard: "\f0ea"; 112 | @fa-var-clock-o: "\f017"; 113 | @fa-var-cloud: "\f0c2"; 114 | @fa-var-cloud-download: "\f0ed"; 115 | @fa-var-cloud-upload: "\f0ee"; 116 | @fa-var-cny: "\f157"; 117 | @fa-var-code: "\f121"; 118 | @fa-var-code-fork: "\f126"; 119 | @fa-var-codepen: "\f1cb"; 120 | @fa-var-coffee: "\f0f4"; 121 | @fa-var-cog: "\f013"; 122 | @fa-var-cogs: "\f085"; 123 | @fa-var-columns: "\f0db"; 124 | @fa-var-comment: "\f075"; 125 | @fa-var-comment-o: "\f0e5"; 126 | @fa-var-comments: "\f086"; 127 | @fa-var-comments-o: "\f0e6"; 128 | @fa-var-compass: "\f14e"; 129 | @fa-var-compress: "\f066"; 130 | @fa-var-copy: "\f0c5"; 131 | @fa-var-credit-card: "\f09d"; 132 | @fa-var-crop: "\f125"; 133 | @fa-var-crosshairs: "\f05b"; 134 | @fa-var-css3: "\f13c"; 135 | @fa-var-cube: "\f1b2"; 136 | @fa-var-cubes: "\f1b3"; 137 | @fa-var-cut: "\f0c4"; 138 | @fa-var-cutlery: "\f0f5"; 139 | @fa-var-dashboard: "\f0e4"; 140 | @fa-var-database: "\f1c0"; 141 | @fa-var-dedent: "\f03b"; 142 | @fa-var-delicious: "\f1a5"; 143 | @fa-var-desktop: "\f108"; 144 | @fa-var-deviantart: "\f1bd"; 145 | @fa-var-digg: "\f1a6"; 146 | @fa-var-dollar: "\f155"; 147 | @fa-var-dot-circle-o: "\f192"; 148 | @fa-var-download: "\f019"; 149 | @fa-var-dribbble: "\f17d"; 150 | @fa-var-dropbox: "\f16b"; 151 | @fa-var-drupal: "\f1a9"; 152 | @fa-var-edit: "\f044"; 153 | @fa-var-eject: "\f052"; 154 | @fa-var-ellipsis-h: "\f141"; 155 | @fa-var-ellipsis-v: "\f142"; 156 | @fa-var-empire: "\f1d1"; 157 | @fa-var-envelope: "\f0e0"; 158 | @fa-var-envelope-o: "\f003"; 159 | @fa-var-envelope-square: "\f199"; 160 | @fa-var-eraser: "\f12d"; 161 | @fa-var-eur: "\f153"; 162 | @fa-var-euro: "\f153"; 163 | @fa-var-exchange: "\f0ec"; 164 | @fa-var-exclamation: "\f12a"; 165 | @fa-var-exclamation-circle: "\f06a"; 166 | @fa-var-exclamation-triangle: "\f071"; 167 | @fa-var-expand: "\f065"; 168 | @fa-var-external-link: "\f08e"; 169 | @fa-var-external-link-square: "\f14c"; 170 | @fa-var-eye: "\f06e"; 171 | @fa-var-eye-slash: "\f070"; 172 | @fa-var-facebook: "\f09a"; 173 | @fa-var-facebook-square: "\f082"; 174 | @fa-var-fast-backward: "\f049"; 175 | @fa-var-fast-forward: "\f050"; 176 | @fa-var-fax: "\f1ac"; 177 | @fa-var-female: "\f182"; 178 | @fa-var-fighter-jet: "\f0fb"; 179 | @fa-var-file: "\f15b"; 180 | @fa-var-file-archive-o: "\f1c6"; 181 | @fa-var-file-audio-o: "\f1c7"; 182 | @fa-var-file-code-o: "\f1c9"; 183 | @fa-var-file-excel-o: "\f1c3"; 184 | @fa-var-file-image-o: "\f1c5"; 185 | @fa-var-file-movie-o: "\f1c8"; 186 | @fa-var-file-o: "\f016"; 187 | @fa-var-file-pdf-o: "\f1c1"; 188 | @fa-var-file-photo-o: "\f1c5"; 189 | @fa-var-file-picture-o: "\f1c5"; 190 | @fa-var-file-powerpoint-o: "\f1c4"; 191 | @fa-var-file-sound-o: "\f1c7"; 192 | @fa-var-file-text: "\f15c"; 193 | @fa-var-file-text-o: "\f0f6"; 194 | @fa-var-file-video-o: "\f1c8"; 195 | @fa-var-file-word-o: "\f1c2"; 196 | @fa-var-file-zip-o: "\f1c6"; 197 | @fa-var-files-o: "\f0c5"; 198 | @fa-var-film: "\f008"; 199 | @fa-var-filter: "\f0b0"; 200 | @fa-var-fire: "\f06d"; 201 | @fa-var-fire-extinguisher: "\f134"; 202 | @fa-var-flag: "\f024"; 203 | @fa-var-flag-checkered: "\f11e"; 204 | @fa-var-flag-o: "\f11d"; 205 | @fa-var-flash: "\f0e7"; 206 | @fa-var-flask: "\f0c3"; 207 | @fa-var-flickr: "\f16e"; 208 | @fa-var-floppy-o: "\f0c7"; 209 | @fa-var-folder: "\f07b"; 210 | @fa-var-folder-o: "\f114"; 211 | @fa-var-folder-open: "\f07c"; 212 | @fa-var-folder-open-o: "\f115"; 213 | @fa-var-font: "\f031"; 214 | @fa-var-forward: "\f04e"; 215 | @fa-var-foursquare: "\f180"; 216 | @fa-var-frown-o: "\f119"; 217 | @fa-var-gamepad: "\f11b"; 218 | @fa-var-gavel: "\f0e3"; 219 | @fa-var-gbp: "\f154"; 220 | @fa-var-ge: "\f1d1"; 221 | @fa-var-gear: "\f013"; 222 | @fa-var-gears: "\f085"; 223 | @fa-var-gift: "\f06b"; 224 | @fa-var-git: "\f1d3"; 225 | @fa-var-git-square: "\f1d2"; 226 | @fa-var-github: "\f09b"; 227 | @fa-var-github-alt: "\f113"; 228 | @fa-var-github-square: "\f092"; 229 | @fa-var-gittip: "\f184"; 230 | @fa-var-glass: "\f000"; 231 | @fa-var-globe: "\f0ac"; 232 | @fa-var-google: "\f1a0"; 233 | @fa-var-google-plus: "\f0d5"; 234 | @fa-var-google-plus-square: "\f0d4"; 235 | @fa-var-graduation-cap: "\f19d"; 236 | @fa-var-group: "\f0c0"; 237 | @fa-var-h-square: "\f0fd"; 238 | @fa-var-hacker-news: "\f1d4"; 239 | @fa-var-hand-o-down: "\f0a7"; 240 | @fa-var-hand-o-left: "\f0a5"; 241 | @fa-var-hand-o-right: "\f0a4"; 242 | @fa-var-hand-o-up: "\f0a6"; 243 | @fa-var-hdd-o: "\f0a0"; 244 | @fa-var-header: "\f1dc"; 245 | @fa-var-headphones: "\f025"; 246 | @fa-var-heart: "\f004"; 247 | @fa-var-heart-o: "\f08a"; 248 | @fa-var-history: "\f1da"; 249 | @fa-var-home: "\f015"; 250 | @fa-var-hospital-o: "\f0f8"; 251 | @fa-var-html5: "\f13b"; 252 | @fa-var-image: "\f03e"; 253 | @fa-var-inbox: "\f01c"; 254 | @fa-var-indent: "\f03c"; 255 | @fa-var-info: "\f129"; 256 | @fa-var-info-circle: "\f05a"; 257 | @fa-var-inr: "\f156"; 258 | @fa-var-instagram: "\f16d"; 259 | @fa-var-institution: "\f19c"; 260 | @fa-var-italic: "\f033"; 261 | @fa-var-joomla: "\f1aa"; 262 | @fa-var-jpy: "\f157"; 263 | @fa-var-jsfiddle: "\f1cc"; 264 | @fa-var-key: "\f084"; 265 | @fa-var-keyboard-o: "\f11c"; 266 | @fa-var-krw: "\f159"; 267 | @fa-var-language: "\f1ab"; 268 | @fa-var-laptop: "\f109"; 269 | @fa-var-leaf: "\f06c"; 270 | @fa-var-legal: "\f0e3"; 271 | @fa-var-lemon-o: "\f094"; 272 | @fa-var-level-down: "\f149"; 273 | @fa-var-level-up: "\f148"; 274 | @fa-var-life-bouy: "\f1cd"; 275 | @fa-var-life-ring: "\f1cd"; 276 | @fa-var-life-saver: "\f1cd"; 277 | @fa-var-lightbulb-o: "\f0eb"; 278 | @fa-var-link: "\f0c1"; 279 | @fa-var-linkedin: "\f0e1"; 280 | @fa-var-linkedin-square: "\f08c"; 281 | @fa-var-linux: "\f17c"; 282 | @fa-var-list: "\f03a"; 283 | @fa-var-list-alt: "\f022"; 284 | @fa-var-list-ol: "\f0cb"; 285 | @fa-var-list-ul: "\f0ca"; 286 | @fa-var-location-arrow: "\f124"; 287 | @fa-var-lock: "\f023"; 288 | @fa-var-long-arrow-down: "\f175"; 289 | @fa-var-long-arrow-left: "\f177"; 290 | @fa-var-long-arrow-right: "\f178"; 291 | @fa-var-long-arrow-up: "\f176"; 292 | @fa-var-magic: "\f0d0"; 293 | @fa-var-magnet: "\f076"; 294 | @fa-var-mail-forward: "\f064"; 295 | @fa-var-mail-reply: "\f112"; 296 | @fa-var-mail-reply-all: "\f122"; 297 | @fa-var-male: "\f183"; 298 | @fa-var-map-marker: "\f041"; 299 | @fa-var-maxcdn: "\f136"; 300 | @fa-var-medkit: "\f0fa"; 301 | @fa-var-meh-o: "\f11a"; 302 | @fa-var-microphone: "\f130"; 303 | @fa-var-microphone-slash: "\f131"; 304 | @fa-var-minus: "\f068"; 305 | @fa-var-minus-circle: "\f056"; 306 | @fa-var-minus-square: "\f146"; 307 | @fa-var-minus-square-o: "\f147"; 308 | @fa-var-mobile: "\f10b"; 309 | @fa-var-mobile-phone: "\f10b"; 310 | @fa-var-money: "\f0d6"; 311 | @fa-var-moon-o: "\f186"; 312 | @fa-var-mortar-board: "\f19d"; 313 | @fa-var-music: "\f001"; 314 | @fa-var-navicon: "\f0c9"; 315 | @fa-var-openid: "\f19b"; 316 | @fa-var-outdent: "\f03b"; 317 | @fa-var-pagelines: "\f18c"; 318 | @fa-var-paper-plane: "\f1d8"; 319 | @fa-var-paper-plane-o: "\f1d9"; 320 | @fa-var-paperclip: "\f0c6"; 321 | @fa-var-paragraph: "\f1dd"; 322 | @fa-var-paste: "\f0ea"; 323 | @fa-var-pause: "\f04c"; 324 | @fa-var-paw: "\f1b0"; 325 | @fa-var-pencil: "\f040"; 326 | @fa-var-pencil-square: "\f14b"; 327 | @fa-var-pencil-square-o: "\f044"; 328 | @fa-var-phone: "\f095"; 329 | @fa-var-phone-square: "\f098"; 330 | @fa-var-photo: "\f03e"; 331 | @fa-var-picture-o: "\f03e"; 332 | @fa-var-pied-piper: "\f1a7"; 333 | @fa-var-pied-piper-alt: "\f1a8"; 334 | @fa-var-pied-piper-square: "\f1a7"; 335 | @fa-var-pinterest: "\f0d2"; 336 | @fa-var-pinterest-square: "\f0d3"; 337 | @fa-var-plane: "\f072"; 338 | @fa-var-play: "\f04b"; 339 | @fa-var-play-circle: "\f144"; 340 | @fa-var-play-circle-o: "\f01d"; 341 | @fa-var-plus: "\f067"; 342 | @fa-var-plus-circle: "\f055"; 343 | @fa-var-plus-square: "\f0fe"; 344 | @fa-var-plus-square-o: "\f196"; 345 | @fa-var-power-off: "\f011"; 346 | @fa-var-print: "\f02f"; 347 | @fa-var-puzzle-piece: "\f12e"; 348 | @fa-var-qq: "\f1d6"; 349 | @fa-var-qrcode: "\f029"; 350 | @fa-var-question: "\f128"; 351 | @fa-var-question-circle: "\f059"; 352 | @fa-var-quote-left: "\f10d"; 353 | @fa-var-quote-right: "\f10e"; 354 | @fa-var-ra: "\f1d0"; 355 | @fa-var-random: "\f074"; 356 | @fa-var-rebel: "\f1d0"; 357 | @fa-var-recycle: "\f1b8"; 358 | @fa-var-reddit: "\f1a1"; 359 | @fa-var-reddit-square: "\f1a2"; 360 | @fa-var-refresh: "\f021"; 361 | @fa-var-renren: "\f18b"; 362 | @fa-var-reorder: "\f0c9"; 363 | @fa-var-repeat: "\f01e"; 364 | @fa-var-reply: "\f112"; 365 | @fa-var-reply-all: "\f122"; 366 | @fa-var-retweet: "\f079"; 367 | @fa-var-rmb: "\f157"; 368 | @fa-var-road: "\f018"; 369 | @fa-var-rocket: "\f135"; 370 | @fa-var-rotate-left: "\f0e2"; 371 | @fa-var-rotate-right: "\f01e"; 372 | @fa-var-rouble: "\f158"; 373 | @fa-var-rss: "\f09e"; 374 | @fa-var-rss-square: "\f143"; 375 | @fa-var-rub: "\f158"; 376 | @fa-var-ruble: "\f158"; 377 | @fa-var-rupee: "\f156"; 378 | @fa-var-save: "\f0c7"; 379 | @fa-var-scissors: "\f0c4"; 380 | @fa-var-search: "\f002"; 381 | @fa-var-search-minus: "\f010"; 382 | @fa-var-search-plus: "\f00e"; 383 | @fa-var-send: "\f1d8"; 384 | @fa-var-send-o: "\f1d9"; 385 | @fa-var-share: "\f064"; 386 | @fa-var-share-alt: "\f1e0"; 387 | @fa-var-share-alt-square: "\f1e1"; 388 | @fa-var-share-square: "\f14d"; 389 | @fa-var-share-square-o: "\f045"; 390 | @fa-var-shield: "\f132"; 391 | @fa-var-shopping-cart: "\f07a"; 392 | @fa-var-sign-in: "\f090"; 393 | @fa-var-sign-out: "\f08b"; 394 | @fa-var-signal: "\f012"; 395 | @fa-var-sitemap: "\f0e8"; 396 | @fa-var-skype: "\f17e"; 397 | @fa-var-slack: "\f198"; 398 | @fa-var-sliders: "\f1de"; 399 | @fa-var-smile-o: "\f118"; 400 | @fa-var-sort: "\f0dc"; 401 | @fa-var-sort-alpha-asc: "\f15d"; 402 | @fa-var-sort-alpha-desc: "\f15e"; 403 | @fa-var-sort-amount-asc: "\f160"; 404 | @fa-var-sort-amount-desc: "\f161"; 405 | @fa-var-sort-asc: "\f0de"; 406 | @fa-var-sort-desc: "\f0dd"; 407 | @fa-var-sort-down: "\f0dd"; 408 | @fa-var-sort-numeric-asc: "\f162"; 409 | @fa-var-sort-numeric-desc: "\f163"; 410 | @fa-var-sort-up: "\f0de"; 411 | @fa-var-soundcloud: "\f1be"; 412 | @fa-var-space-shuttle: "\f197"; 413 | @fa-var-spinner: "\f110"; 414 | @fa-var-spoon: "\f1b1"; 415 | @fa-var-spotify: "\f1bc"; 416 | @fa-var-square: "\f0c8"; 417 | @fa-var-square-o: "\f096"; 418 | @fa-var-stack-exchange: "\f18d"; 419 | @fa-var-stack-overflow: "\f16c"; 420 | @fa-var-star: "\f005"; 421 | @fa-var-star-half: "\f089"; 422 | @fa-var-star-half-empty: "\f123"; 423 | @fa-var-star-half-full: "\f123"; 424 | @fa-var-star-half-o: "\f123"; 425 | @fa-var-star-o: "\f006"; 426 | @fa-var-steam: "\f1b6"; 427 | @fa-var-steam-square: "\f1b7"; 428 | @fa-var-step-backward: "\f048"; 429 | @fa-var-step-forward: "\f051"; 430 | @fa-var-stethoscope: "\f0f1"; 431 | @fa-var-stop: "\f04d"; 432 | @fa-var-strikethrough: "\f0cc"; 433 | @fa-var-stumbleupon: "\f1a4"; 434 | @fa-var-stumbleupon-circle: "\f1a3"; 435 | @fa-var-subscript: "\f12c"; 436 | @fa-var-suitcase: "\f0f2"; 437 | @fa-var-sun-o: "\f185"; 438 | @fa-var-superscript: "\f12b"; 439 | @fa-var-support: "\f1cd"; 440 | @fa-var-table: "\f0ce"; 441 | @fa-var-tablet: "\f10a"; 442 | @fa-var-tachometer: "\f0e4"; 443 | @fa-var-tag: "\f02b"; 444 | @fa-var-tags: "\f02c"; 445 | @fa-var-tasks: "\f0ae"; 446 | @fa-var-taxi: "\f1ba"; 447 | @fa-var-tencent-weibo: "\f1d5"; 448 | @fa-var-terminal: "\f120"; 449 | @fa-var-text-height: "\f034"; 450 | @fa-var-text-width: "\f035"; 451 | @fa-var-th: "\f00a"; 452 | @fa-var-th-large: "\f009"; 453 | @fa-var-th-list: "\f00b"; 454 | @fa-var-thumb-tack: "\f08d"; 455 | @fa-var-thumbs-down: "\f165"; 456 | @fa-var-thumbs-o-down: "\f088"; 457 | @fa-var-thumbs-o-up: "\f087"; 458 | @fa-var-thumbs-up: "\f164"; 459 | @fa-var-ticket: "\f145"; 460 | @fa-var-times: "\f00d"; 461 | @fa-var-times-circle: "\f057"; 462 | @fa-var-times-circle-o: "\f05c"; 463 | @fa-var-tint: "\f043"; 464 | @fa-var-toggle-down: "\f150"; 465 | @fa-var-toggle-left: "\f191"; 466 | @fa-var-toggle-right: "\f152"; 467 | @fa-var-toggle-up: "\f151"; 468 | @fa-var-trash-o: "\f014"; 469 | @fa-var-tree: "\f1bb"; 470 | @fa-var-trello: "\f181"; 471 | @fa-var-trophy: "\f091"; 472 | @fa-var-truck: "\f0d1"; 473 | @fa-var-try: "\f195"; 474 | @fa-var-tumblr: "\f173"; 475 | @fa-var-tumblr-square: "\f174"; 476 | @fa-var-turkish-lira: "\f195"; 477 | @fa-var-twitter: "\f099"; 478 | @fa-var-twitter-square: "\f081"; 479 | @fa-var-umbrella: "\f0e9"; 480 | @fa-var-underline: "\f0cd"; 481 | @fa-var-undo: "\f0e2"; 482 | @fa-var-university: "\f19c"; 483 | @fa-var-unlink: "\f127"; 484 | @fa-var-unlock: "\f09c"; 485 | @fa-var-unlock-alt: "\f13e"; 486 | @fa-var-unsorted: "\f0dc"; 487 | @fa-var-upload: "\f093"; 488 | @fa-var-usd: "\f155"; 489 | @fa-var-user: "\f007"; 490 | @fa-var-user-md: "\f0f0"; 491 | @fa-var-users: "\f0c0"; 492 | @fa-var-video-camera: "\f03d"; 493 | @fa-var-vimeo-square: "\f194"; 494 | @fa-var-vine: "\f1ca"; 495 | @fa-var-vk: "\f189"; 496 | @fa-var-volume-down: "\f027"; 497 | @fa-var-volume-off: "\f026"; 498 | @fa-var-volume-up: "\f028"; 499 | @fa-var-warning: "\f071"; 500 | @fa-var-wechat: "\f1d7"; 501 | @fa-var-weibo: "\f18a"; 502 | @fa-var-weixin: "\f1d7"; 503 | @fa-var-wheelchair: "\f193"; 504 | @fa-var-windows: "\f17a"; 505 | @fa-var-won: "\f159"; 506 | @fa-var-wordpress: "\f19a"; 507 | @fa-var-wrench: "\f0ad"; 508 | @fa-var-xing: "\f168"; 509 | @fa-var-xing-square: "\f169"; 510 | @fa-var-yahoo: "\f19e"; 511 | @fa-var-yen: "\f157"; 512 | @fa-var-youtube: "\f167"; 513 | @fa-var-youtube-play: "\f16a"; 514 | @fa-var-youtube-square: "\f166"; 515 | 516 | -------------------------------------------------------------------------------- /chrome/css/font-awesome-4.1.0/scss/_variables.scss: -------------------------------------------------------------------------------- 1 | // Variables 2 | // -------------------------- 3 | 4 | $fa-font-path: "../fonts" !default; 5 | //$fa-font-path: "//netdna.bootstrapcdn.com/font-awesome/4.1.0/fonts" !default; // for referencing Bootstrap CDN font files directly 6 | $fa-css-prefix: fa !default; 7 | $fa-version: "4.1.0" !default; 8 | $fa-border-color: #eee !default; 9 | $fa-inverse: #fff !default; 10 | $fa-li-width: (30em / 14) !default; 11 | 12 | $fa-var-adjust: "\f042"; 13 | $fa-var-adn: "\f170"; 14 | $fa-var-align-center: "\f037"; 15 | $fa-var-align-justify: "\f039"; 16 | $fa-var-align-left: "\f036"; 17 | $fa-var-align-right: "\f038"; 18 | $fa-var-ambulance: "\f0f9"; 19 | $fa-var-anchor: "\f13d"; 20 | $fa-var-android: "\f17b"; 21 | $fa-var-angle-double-down: "\f103"; 22 | $fa-var-angle-double-left: "\f100"; 23 | $fa-var-angle-double-right: "\f101"; 24 | $fa-var-angle-double-up: "\f102"; 25 | $fa-var-angle-down: "\f107"; 26 | $fa-var-angle-left: "\f104"; 27 | $fa-var-angle-right: "\f105"; 28 | $fa-var-angle-up: "\f106"; 29 | $fa-var-apple: "\f179"; 30 | $fa-var-archive: "\f187"; 31 | $fa-var-arrow-circle-down: "\f0ab"; 32 | $fa-var-arrow-circle-left: "\f0a8"; 33 | $fa-var-arrow-circle-o-down: "\f01a"; 34 | $fa-var-arrow-circle-o-left: "\f190"; 35 | $fa-var-arrow-circle-o-right: "\f18e"; 36 | $fa-var-arrow-circle-o-up: "\f01b"; 37 | $fa-var-arrow-circle-right: "\f0a9"; 38 | $fa-var-arrow-circle-up: "\f0aa"; 39 | $fa-var-arrow-down: "\f063"; 40 | $fa-var-arrow-left: "\f060"; 41 | $fa-var-arrow-right: "\f061"; 42 | $fa-var-arrow-up: "\f062"; 43 | $fa-var-arrows: "\f047"; 44 | $fa-var-arrows-alt: "\f0b2"; 45 | $fa-var-arrows-h: "\f07e"; 46 | $fa-var-arrows-v: "\f07d"; 47 | $fa-var-asterisk: "\f069"; 48 | $fa-var-automobile: "\f1b9"; 49 | $fa-var-backward: "\f04a"; 50 | $fa-var-ban: "\f05e"; 51 | $fa-var-bank: "\f19c"; 52 | $fa-var-bar-chart-o: "\f080"; 53 | $fa-var-barcode: "\f02a"; 54 | $fa-var-bars: "\f0c9"; 55 | $fa-var-beer: "\f0fc"; 56 | $fa-var-behance: "\f1b4"; 57 | $fa-var-behance-square: "\f1b5"; 58 | $fa-var-bell: "\f0f3"; 59 | $fa-var-bell-o: "\f0a2"; 60 | $fa-var-bitbucket: "\f171"; 61 | $fa-var-bitbucket-square: "\f172"; 62 | $fa-var-bitcoin: "\f15a"; 63 | $fa-var-bold: "\f032"; 64 | $fa-var-bolt: "\f0e7"; 65 | $fa-var-bomb: "\f1e2"; 66 | $fa-var-book: "\f02d"; 67 | $fa-var-bookmark: "\f02e"; 68 | $fa-var-bookmark-o: "\f097"; 69 | $fa-var-briefcase: "\f0b1"; 70 | $fa-var-btc: "\f15a"; 71 | $fa-var-bug: "\f188"; 72 | $fa-var-building: "\f1ad"; 73 | $fa-var-building-o: "\f0f7"; 74 | $fa-var-bullhorn: "\f0a1"; 75 | $fa-var-bullseye: "\f140"; 76 | $fa-var-cab: "\f1ba"; 77 | $fa-var-calendar: "\f073"; 78 | $fa-var-calendar-o: "\f133"; 79 | $fa-var-camera: "\f030"; 80 | $fa-var-camera-retro: "\f083"; 81 | $fa-var-car: "\f1b9"; 82 | $fa-var-caret-down: "\f0d7"; 83 | $fa-var-caret-left: "\f0d9"; 84 | $fa-var-caret-right: "\f0da"; 85 | $fa-var-caret-square-o-down: "\f150"; 86 | $fa-var-caret-square-o-left: "\f191"; 87 | $fa-var-caret-square-o-right: "\f152"; 88 | $fa-var-caret-square-o-up: "\f151"; 89 | $fa-var-caret-up: "\f0d8"; 90 | $fa-var-certificate: "\f0a3"; 91 | $fa-var-chain: "\f0c1"; 92 | $fa-var-chain-broken: "\f127"; 93 | $fa-var-check: "\f00c"; 94 | $fa-var-check-circle: "\f058"; 95 | $fa-var-check-circle-o: "\f05d"; 96 | $fa-var-check-square: "\f14a"; 97 | $fa-var-check-square-o: "\f046"; 98 | $fa-var-chevron-circle-down: "\f13a"; 99 | $fa-var-chevron-circle-left: "\f137"; 100 | $fa-var-chevron-circle-right: "\f138"; 101 | $fa-var-chevron-circle-up: "\f139"; 102 | $fa-var-chevron-down: "\f078"; 103 | $fa-var-chevron-left: "\f053"; 104 | $fa-var-chevron-right: "\f054"; 105 | $fa-var-chevron-up: "\f077"; 106 | $fa-var-child: "\f1ae"; 107 | $fa-var-circle: "\f111"; 108 | $fa-var-circle-o: "\f10c"; 109 | $fa-var-circle-o-notch: "\f1ce"; 110 | $fa-var-circle-thin: "\f1db"; 111 | $fa-var-clipboard: "\f0ea"; 112 | $fa-var-clock-o: "\f017"; 113 | $fa-var-cloud: "\f0c2"; 114 | $fa-var-cloud-download: "\f0ed"; 115 | $fa-var-cloud-upload: "\f0ee"; 116 | $fa-var-cny: "\f157"; 117 | $fa-var-code: "\f121"; 118 | $fa-var-code-fork: "\f126"; 119 | $fa-var-codepen: "\f1cb"; 120 | $fa-var-coffee: "\f0f4"; 121 | $fa-var-cog: "\f013"; 122 | $fa-var-cogs: "\f085"; 123 | $fa-var-columns: "\f0db"; 124 | $fa-var-comment: "\f075"; 125 | $fa-var-comment-o: "\f0e5"; 126 | $fa-var-comments: "\f086"; 127 | $fa-var-comments-o: "\f0e6"; 128 | $fa-var-compass: "\f14e"; 129 | $fa-var-compress: "\f066"; 130 | $fa-var-copy: "\f0c5"; 131 | $fa-var-credit-card: "\f09d"; 132 | $fa-var-crop: "\f125"; 133 | $fa-var-crosshairs: "\f05b"; 134 | $fa-var-css3: "\f13c"; 135 | $fa-var-cube: "\f1b2"; 136 | $fa-var-cubes: "\f1b3"; 137 | $fa-var-cut: "\f0c4"; 138 | $fa-var-cutlery: "\f0f5"; 139 | $fa-var-dashboard: "\f0e4"; 140 | $fa-var-database: "\f1c0"; 141 | $fa-var-dedent: "\f03b"; 142 | $fa-var-delicious: "\f1a5"; 143 | $fa-var-desktop: "\f108"; 144 | $fa-var-deviantart: "\f1bd"; 145 | $fa-var-digg: "\f1a6"; 146 | $fa-var-dollar: "\f155"; 147 | $fa-var-dot-circle-o: "\f192"; 148 | $fa-var-download: "\f019"; 149 | $fa-var-dribbble: "\f17d"; 150 | $fa-var-dropbox: "\f16b"; 151 | $fa-var-drupal: "\f1a9"; 152 | $fa-var-edit: "\f044"; 153 | $fa-var-eject: "\f052"; 154 | $fa-var-ellipsis-h: "\f141"; 155 | $fa-var-ellipsis-v: "\f142"; 156 | $fa-var-empire: "\f1d1"; 157 | $fa-var-envelope: "\f0e0"; 158 | $fa-var-envelope-o: "\f003"; 159 | $fa-var-envelope-square: "\f199"; 160 | $fa-var-eraser: "\f12d"; 161 | $fa-var-eur: "\f153"; 162 | $fa-var-euro: "\f153"; 163 | $fa-var-exchange: "\f0ec"; 164 | $fa-var-exclamation: "\f12a"; 165 | $fa-var-exclamation-circle: "\f06a"; 166 | $fa-var-exclamation-triangle: "\f071"; 167 | $fa-var-expand: "\f065"; 168 | $fa-var-external-link: "\f08e"; 169 | $fa-var-external-link-square: "\f14c"; 170 | $fa-var-eye: "\f06e"; 171 | $fa-var-eye-slash: "\f070"; 172 | $fa-var-facebook: "\f09a"; 173 | $fa-var-facebook-square: "\f082"; 174 | $fa-var-fast-backward: "\f049"; 175 | $fa-var-fast-forward: "\f050"; 176 | $fa-var-fax: "\f1ac"; 177 | $fa-var-female: "\f182"; 178 | $fa-var-fighter-jet: "\f0fb"; 179 | $fa-var-file: "\f15b"; 180 | $fa-var-file-archive-o: "\f1c6"; 181 | $fa-var-file-audio-o: "\f1c7"; 182 | $fa-var-file-code-o: "\f1c9"; 183 | $fa-var-file-excel-o: "\f1c3"; 184 | $fa-var-file-image-o: "\f1c5"; 185 | $fa-var-file-movie-o: "\f1c8"; 186 | $fa-var-file-o: "\f016"; 187 | $fa-var-file-pdf-o: "\f1c1"; 188 | $fa-var-file-photo-o: "\f1c5"; 189 | $fa-var-file-picture-o: "\f1c5"; 190 | $fa-var-file-powerpoint-o: "\f1c4"; 191 | $fa-var-file-sound-o: "\f1c7"; 192 | $fa-var-file-text: "\f15c"; 193 | $fa-var-file-text-o: "\f0f6"; 194 | $fa-var-file-video-o: "\f1c8"; 195 | $fa-var-file-word-o: "\f1c2"; 196 | $fa-var-file-zip-o: "\f1c6"; 197 | $fa-var-files-o: "\f0c5"; 198 | $fa-var-film: "\f008"; 199 | $fa-var-filter: "\f0b0"; 200 | $fa-var-fire: "\f06d"; 201 | $fa-var-fire-extinguisher: "\f134"; 202 | $fa-var-flag: "\f024"; 203 | $fa-var-flag-checkered: "\f11e"; 204 | $fa-var-flag-o: "\f11d"; 205 | $fa-var-flash: "\f0e7"; 206 | $fa-var-flask: "\f0c3"; 207 | $fa-var-flickr: "\f16e"; 208 | $fa-var-floppy-o: "\f0c7"; 209 | $fa-var-folder: "\f07b"; 210 | $fa-var-folder-o: "\f114"; 211 | $fa-var-folder-open: "\f07c"; 212 | $fa-var-folder-open-o: "\f115"; 213 | $fa-var-font: "\f031"; 214 | $fa-var-forward: "\f04e"; 215 | $fa-var-foursquare: "\f180"; 216 | $fa-var-frown-o: "\f119"; 217 | $fa-var-gamepad: "\f11b"; 218 | $fa-var-gavel: "\f0e3"; 219 | $fa-var-gbp: "\f154"; 220 | $fa-var-ge: "\f1d1"; 221 | $fa-var-gear: "\f013"; 222 | $fa-var-gears: "\f085"; 223 | $fa-var-gift: "\f06b"; 224 | $fa-var-git: "\f1d3"; 225 | $fa-var-git-square: "\f1d2"; 226 | $fa-var-github: "\f09b"; 227 | $fa-var-github-alt: "\f113"; 228 | $fa-var-github-square: "\f092"; 229 | $fa-var-gittip: "\f184"; 230 | $fa-var-glass: "\f000"; 231 | $fa-var-globe: "\f0ac"; 232 | $fa-var-google: "\f1a0"; 233 | $fa-var-google-plus: "\f0d5"; 234 | $fa-var-google-plus-square: "\f0d4"; 235 | $fa-var-graduation-cap: "\f19d"; 236 | $fa-var-group: "\f0c0"; 237 | $fa-var-h-square: "\f0fd"; 238 | $fa-var-hacker-news: "\f1d4"; 239 | $fa-var-hand-o-down: "\f0a7"; 240 | $fa-var-hand-o-left: "\f0a5"; 241 | $fa-var-hand-o-right: "\f0a4"; 242 | $fa-var-hand-o-up: "\f0a6"; 243 | $fa-var-hdd-o: "\f0a0"; 244 | $fa-var-header: "\f1dc"; 245 | $fa-var-headphones: "\f025"; 246 | $fa-var-heart: "\f004"; 247 | $fa-var-heart-o: "\f08a"; 248 | $fa-var-history: "\f1da"; 249 | $fa-var-home: "\f015"; 250 | $fa-var-hospital-o: "\f0f8"; 251 | $fa-var-html5: "\f13b"; 252 | $fa-var-image: "\f03e"; 253 | $fa-var-inbox: "\f01c"; 254 | $fa-var-indent: "\f03c"; 255 | $fa-var-info: "\f129"; 256 | $fa-var-info-circle: "\f05a"; 257 | $fa-var-inr: "\f156"; 258 | $fa-var-instagram: "\f16d"; 259 | $fa-var-institution: "\f19c"; 260 | $fa-var-italic: "\f033"; 261 | $fa-var-joomla: "\f1aa"; 262 | $fa-var-jpy: "\f157"; 263 | $fa-var-jsfiddle: "\f1cc"; 264 | $fa-var-key: "\f084"; 265 | $fa-var-keyboard-o: "\f11c"; 266 | $fa-var-krw: "\f159"; 267 | $fa-var-language: "\f1ab"; 268 | $fa-var-laptop: "\f109"; 269 | $fa-var-leaf: "\f06c"; 270 | $fa-var-legal: "\f0e3"; 271 | $fa-var-lemon-o: "\f094"; 272 | $fa-var-level-down: "\f149"; 273 | $fa-var-level-up: "\f148"; 274 | $fa-var-life-bouy: "\f1cd"; 275 | $fa-var-life-ring: "\f1cd"; 276 | $fa-var-life-saver: "\f1cd"; 277 | $fa-var-lightbulb-o: "\f0eb"; 278 | $fa-var-link: "\f0c1"; 279 | $fa-var-linkedin: "\f0e1"; 280 | $fa-var-linkedin-square: "\f08c"; 281 | $fa-var-linux: "\f17c"; 282 | $fa-var-list: "\f03a"; 283 | $fa-var-list-alt: "\f022"; 284 | $fa-var-list-ol: "\f0cb"; 285 | $fa-var-list-ul: "\f0ca"; 286 | $fa-var-location-arrow: "\f124"; 287 | $fa-var-lock: "\f023"; 288 | $fa-var-long-arrow-down: "\f175"; 289 | $fa-var-long-arrow-left: "\f177"; 290 | $fa-var-long-arrow-right: "\f178"; 291 | $fa-var-long-arrow-up: "\f176"; 292 | $fa-var-magic: "\f0d0"; 293 | $fa-var-magnet: "\f076"; 294 | $fa-var-mail-forward: "\f064"; 295 | $fa-var-mail-reply: "\f112"; 296 | $fa-var-mail-reply-all: "\f122"; 297 | $fa-var-male: "\f183"; 298 | $fa-var-map-marker: "\f041"; 299 | $fa-var-maxcdn: "\f136"; 300 | $fa-var-medkit: "\f0fa"; 301 | $fa-var-meh-o: "\f11a"; 302 | $fa-var-microphone: "\f130"; 303 | $fa-var-microphone-slash: "\f131"; 304 | $fa-var-minus: "\f068"; 305 | $fa-var-minus-circle: "\f056"; 306 | $fa-var-minus-square: "\f146"; 307 | $fa-var-minus-square-o: "\f147"; 308 | $fa-var-mobile: "\f10b"; 309 | $fa-var-mobile-phone: "\f10b"; 310 | $fa-var-money: "\f0d6"; 311 | $fa-var-moon-o: "\f186"; 312 | $fa-var-mortar-board: "\f19d"; 313 | $fa-var-music: "\f001"; 314 | $fa-var-navicon: "\f0c9"; 315 | $fa-var-openid: "\f19b"; 316 | $fa-var-outdent: "\f03b"; 317 | $fa-var-pagelines: "\f18c"; 318 | $fa-var-paper-plane: "\f1d8"; 319 | $fa-var-paper-plane-o: "\f1d9"; 320 | $fa-var-paperclip: "\f0c6"; 321 | $fa-var-paragraph: "\f1dd"; 322 | $fa-var-paste: "\f0ea"; 323 | $fa-var-pause: "\f04c"; 324 | $fa-var-paw: "\f1b0"; 325 | $fa-var-pencil: "\f040"; 326 | $fa-var-pencil-square: "\f14b"; 327 | $fa-var-pencil-square-o: "\f044"; 328 | $fa-var-phone: "\f095"; 329 | $fa-var-phone-square: "\f098"; 330 | $fa-var-photo: "\f03e"; 331 | $fa-var-picture-o: "\f03e"; 332 | $fa-var-pied-piper: "\f1a7"; 333 | $fa-var-pied-piper-alt: "\f1a8"; 334 | $fa-var-pied-piper-square: "\f1a7"; 335 | $fa-var-pinterest: "\f0d2"; 336 | $fa-var-pinterest-square: "\f0d3"; 337 | $fa-var-plane: "\f072"; 338 | $fa-var-play: "\f04b"; 339 | $fa-var-play-circle: "\f144"; 340 | $fa-var-play-circle-o: "\f01d"; 341 | $fa-var-plus: "\f067"; 342 | $fa-var-plus-circle: "\f055"; 343 | $fa-var-plus-square: "\f0fe"; 344 | $fa-var-plus-square-o: "\f196"; 345 | $fa-var-power-off: "\f011"; 346 | $fa-var-print: "\f02f"; 347 | $fa-var-puzzle-piece: "\f12e"; 348 | $fa-var-qq: "\f1d6"; 349 | $fa-var-qrcode: "\f029"; 350 | $fa-var-question: "\f128"; 351 | $fa-var-question-circle: "\f059"; 352 | $fa-var-quote-left: "\f10d"; 353 | $fa-var-quote-right: "\f10e"; 354 | $fa-var-ra: "\f1d0"; 355 | $fa-var-random: "\f074"; 356 | $fa-var-rebel: "\f1d0"; 357 | $fa-var-recycle: "\f1b8"; 358 | $fa-var-reddit: "\f1a1"; 359 | $fa-var-reddit-square: "\f1a2"; 360 | $fa-var-refresh: "\f021"; 361 | $fa-var-renren: "\f18b"; 362 | $fa-var-reorder: "\f0c9"; 363 | $fa-var-repeat: "\f01e"; 364 | $fa-var-reply: "\f112"; 365 | $fa-var-reply-all: "\f122"; 366 | $fa-var-retweet: "\f079"; 367 | $fa-var-rmb: "\f157"; 368 | $fa-var-road: "\f018"; 369 | $fa-var-rocket: "\f135"; 370 | $fa-var-rotate-left: "\f0e2"; 371 | $fa-var-rotate-right: "\f01e"; 372 | $fa-var-rouble: "\f158"; 373 | $fa-var-rss: "\f09e"; 374 | $fa-var-rss-square: "\f143"; 375 | $fa-var-rub: "\f158"; 376 | $fa-var-ruble: "\f158"; 377 | $fa-var-rupee: "\f156"; 378 | $fa-var-save: "\f0c7"; 379 | $fa-var-scissors: "\f0c4"; 380 | $fa-var-search: "\f002"; 381 | $fa-var-search-minus: "\f010"; 382 | $fa-var-search-plus: "\f00e"; 383 | $fa-var-send: "\f1d8"; 384 | $fa-var-send-o: "\f1d9"; 385 | $fa-var-share: "\f064"; 386 | $fa-var-share-alt: "\f1e0"; 387 | $fa-var-share-alt-square: "\f1e1"; 388 | $fa-var-share-square: "\f14d"; 389 | $fa-var-share-square-o: "\f045"; 390 | $fa-var-shield: "\f132"; 391 | $fa-var-shopping-cart: "\f07a"; 392 | $fa-var-sign-in: "\f090"; 393 | $fa-var-sign-out: "\f08b"; 394 | $fa-var-signal: "\f012"; 395 | $fa-var-sitemap: "\f0e8"; 396 | $fa-var-skype: "\f17e"; 397 | $fa-var-slack: "\f198"; 398 | $fa-var-sliders: "\f1de"; 399 | $fa-var-smile-o: "\f118"; 400 | $fa-var-sort: "\f0dc"; 401 | $fa-var-sort-alpha-asc: "\f15d"; 402 | $fa-var-sort-alpha-desc: "\f15e"; 403 | $fa-var-sort-amount-asc: "\f160"; 404 | $fa-var-sort-amount-desc: "\f161"; 405 | $fa-var-sort-asc: "\f0de"; 406 | $fa-var-sort-desc: "\f0dd"; 407 | $fa-var-sort-down: "\f0dd"; 408 | $fa-var-sort-numeric-asc: "\f162"; 409 | $fa-var-sort-numeric-desc: "\f163"; 410 | $fa-var-sort-up: "\f0de"; 411 | $fa-var-soundcloud: "\f1be"; 412 | $fa-var-space-shuttle: "\f197"; 413 | $fa-var-spinner: "\f110"; 414 | $fa-var-spoon: "\f1b1"; 415 | $fa-var-spotify: "\f1bc"; 416 | $fa-var-square: "\f0c8"; 417 | $fa-var-square-o: "\f096"; 418 | $fa-var-stack-exchange: "\f18d"; 419 | $fa-var-stack-overflow: "\f16c"; 420 | $fa-var-star: "\f005"; 421 | $fa-var-star-half: "\f089"; 422 | $fa-var-star-half-empty: "\f123"; 423 | $fa-var-star-half-full: "\f123"; 424 | $fa-var-star-half-o: "\f123"; 425 | $fa-var-star-o: "\f006"; 426 | $fa-var-steam: "\f1b6"; 427 | $fa-var-steam-square: "\f1b7"; 428 | $fa-var-step-backward: "\f048"; 429 | $fa-var-step-forward: "\f051"; 430 | $fa-var-stethoscope: "\f0f1"; 431 | $fa-var-stop: "\f04d"; 432 | $fa-var-strikethrough: "\f0cc"; 433 | $fa-var-stumbleupon: "\f1a4"; 434 | $fa-var-stumbleupon-circle: "\f1a3"; 435 | $fa-var-subscript: "\f12c"; 436 | $fa-var-suitcase: "\f0f2"; 437 | $fa-var-sun-o: "\f185"; 438 | $fa-var-superscript: "\f12b"; 439 | $fa-var-support: "\f1cd"; 440 | $fa-var-table: "\f0ce"; 441 | $fa-var-tablet: "\f10a"; 442 | $fa-var-tachometer: "\f0e4"; 443 | $fa-var-tag: "\f02b"; 444 | $fa-var-tags: "\f02c"; 445 | $fa-var-tasks: "\f0ae"; 446 | $fa-var-taxi: "\f1ba"; 447 | $fa-var-tencent-weibo: "\f1d5"; 448 | $fa-var-terminal: "\f120"; 449 | $fa-var-text-height: "\f034"; 450 | $fa-var-text-width: "\f035"; 451 | $fa-var-th: "\f00a"; 452 | $fa-var-th-large: "\f009"; 453 | $fa-var-th-list: "\f00b"; 454 | $fa-var-thumb-tack: "\f08d"; 455 | $fa-var-thumbs-down: "\f165"; 456 | $fa-var-thumbs-o-down: "\f088"; 457 | $fa-var-thumbs-o-up: "\f087"; 458 | $fa-var-thumbs-up: "\f164"; 459 | $fa-var-ticket: "\f145"; 460 | $fa-var-times: "\f00d"; 461 | $fa-var-times-circle: "\f057"; 462 | $fa-var-times-circle-o: "\f05c"; 463 | $fa-var-tint: "\f043"; 464 | $fa-var-toggle-down: "\f150"; 465 | $fa-var-toggle-left: "\f191"; 466 | $fa-var-toggle-right: "\f152"; 467 | $fa-var-toggle-up: "\f151"; 468 | $fa-var-trash-o: "\f014"; 469 | $fa-var-tree: "\f1bb"; 470 | $fa-var-trello: "\f181"; 471 | $fa-var-trophy: "\f091"; 472 | $fa-var-truck: "\f0d1"; 473 | $fa-var-try: "\f195"; 474 | $fa-var-tumblr: "\f173"; 475 | $fa-var-tumblr-square: "\f174"; 476 | $fa-var-turkish-lira: "\f195"; 477 | $fa-var-twitter: "\f099"; 478 | $fa-var-twitter-square: "\f081"; 479 | $fa-var-umbrella: "\f0e9"; 480 | $fa-var-underline: "\f0cd"; 481 | $fa-var-undo: "\f0e2"; 482 | $fa-var-university: "\f19c"; 483 | $fa-var-unlink: "\f127"; 484 | $fa-var-unlock: "\f09c"; 485 | $fa-var-unlock-alt: "\f13e"; 486 | $fa-var-unsorted: "\f0dc"; 487 | $fa-var-upload: "\f093"; 488 | $fa-var-usd: "\f155"; 489 | $fa-var-user: "\f007"; 490 | $fa-var-user-md: "\f0f0"; 491 | $fa-var-users: "\f0c0"; 492 | $fa-var-video-camera: "\f03d"; 493 | $fa-var-vimeo-square: "\f194"; 494 | $fa-var-vine: "\f1ca"; 495 | $fa-var-vk: "\f189"; 496 | $fa-var-volume-down: "\f027"; 497 | $fa-var-volume-off: "\f026"; 498 | $fa-var-volume-up: "\f028"; 499 | $fa-var-warning: "\f071"; 500 | $fa-var-wechat: "\f1d7"; 501 | $fa-var-weibo: "\f18a"; 502 | $fa-var-weixin: "\f1d7"; 503 | $fa-var-wheelchair: "\f193"; 504 | $fa-var-windows: "\f17a"; 505 | $fa-var-won: "\f159"; 506 | $fa-var-wordpress: "\f19a"; 507 | $fa-var-wrench: "\f0ad"; 508 | $fa-var-xing: "\f168"; 509 | $fa-var-xing-square: "\f169"; 510 | $fa-var-yahoo: "\f19e"; 511 | $fa-var-yen: "\f157"; 512 | $fa-var-youtube: "\f167"; 513 | $fa-var-youtube-play: "\f16a"; 514 | $fa-var-youtube-square: "\f166"; 515 | 516 | -------------------------------------------------------------------------------- /chrome/css/font-awesome-4.1.0/css/font-awesome.min.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome 4.1.0 by @davegandy - http://fontawesome.io - @fontawesome 3 | * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) 4 | */@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:normal;font-style:normal}.fa{display:inline-block;font-family:FontAwesome;font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571429em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14285714em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14285714em;width:2.14285714em;top:.14285714em;text-align:center}.fa-li.fa-lg{left:-1.85714286em}.fa-border{padding:.2em .25em .15em;border:solid .08em #eee;border-radius:.1em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left{margin-right:.3em}.fa.pull-right{margin-left:.3em}.fa-spin{-webkit-animation:spin 2s infinite linear;-moz-animation:spin 2s infinite linear;-o-animation:spin 2s infinite linear;animation:spin 2s infinite linear}@-moz-keyframes spin{0%{-moz-transform:rotate(0deg)}100%{-moz-transform:rotate(359deg)}}@-webkit-keyframes spin{0%{-webkit-transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg)}}@-o-keyframes spin{0%{-o-transform:rotate(0deg)}100%{-o-transform:rotate(359deg)}}@keyframes spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=1);-webkit-transform:rotate(90deg);-moz-transform:rotate(90deg);-ms-transform:rotate(90deg);-o-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2);-webkit-transform:rotate(180deg);-moz-transform:rotate(180deg);-ms-transform:rotate(180deg);-o-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=3);-webkit-transform:rotate(270deg);-moz-transform:rotate(270deg);-ms-transform:rotate(270deg);-o-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1);-webkit-transform:scale(-1, 1);-moz-transform:scale(-1, 1);-ms-transform:scale(-1, 1);-o-transform:scale(-1, 1);transform:scale(-1, 1)}.fa-flip-vertical{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1);-webkit-transform:scale(1, -1);-moz-transform:scale(1, -1);-ms-transform:scale(1, -1);-o-transform:scale(1, -1);transform:scale(1, -1)}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:"\f000"}.fa-music:before{content:"\f001"}.fa-search:before{content:"\f002"}.fa-envelope-o:before{content:"\f003"}.fa-heart:before{content:"\f004"}.fa-star:before{content:"\f005"}.fa-star-o:before{content:"\f006"}.fa-user:before{content:"\f007"}.fa-film:before{content:"\f008"}.fa-th-large:before{content:"\f009"}.fa-th:before{content:"\f00a"}.fa-th-list:before{content:"\f00b"}.fa-check:before{content:"\f00c"}.fa-times:before{content:"\f00d"}.fa-search-plus:before{content:"\f00e"}.fa-search-minus:before{content:"\f010"}.fa-power-off:before{content:"\f011"}.fa-signal:before{content:"\f012"}.fa-gear:before,.fa-cog:before{content:"\f013"}.fa-trash-o:before{content:"\f014"}.fa-home:before{content:"\f015"}.fa-file-o:before{content:"\f016"}.fa-clock-o:before{content:"\f017"}.fa-road:before{content:"\f018"}.fa-download:before{content:"\f019"}.fa-arrow-circle-o-down:before{content:"\f01a"}.fa-arrow-circle-o-up:before{content:"\f01b"}.fa-inbox:before{content:"\f01c"}.fa-play-circle-o:before{content:"\f01d"}.fa-rotate-right:before,.fa-repeat:before{content:"\f01e"}.fa-refresh:before{content:"\f021"}.fa-list-alt:before{content:"\f022"}.fa-lock:before{content:"\f023"}.fa-flag:before{content:"\f024"}.fa-headphones:before{content:"\f025"}.fa-volume-off:before{content:"\f026"}.fa-volume-down:before{content:"\f027"}.fa-volume-up:before{content:"\f028"}.fa-qrcode:before{content:"\f029"}.fa-barcode:before{content:"\f02a"}.fa-tag:before{content:"\f02b"}.fa-tags:before{content:"\f02c"}.fa-book:before{content:"\f02d"}.fa-bookmark:before{content:"\f02e"}.fa-print:before{content:"\f02f"}.fa-camera:before{content:"\f030"}.fa-font:before{content:"\f031"}.fa-bold:before{content:"\f032"}.fa-italic:before{content:"\f033"}.fa-text-height:before{content:"\f034"}.fa-text-width:before{content:"\f035"}.fa-align-left:before{content:"\f036"}.fa-align-center:before{content:"\f037"}.fa-align-right:before{content:"\f038"}.fa-align-justify:before{content:"\f039"}.fa-list:before{content:"\f03a"}.fa-dedent:before,.fa-outdent:before{content:"\f03b"}.fa-indent:before{content:"\f03c"}.fa-video-camera:before{content:"\f03d"}.fa-photo:before,.fa-image:before,.fa-picture-o:before{content:"\f03e"}.fa-pencil:before{content:"\f040"}.fa-map-marker:before{content:"\f041"}.fa-adjust:before{content:"\f042"}.fa-tint:before{content:"\f043"}.fa-edit:before,.fa-pencil-square-o:before{content:"\f044"}.fa-share-square-o:before{content:"\f045"}.fa-check-square-o:before{content:"\f046"}.fa-arrows:before{content:"\f047"}.fa-step-backward:before{content:"\f048"}.fa-fast-backward:before{content:"\f049"}.fa-backward:before{content:"\f04a"}.fa-play:before{content:"\f04b"}.fa-pause:before{content:"\f04c"}.fa-stop:before{content:"\f04d"}.fa-forward:before{content:"\f04e"}.fa-fast-forward:before{content:"\f050"}.fa-step-forward:before{content:"\f051"}.fa-eject:before{content:"\f052"}.fa-chevron-left:before{content:"\f053"}.fa-chevron-right:before{content:"\f054"}.fa-plus-circle:before{content:"\f055"}.fa-minus-circle:before{content:"\f056"}.fa-times-circle:before{content:"\f057"}.fa-check-circle:before{content:"\f058"}.fa-question-circle:before{content:"\f059"}.fa-info-circle:before{content:"\f05a"}.fa-crosshairs:before{content:"\f05b"}.fa-times-circle-o:before{content:"\f05c"}.fa-check-circle-o:before{content:"\f05d"}.fa-ban:before{content:"\f05e"}.fa-arrow-left:before{content:"\f060"}.fa-arrow-right:before{content:"\f061"}.fa-arrow-up:before{content:"\f062"}.fa-arrow-down:before{content:"\f063"}.fa-mail-forward:before,.fa-share:before{content:"\f064"}.fa-expand:before{content:"\f065"}.fa-compress:before{content:"\f066"}.fa-plus:before{content:"\f067"}.fa-minus:before{content:"\f068"}.fa-asterisk:before{content:"\f069"}.fa-exclamation-circle:before{content:"\f06a"}.fa-gift:before{content:"\f06b"}.fa-leaf:before{content:"\f06c"}.fa-fire:before{content:"\f06d"}.fa-eye:before{content:"\f06e"}.fa-eye-slash:before{content:"\f070"}.fa-warning:before,.fa-exclamation-triangle:before{content:"\f071"}.fa-plane:before{content:"\f072"}.fa-calendar:before{content:"\f073"}.fa-random:before{content:"\f074"}.fa-comment:before{content:"\f075"}.fa-magnet:before{content:"\f076"}.fa-chevron-up:before{content:"\f077"}.fa-chevron-down:before{content:"\f078"}.fa-retweet:before{content:"\f079"}.fa-shopping-cart:before{content:"\f07a"}.fa-folder:before{content:"\f07b"}.fa-folder-open:before{content:"\f07c"}.fa-arrows-v:before{content:"\f07d"}.fa-arrows-h:before{content:"\f07e"}.fa-bar-chart-o:before{content:"\f080"}.fa-twitter-square:before{content:"\f081"}.fa-facebook-square:before{content:"\f082"}.fa-camera-retro:before{content:"\f083"}.fa-key:before{content:"\f084"}.fa-gears:before,.fa-cogs:before{content:"\f085"}.fa-comments:before{content:"\f086"}.fa-thumbs-o-up:before{content:"\f087"}.fa-thumbs-o-down:before{content:"\f088"}.fa-star-half:before{content:"\f089"}.fa-heart-o:before{content:"\f08a"}.fa-sign-out:before{content:"\f08b"}.fa-linkedin-square:before{content:"\f08c"}.fa-thumb-tack:before{content:"\f08d"}.fa-external-link:before{content:"\f08e"}.fa-sign-in:before{content:"\f090"}.fa-trophy:before{content:"\f091"}.fa-github-square:before{content:"\f092"}.fa-upload:before{content:"\f093"}.fa-lemon-o:before{content:"\f094"}.fa-phone:before{content:"\f095"}.fa-square-o:before{content:"\f096"}.fa-bookmark-o:before{content:"\f097"}.fa-phone-square:before{content:"\f098"}.fa-twitter:before{content:"\f099"}.fa-facebook:before{content:"\f09a"}.fa-github:before{content:"\f09b"}.fa-unlock:before{content:"\f09c"}.fa-credit-card:before{content:"\f09d"}.fa-rss:before{content:"\f09e"}.fa-hdd-o:before{content:"\f0a0"}.fa-bullhorn:before{content:"\f0a1"}.fa-bell:before{content:"\f0f3"}.fa-certificate:before{content:"\f0a3"}.fa-hand-o-right:before{content:"\f0a4"}.fa-hand-o-left:before{content:"\f0a5"}.fa-hand-o-up:before{content:"\f0a6"}.fa-hand-o-down:before{content:"\f0a7"}.fa-arrow-circle-left:before{content:"\f0a8"}.fa-arrow-circle-right:before{content:"\f0a9"}.fa-arrow-circle-up:before{content:"\f0aa"}.fa-arrow-circle-down:before{content:"\f0ab"}.fa-globe:before{content:"\f0ac"}.fa-wrench:before{content:"\f0ad"}.fa-tasks:before{content:"\f0ae"}.fa-filter:before{content:"\f0b0"}.fa-briefcase:before{content:"\f0b1"}.fa-arrows-alt:before{content:"\f0b2"}.fa-group:before,.fa-users:before{content:"\f0c0"}.fa-chain:before,.fa-link:before{content:"\f0c1"}.fa-cloud:before{content:"\f0c2"}.fa-flask:before{content:"\f0c3"}.fa-cut:before,.fa-scissors:before{content:"\f0c4"}.fa-copy:before,.fa-files-o:before{content:"\f0c5"}.fa-paperclip:before{content:"\f0c6"}.fa-save:before,.fa-floppy-o:before{content:"\f0c7"}.fa-square:before{content:"\f0c8"}.fa-navicon:before,.fa-reorder:before,.fa-bars:before{content:"\f0c9"}.fa-list-ul:before{content:"\f0ca"}.fa-list-ol:before{content:"\f0cb"}.fa-strikethrough:before{content:"\f0cc"}.fa-underline:before{content:"\f0cd"}.fa-table:before{content:"\f0ce"}.fa-magic:before{content:"\f0d0"}.fa-truck:before{content:"\f0d1"}.fa-pinterest:before{content:"\f0d2"}.fa-pinterest-square:before{content:"\f0d3"}.fa-google-plus-square:before{content:"\f0d4"}.fa-google-plus:before{content:"\f0d5"}.fa-money:before{content:"\f0d6"}.fa-caret-down:before{content:"\f0d7"}.fa-caret-up:before{content:"\f0d8"}.fa-caret-left:before{content:"\f0d9"}.fa-caret-right:before{content:"\f0da"}.fa-columns:before{content:"\f0db"}.fa-unsorted:before,.fa-sort:before{content:"\f0dc"}.fa-sort-down:before,.fa-sort-desc:before{content:"\f0dd"}.fa-sort-up:before,.fa-sort-asc:before{content:"\f0de"}.fa-envelope:before{content:"\f0e0"}.fa-linkedin:before{content:"\f0e1"}.fa-rotate-left:before,.fa-undo:before{content:"\f0e2"}.fa-legal:before,.fa-gavel:before{content:"\f0e3"}.fa-dashboard:before,.fa-tachometer:before{content:"\f0e4"}.fa-comment-o:before{content:"\f0e5"}.fa-comments-o:before{content:"\f0e6"}.fa-flash:before,.fa-bolt:before{content:"\f0e7"}.fa-sitemap:before{content:"\f0e8"}.fa-umbrella:before{content:"\f0e9"}.fa-paste:before,.fa-clipboard:before{content:"\f0ea"}.fa-lightbulb-o:before{content:"\f0eb"}.fa-exchange:before{content:"\f0ec"}.fa-cloud-download:before{content:"\f0ed"}.fa-cloud-upload:before{content:"\f0ee"}.fa-user-md:before{content:"\f0f0"}.fa-stethoscope:before{content:"\f0f1"}.fa-suitcase:before{content:"\f0f2"}.fa-bell-o:before{content:"\f0a2"}.fa-coffee:before{content:"\f0f4"}.fa-cutlery:before{content:"\f0f5"}.fa-file-text-o:before{content:"\f0f6"}.fa-building-o:before{content:"\f0f7"}.fa-hospital-o:before{content:"\f0f8"}.fa-ambulance:before{content:"\f0f9"}.fa-medkit:before{content:"\f0fa"}.fa-fighter-jet:before{content:"\f0fb"}.fa-beer:before{content:"\f0fc"}.fa-h-square:before{content:"\f0fd"}.fa-plus-square:before{content:"\f0fe"}.fa-angle-double-left:before{content:"\f100"}.fa-angle-double-right:before{content:"\f101"}.fa-angle-double-up:before{content:"\f102"}.fa-angle-double-down:before{content:"\f103"}.fa-angle-left:before{content:"\f104"}.fa-angle-right:before{content:"\f105"}.fa-angle-up:before{content:"\f106"}.fa-angle-down:before{content:"\f107"}.fa-desktop:before{content:"\f108"}.fa-laptop:before{content:"\f109"}.fa-tablet:before{content:"\f10a"}.fa-mobile-phone:before,.fa-mobile:before{content:"\f10b"}.fa-circle-o:before{content:"\f10c"}.fa-quote-left:before{content:"\f10d"}.fa-quote-right:before{content:"\f10e"}.fa-spinner:before{content:"\f110"}.fa-circle:before{content:"\f111"}.fa-mail-reply:before,.fa-reply:before{content:"\f112"}.fa-github-alt:before{content:"\f113"}.fa-folder-o:before{content:"\f114"}.fa-folder-open-o:before{content:"\f115"}.fa-smile-o:before{content:"\f118"}.fa-frown-o:before{content:"\f119"}.fa-meh-o:before{content:"\f11a"}.fa-gamepad:before{content:"\f11b"}.fa-keyboard-o:before{content:"\f11c"}.fa-flag-o:before{content:"\f11d"}.fa-flag-checkered:before{content:"\f11e"}.fa-terminal:before{content:"\f120"}.fa-code:before{content:"\f121"}.fa-mail-reply-all:before,.fa-reply-all:before{content:"\f122"}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:"\f123"}.fa-location-arrow:before{content:"\f124"}.fa-crop:before{content:"\f125"}.fa-code-fork:before{content:"\f126"}.fa-unlink:before,.fa-chain-broken:before{content:"\f127"}.fa-question:before{content:"\f128"}.fa-info:before{content:"\f129"}.fa-exclamation:before{content:"\f12a"}.fa-superscript:before{content:"\f12b"}.fa-subscript:before{content:"\f12c"}.fa-eraser:before{content:"\f12d"}.fa-puzzle-piece:before{content:"\f12e"}.fa-microphone:before{content:"\f130"}.fa-microphone-slash:before{content:"\f131"}.fa-shield:before{content:"\f132"}.fa-calendar-o:before{content:"\f133"}.fa-fire-extinguisher:before{content:"\f134"}.fa-rocket:before{content:"\f135"}.fa-maxcdn:before{content:"\f136"}.fa-chevron-circle-left:before{content:"\f137"}.fa-chevron-circle-right:before{content:"\f138"}.fa-chevron-circle-up:before{content:"\f139"}.fa-chevron-circle-down:before{content:"\f13a"}.fa-html5:before{content:"\f13b"}.fa-css3:before{content:"\f13c"}.fa-anchor:before{content:"\f13d"}.fa-unlock-alt:before{content:"\f13e"}.fa-bullseye:before{content:"\f140"}.fa-ellipsis-h:before{content:"\f141"}.fa-ellipsis-v:before{content:"\f142"}.fa-rss-square:before{content:"\f143"}.fa-play-circle:before{content:"\f144"}.fa-ticket:before{content:"\f145"}.fa-minus-square:before{content:"\f146"}.fa-minus-square-o:before{content:"\f147"}.fa-level-up:before{content:"\f148"}.fa-level-down:before{content:"\f149"}.fa-check-square:before{content:"\f14a"}.fa-pencil-square:before{content:"\f14b"}.fa-external-link-square:before{content:"\f14c"}.fa-share-square:before{content:"\f14d"}.fa-compass:before{content:"\f14e"}.fa-toggle-down:before,.fa-caret-square-o-down:before{content:"\f150"}.fa-toggle-up:before,.fa-caret-square-o-up:before{content:"\f151"}.fa-toggle-right:before,.fa-caret-square-o-right:before{content:"\f152"}.fa-euro:before,.fa-eur:before{content:"\f153"}.fa-gbp:before{content:"\f154"}.fa-dollar:before,.fa-usd:before{content:"\f155"}.fa-rupee:before,.fa-inr:before{content:"\f156"}.fa-cny:before,.fa-rmb:before,.fa-yen:before,.fa-jpy:before{content:"\f157"}.fa-ruble:before,.fa-rouble:before,.fa-rub:before{content:"\f158"}.fa-won:before,.fa-krw:before{content:"\f159"}.fa-bitcoin:before,.fa-btc:before{content:"\f15a"}.fa-file:before{content:"\f15b"}.fa-file-text:before{content:"\f15c"}.fa-sort-alpha-asc:before{content:"\f15d"}.fa-sort-alpha-desc:before{content:"\f15e"}.fa-sort-amount-asc:before{content:"\f160"}.fa-sort-amount-desc:before{content:"\f161"}.fa-sort-numeric-asc:before{content:"\f162"}.fa-sort-numeric-desc:before{content:"\f163"}.fa-thumbs-up:before{content:"\f164"}.fa-thumbs-down:before{content:"\f165"}.fa-youtube-square:before{content:"\f166"}.fa-youtube:before{content:"\f167"}.fa-xing:before{content:"\f168"}.fa-xing-square:before{content:"\f169"}.fa-youtube-play:before{content:"\f16a"}.fa-dropbox:before{content:"\f16b"}.fa-stack-overflow:before{content:"\f16c"}.fa-instagram:before{content:"\f16d"}.fa-flickr:before{content:"\f16e"}.fa-adn:before{content:"\f170"}.fa-bitbucket:before{content:"\f171"}.fa-bitbucket-square:before{content:"\f172"}.fa-tumblr:before{content:"\f173"}.fa-tumblr-square:before{content:"\f174"}.fa-long-arrow-down:before{content:"\f175"}.fa-long-arrow-up:before{content:"\f176"}.fa-long-arrow-left:before{content:"\f177"}.fa-long-arrow-right:before{content:"\f178"}.fa-apple:before{content:"\f179"}.fa-windows:before{content:"\f17a"}.fa-android:before{content:"\f17b"}.fa-linux:before{content:"\f17c"}.fa-dribbble:before{content:"\f17d"}.fa-skype:before{content:"\f17e"}.fa-foursquare:before{content:"\f180"}.fa-trello:before{content:"\f181"}.fa-female:before{content:"\f182"}.fa-male:before{content:"\f183"}.fa-gittip:before{content:"\f184"}.fa-sun-o:before{content:"\f185"}.fa-moon-o:before{content:"\f186"}.fa-archive:before{content:"\f187"}.fa-bug:before{content:"\f188"}.fa-vk:before{content:"\f189"}.fa-weibo:before{content:"\f18a"}.fa-renren:before{content:"\f18b"}.fa-pagelines:before{content:"\f18c"}.fa-stack-exchange:before{content:"\f18d"}.fa-arrow-circle-o-right:before{content:"\f18e"}.fa-arrow-circle-o-left:before{content:"\f190"}.fa-toggle-left:before,.fa-caret-square-o-left:before{content:"\f191"}.fa-dot-circle-o:before{content:"\f192"}.fa-wheelchair:before{content:"\f193"}.fa-vimeo-square:before{content:"\f194"}.fa-turkish-lira:before,.fa-try:before{content:"\f195"}.fa-plus-square-o:before{content:"\f196"}.fa-space-shuttle:before{content:"\f197"}.fa-slack:before{content:"\f198"}.fa-envelope-square:before{content:"\f199"}.fa-wordpress:before{content:"\f19a"}.fa-openid:before{content:"\f19b"}.fa-institution:before,.fa-bank:before,.fa-university:before{content:"\f19c"}.fa-mortar-board:before,.fa-graduation-cap:before{content:"\f19d"}.fa-yahoo:before{content:"\f19e"}.fa-google:before{content:"\f1a0"}.fa-reddit:before{content:"\f1a1"}.fa-reddit-square:before{content:"\f1a2"}.fa-stumbleupon-circle:before{content:"\f1a3"}.fa-stumbleupon:before{content:"\f1a4"}.fa-delicious:before{content:"\f1a5"}.fa-digg:before{content:"\f1a6"}.fa-pied-piper-square:before,.fa-pied-piper:before{content:"\f1a7"}.fa-pied-piper-alt:before{content:"\f1a8"}.fa-drupal:before{content:"\f1a9"}.fa-joomla:before{content:"\f1aa"}.fa-language:before{content:"\f1ab"}.fa-fax:before{content:"\f1ac"}.fa-building:before{content:"\f1ad"}.fa-child:before{content:"\f1ae"}.fa-paw:before{content:"\f1b0"}.fa-spoon:before{content:"\f1b1"}.fa-cube:before{content:"\f1b2"}.fa-cubes:before{content:"\f1b3"}.fa-behance:before{content:"\f1b4"}.fa-behance-square:before{content:"\f1b5"}.fa-steam:before{content:"\f1b6"}.fa-steam-square:before{content:"\f1b7"}.fa-recycle:before{content:"\f1b8"}.fa-automobile:before,.fa-car:before{content:"\f1b9"}.fa-cab:before,.fa-taxi:before{content:"\f1ba"}.fa-tree:before{content:"\f1bb"}.fa-spotify:before{content:"\f1bc"}.fa-deviantart:before{content:"\f1bd"}.fa-soundcloud:before{content:"\f1be"}.fa-database:before{content:"\f1c0"}.fa-file-pdf-o:before{content:"\f1c1"}.fa-file-word-o:before{content:"\f1c2"}.fa-file-excel-o:before{content:"\f1c3"}.fa-file-powerpoint-o:before{content:"\f1c4"}.fa-file-photo-o:before,.fa-file-picture-o:before,.fa-file-image-o:before{content:"\f1c5"}.fa-file-zip-o:before,.fa-file-archive-o:before{content:"\f1c6"}.fa-file-sound-o:before,.fa-file-audio-o:before{content:"\f1c7"}.fa-file-movie-o:before,.fa-file-video-o:before{content:"\f1c8"}.fa-file-code-o:before{content:"\f1c9"}.fa-vine:before{content:"\f1ca"}.fa-codepen:before{content:"\f1cb"}.fa-jsfiddle:before{content:"\f1cc"}.fa-life-bouy:before,.fa-life-saver:before,.fa-support:before,.fa-life-ring:before{content:"\f1cd"}.fa-circle-o-notch:before{content:"\f1ce"}.fa-ra:before,.fa-rebel:before{content:"\f1d0"}.fa-ge:before,.fa-empire:before{content:"\f1d1"}.fa-git-square:before{content:"\f1d2"}.fa-git:before{content:"\f1d3"}.fa-hacker-news:before{content:"\f1d4"}.fa-tencent-weibo:before{content:"\f1d5"}.fa-qq:before{content:"\f1d6"}.fa-wechat:before,.fa-weixin:before{content:"\f1d7"}.fa-send:before,.fa-paper-plane:before{content:"\f1d8"}.fa-send-o:before,.fa-paper-plane-o:before{content:"\f1d9"}.fa-history:before{content:"\f1da"}.fa-circle-thin:before{content:"\f1db"}.fa-header:before{content:"\f1dc"}.fa-paragraph:before{content:"\f1dd"}.fa-sliders:before{content:"\f1de"}.fa-share-alt:before{content:"\f1e0"}.fa-share-alt-square:before{content:"\f1e1"}.fa-bomb:before{content:"\f1e2"} --------------------------------------------------------------------------------