├── .npmignore ├── .github └── screenshots │ └── window.png ├── src ├── index.js ├── ui │ ├── index.js │ ├── ToolBar.js │ ├── ProcessTableHeader.js │ ├── ProcessRow.js │ ├── ProcessTable.js │ └── ProcessManager.js ├── ProcessManager.js └── ProcessManagerWindow.js ├── example ├── package.json ├── index.html └── main.js ├── process-manager.html ├── webpack.config.js ├── tests └── test.js ├── .gitignore ├── package.json ├── README.md └── vendor └── photon.css /.npmignore: -------------------------------------------------------------------------------- 1 | /.git 2 | /example 3 | npm-debug.log 4 | node_modules 5 | -------------------------------------------------------------------------------- /.github/screenshots/window.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/getstation/electron-process-manager/HEAD/.github/screenshots/window.png -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | var ProcessManager = require('./ProcessManager.js'); 2 | 3 | // singleton 4 | module.exports = new ProcessManager(); 5 | -------------------------------------------------------------------------------- /src/ui/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { render } from 'react-dom'; 3 | 4 | import ProcessManager from './ProcessManager'; 5 | 6 | render(, document.getElementById('app')); 7 | -------------------------------------------------------------------------------- /example/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "electron-process-manager-example-app", 3 | "version": "0.0.1", 4 | "description": "An example application for electron-process-manager module", 5 | "main": "main.js", 6 | "private": true 7 | } 8 | -------------------------------------------------------------------------------- /process-manager.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Process Manager 6 | 7 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /example/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Example 6 | 7 | 8 | We are using Node.js , 9 | Chromium , 10 | and Electron . 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | const webpack = require('webpack'); 2 | const path = require('path'); 3 | 4 | const BUILD_DIR = path.resolve(__dirname, 'dist'); 5 | 6 | const config = { 7 | entry: path.resolve(__dirname, 'src/ui/index.js'), 8 | target: 'electron-renderer', 9 | output: { 10 | path: BUILD_DIR, 11 | filename: 'ui-bundle.js' 12 | }, 13 | module: { 14 | rules: [ 15 | { 16 | test: /\.(jsx|js)?$/, 17 | include: path.resolve(__dirname, 'src/ui'), 18 | use: [ 19 | { 20 | loader: 'babel-loader', 21 | options: { 22 | presets: [ 23 | '@babel/preset-env', 24 | '@babel/preset-react' 25 | ], 26 | } 27 | } 28 | ] 29 | } 30 | ] 31 | }, 32 | }; 33 | 34 | module.exports = config; 35 | -------------------------------------------------------------------------------- /src/ui/ToolBar.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | 4 | export default class ToolBar extends React.Component { 5 | 6 | static propTypes = { 7 | onKillClick: PropTypes.func, 8 | disableKill: PropTypes.bool, 9 | onOpenDevToolClick: PropTypes.func, 10 | disabelOpenDevTool: PropTypes.bool 11 | } 12 | 13 | render() { 14 | return ( 15 |
16 |
17 | 24 | 31 |
32 |
33 | ) 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /tests/test.js: -------------------------------------------------------------------------------- 1 | /* 2 | vk: the test works for Electron 9 + Spectron 11 3 | */ 4 | const Application = require('spectron').Application; 5 | const { join } = require('path'); 6 | const assert = require('assert'); 7 | 8 | const app = new Application({ 9 | env: { TEST_PROCESS_MANAGER: 1 }, 10 | path: require(join(__dirname, '../node_modules/electron')), 11 | args: [join(__dirname, '../example/main.js')] 12 | }); 13 | 14 | 15 | app.start() 16 | .then(() => app.client.waitUntilWindowLoaded()) 17 | .then(() => app.electron.ipcRenderer.send('open-process-manager')) 18 | .then(() => app.client.waitUntilWindowLoaded()) 19 | .then(() => assert(app.client.getWindowCount(), 2)) 20 | .then(() => app.client.switchWindow(/process-manager\.html/)) 21 | // .then(() => app.client.waitForVisible('#app .process-table')) 22 | .then(() => app.client.$('#app .process-table')) 23 | .then(element => element.waitForDisplayed()) 24 | .then(() => app.stop()) 25 | .catch(function (error) { 26 | console.error('Test failed', error); 27 | if (app && app.isRunning()) { 28 | app.stop().then(() => process.exit(1)) 29 | } else process.exit(1); 30 | }); 31 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | 8 | # Runtime data 9 | pids 10 | *.pid 11 | *.seed 12 | *.pid.lock 13 | 14 | # Directory for instrumented libs generated by jscoverage/JSCover 15 | lib-cov 16 | 17 | # Coverage directory used by tools like istanbul 18 | coverage 19 | 20 | # nyc test coverage 21 | .nyc_output 22 | 23 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 24 | .grunt 25 | 26 | # Bower dependency directory (https://bower.io/) 27 | bower_components 28 | 29 | # node-waf configuration 30 | .lock-wscript 31 | 32 | # Compiled binary addons (http://nodejs.org/api/addons.html) 33 | build/Release 34 | 35 | # Dependency directories 36 | node_modules/ 37 | jspm_packages/ 38 | package-lock.json 39 | 40 | # Typescript v1 declaration files 41 | typings/ 42 | 43 | # Optional npm cache directory 44 | .npm 45 | 46 | # Optional eslint cache 47 | .eslintcache 48 | 49 | # Optional REPL history 50 | .node_repl_history 51 | 52 | # Output of 'npm pack' 53 | *.tgz 54 | 55 | # Yarn Integrity file 56 | .yarn-integrity 57 | 58 | # dotenv environment variables file 59 | .env 60 | 61 | dist 62 | /.idea 63 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "electron-process-manager", 3 | "version": "1.2.0", 4 | "description": "Process manager UI for Electron applications", 5 | "repository": "getstation/electron-process-manager", 6 | "main": "src/index.js", 7 | "scripts": { 8 | "dev": "webpack -d --watch", 9 | "build": "webpack", 10 | "example": "npm run build && electron example", 11 | "test": "npm run build && node tests/test.js", 12 | "prepare": "npm run build" 13 | }, 14 | "author": "", 15 | "license": "MIT", 16 | "devDependencies": { 17 | "@babel/core": "^7.7.7", 18 | "@babel/preset-env": "^7.7.1", 19 | "@babel/preset-react": "^7.7.0", 20 | "babel-loader": "^8.0.6", 21 | "bluebird": "^3.7.1", 22 | "bluebird-extra": "^2.0.0", 23 | "electron": "^9", 24 | "electron-default-menu": "^1.0.2", 25 | "filesize": "^5.0.3", 26 | "format-number": "^3.0.0", 27 | "object-path": "^0.11.4", 28 | "prop-types": "^15.8.1", 29 | "react": "^16.14.0", 30 | "react-dom": "^16.14.0", 31 | "spectron": "^11", 32 | "webpack": "^4.47.0", 33 | "webpack-cli": "^3.3.12" 34 | }, 35 | "dependencies": { 36 | "@getstation/electron-process-reporter": "^2.0.0" 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/ProcessManager.js: -------------------------------------------------------------------------------- 1 | const { EventEmitter } = require('events'); 2 | const process = require('process'); 3 | const { webContents } = require('electron'); 4 | 5 | var ProcessManagerWindow = require('./ProcessManagerWindow.js'); 6 | 7 | const defaultOptions = { defaultSorting: { path: null, how: null } }; 8 | 9 | class ProcessManager extends EventEmitter { 10 | 11 | constructor() { 12 | super(); 13 | // legacy 14 | this.openProcessManager = this.open.bind(this); 15 | } 16 | 17 | open (options = defaultOptions) { 18 | if (this.window) { 19 | this.window.focus(); 20 | } 21 | 22 | this.window = new ProcessManagerWindow(options); 23 | this.window.showWhenReady(); 24 | this.window.on('kill-process', pid => this.killProcess(pid)) 25 | this.window.on('open-dev-tools', webContentsId => this.openDevTools(webContentsId)) 26 | this.window.on('closed', () => this.window = null) 27 | this.emit('open-window', this.window); 28 | 29 | return this.window; 30 | } 31 | 32 | 33 | killProcess(pid) { 34 | this.emit('will-kill-process', pid, this.window); 35 | process.kill(pid); 36 | this.emit('killed-process', pid, this.window); 37 | } 38 | 39 | openDevTools(webContentsId) { 40 | this.emit('will-open-dev-tools', webContentsId, this.window); 41 | 42 | const wc = webContents.fromId(webContentsId); 43 | wc.openDevTools({ mode: 'detach' }); 44 | 45 | this.emit('did-open-dev-tools', webContentsId, this.window); 46 | } 47 | 48 | } 49 | 50 | module.exports = ProcessManager; 51 | -------------------------------------------------------------------------------- /src/ui/ProcessTableHeader.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | 4 | 5 | export default class ProcessTableHeader extends React.Component { 6 | constructor(props) { 7 | super(props); 8 | this.handleClick = this.handleClick.bind(this); 9 | } 10 | static propTypes = { 11 | children: PropTypes.node, 12 | path: PropTypes.string.isRequired, 13 | sorting: PropTypes.PropTypes.shape({ 14 | path: PropTypes.string, 15 | how: PropTypes.string 16 | }), 17 | onSortingChange: PropTypes.func 18 | } 19 | 20 | getSortCharacter() { 21 | if (!this.sortHow) return ( 22 |   23 | ); 24 | return this.sortHow == 'ascending' ? '👆' : '👇' 25 | } 26 | 27 | get sortHow() { 28 | if (!this.props.sorting) return null; 29 | 30 | if (this.props.sorting.path == this.props.path){ 31 | return this.props.sorting.how; 32 | } 33 | return null; 34 | } 35 | 36 | handleClick() { 37 | let nextSortHow = null; 38 | if(this.sortHow === null) { 39 | nextSortHow = 'ascending'; 40 | } else if (this.sortHow === 'ascending') { 41 | nextSortHow = 'descending'; 42 | } else { 43 | nextSortHow = null; 44 | } 45 | this.props.onSortingChange({ 46 | path: this.props.path, 47 | how: nextSortHow 48 | }); 49 | } 50 | render() { 51 | return ( 52 | 53 | {this.props.children} 54 |   55 | {this.getSortCharacter()} 56 | 57 | ) 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /example/main.js: -------------------------------------------------------------------------------- 1 | var { app, shell, BrowserWindow, Menu, ipcMain } = require('electron'); 2 | var join = require('path').join; 3 | 4 | var processManager = require('..'); 5 | const defaultMenu = require('electron-default-menu'); 6 | 7 | processManager.on('killed-process', pid => console.log('Killed process', pid)); 8 | 9 | app.once('window-all-closed', function () { app.quit(); }); 10 | 11 | app.once('ready', function () { 12 | var w = new BrowserWindow({ 13 | webPreferences: { 14 | nodeIntegration: true, 15 | webviewTag: true, 16 | contextIsolation: false, 17 | }, 18 | }); 19 | w.once('closed', function () { w = null; }); 20 | w.loadURL('file://' + join(__dirname, 'index.html')); 21 | 22 | const menu = 23 | defaultMenu(app, shell) 24 | .map(menu => { 25 | if (menu.label === 'Window') { 26 | menu.submenu.push({ 27 | label: 'Open Process Manager', 28 | click: () => processManager.open({ 29 | defaultSorting: { 30 | path: 'cpu.percentCPUUsage', 31 | how: 'descending' 32 | } 33 | }) 34 | }) 35 | } 36 | return menu; 37 | }); 38 | 39 | Menu.setApplicationMenu(Menu.buildFromTemplate(menu)); 40 | }); 41 | 42 | if (process.env.TEST_PROCESS_MANAGER) { 43 | // emulate click on menu item 44 | ipcMain.on('open-process-manager', () => processManager.open()); 45 | 46 | process.on('uncaughtException', function (error) { 47 | console.error(error, error.stack); 48 | process.exit(1); 49 | }); 50 | 51 | } 52 | -------------------------------------------------------------------------------- /src/ui/ProcessRow.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import filesize from 'filesize'; 4 | import format from 'format-number'; 5 | 6 | const KB = 1024; 7 | const formatPercentage = format({ 8 | round: 1, 9 | padRight: 1 10 | }); 11 | 12 | export default class ProcessRow extends React.Component { 13 | static propTypes = { 14 | pid: PropTypes.number, 15 | type: PropTypes.string, 16 | memory: PropTypes.shape({ 17 | peakWorkingSetSize: PropTypes.number, 18 | workingSetSize: PropTypes.number 19 | }), 20 | cpu: PropTypes.shape({ 21 | percentCPUUsage: PropTypes.number, 22 | idleWakeupsPerSecond: PropTypes.number 23 | }), 24 | webContents: PropTypes.arrayOf(PropTypes.shape({ 25 | id: PropTypes.number, 26 | type: PropTypes.string, 27 | URL: PropTypes.string, 28 | URLDomain: PropTypes.string 29 | })), 30 | selected: PropTypes.bool, 31 | onSelect: PropTypes.func 32 | } 33 | 34 | render() { 35 | const { webContents, memory } = this.props; 36 | if (!webContents || webContents.length === 0) { 37 | return ( 38 | 42 | {this.props.pid} 43 | 44 | {this.props.type} 45 | {memory ? filesize(memory.workingSetSize*KB) : 'N/A'} 46 | {formatPercentage(this.props.cpu.percentCPUUsage)} 47 | {this.props.cpu.idleWakeupsPerSecond} 48 | 49 | 50 | 51 | 52 | ) 53 | } else { 54 | // FIX ME: we consider we have only have 1 webContents per process 55 | const wc = webContents[0]; 56 | 57 | return ( 58 | 62 | {this.props.pid} 63 | {wc.URLDomain} 64 | {this.props.type} 65 | {memory ? filesize(memory.workingSetSize*KB) : 'N/A'} 66 | {formatPercentage(this.props.cpu.percentCPUUsage)} 67 | {this.props.cpu.idleWakeupsPerSecond} 68 | {wc.id} 69 | {wc.type} 70 | {wc.URL} 71 | 72 | ) 73 | } 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /src/ProcessManagerWindow.js: -------------------------------------------------------------------------------- 1 | const { app, BrowserWindow, ipcMain } = require('electron'); 2 | const path = require('path'); 3 | const { onExtendedProcessMetrics } = require('@getstation/electron-process-reporter'); 4 | 5 | class ProcessManagerWindow extends BrowserWindow { 6 | 7 | constructor(options) { 8 | const winOptions = Object.assign({ 9 | width: 800, 10 | height: 300, 11 | useContentSize: true, 12 | webPreferences: { 13 | nodeIntegration: true, 14 | contextIsolation: false, 15 | } 16 | }, options || {}); 17 | 18 | super(winOptions); 19 | this.options = options; 20 | 21 | this.attachProcessReporter(); 22 | 23 | const indexHtml = 'file://' + path.join(__dirname, '..', 'process-manager.html'); 24 | this.loadURL(indexHtml); 25 | } 26 | 27 | showWhenReady = () => { 28 | this.once('ready-to-show', () => { 29 | this.show(); 30 | }); 31 | } 32 | 33 | sendStatsReport = (reportData) => { 34 | if (!this.webContents) return; 35 | this.webContents.send('process-manager:data', reportData); 36 | } 37 | 38 | openDevTools = () => { 39 | this.webContents.openDevTools(); 40 | } 41 | 42 | onOpenDevTools = (e, webContentsId) => { 43 | // ignore if not for us 44 | if (!this || this.isDestroyed()) return; 45 | if (e.sender !== this.webContents) return; 46 | 47 | this.emit('open-dev-tools', webContentsId); 48 | } 49 | 50 | onKillProcess = (e, pid) => { 51 | // ignore if not for us 52 | if (!this || this.isDestroyed()) return; 53 | if (e.sender !== this.webContents) return; 54 | 55 | this.emit('kill-process', pid); 56 | } 57 | 58 | attachProcessReporter = () => { 59 | this.subscription = onExtendedProcessMetrics(app) 60 | .subscribe(report => this.sendStatsReport(report)) 61 | ipcMain.on('process-manager:kill-process', this.onKillProcess); 62 | ipcMain.on('process-manager:open-dev-tools', this.onOpenDevTools); 63 | ipcMain.handle('process-manager:defaultSorting', () => { 64 | return this.options.defaultSorting; 65 | }); 66 | 67 | this.on('closed', () => { 68 | if (this.subscription) { 69 | this.subscription.unsubscribe(); 70 | } 71 | ipcMain.removeHandler('process-manager:defaultSorting'); 72 | ipcMain.off('process-manager:kill-process', this.onKillProcess); 73 | ipcMain.off('process-manager:open-dev-tools', this.onOpenDevTools); 74 | }); 75 | } 76 | } 77 | 78 | module.exports = ProcessManagerWindow; 79 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Process Manager UI for Electron Apps 2 | 3 | This package provides a process manager UI for Electron applications. 4 | 5 | It opens a window displaying a table of every processes run by the Electron application with information (type, URL for `webContents`, memory..). 6 | 7 | [![npm version](https://badge.fury.io/js/electron-process-manager.svg)](https://badge.fury.io/js/electron-process-manager) 8 | 9 | ![screenshot](https://github.com/getstation/electron-process-manager/raw/master/.github/screenshots/window.png) 10 | 11 | :warning: For `@electron>=3.0.0, <7.x`, use version `0.7.1` of this package. 12 | For versions `>=7.x`, use latest. 13 | 14 | It can be useful to debug performance of an app with several `webview`. 15 | 16 | It's inspired from Chrome's task manager. 17 | 18 | ## Features 19 | 20 | - [ ] Memory reporting 21 | - [ ] Link memory data to web-contents (for electron >=1.7.1) 22 | - [x] Kill a process from the UI 23 | - [x] Open developer tools for a given process 24 | - [x] CPU metrics 25 | - [x] Sort by columns 26 | 27 | ⚠️ Unfortunately, memory info are no longer available in Electron>=4 (see [electron/electron#16179](https://github.com/electron/electron/issues/16179)) 28 | 29 | ## Installation 30 | 31 | ```bash 32 | $ npm install electron-process-manager 33 | ``` 34 | 35 | ## Usage 36 | ```js 37 | const { openProcessManager } = require('electron-process-manager'); 38 | 39 | openProcessManager(); 40 | ``` 41 | 42 | ## Options 43 | `openProcessManager` function can take options in paramters 44 | 45 | #### options.defaultSorting 46 | **defaultSorting.how**: `'ascending' | 'descending'` 47 | 48 | **defaultSorting.path**: 49 | 50 | | Field name | path | 51 | |--------------------|----------------------------| 52 | | Pid | 'pid' | 53 | | WebContents Domain | 'webContents.0.URLDomain' | 54 | | Process Type | 'webContents.0.type' | 55 | | Private Memory | 'memory.privateBytes' | 56 | | Shared Memory | 'memory.sharedBytes' | 57 | | Working Set Size | 'memory.workingSetSize' | 58 | | % CPU | 'cpu.percentCPUUsage' | 59 | | Idle Wake Ups /s | 'cpu.idleWakeupsPerSecond' | 60 | | WebContents Id | 'webContents.0.id' | 61 | | WebContents Type | 'webContents.0.type' | 62 | | WebContents URL | 'webContents.0.URL' | 63 | 64 | example: 65 | ```js 66 | const { openProcessManager } = require('electron-process-manager'); 67 | 68 | openProcessManager({ how: 'descending', path: 'cpu.percentCPUUsage' }); 69 | ``` 70 | 71 | ## Future 72 | 73 | - Add physical memory (noted as "Memory" in Chrome's task manager) 74 | - Add networks metrics 75 | 76 | Pull requests welcome :) 77 | 78 | ## License 79 | 80 | MIT License 81 | -------------------------------------------------------------------------------- /src/ui/ProcessTable.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | 4 | import ProcessRow from './ProcessRow'; 5 | import ProcessTableHeader from './ProcessTableHeader'; 6 | 7 | export default class ProcessTable extends React.Component { 8 | static propTypes = { 9 | processData: PropTypes.arrayOf(PropTypes.object), 10 | selectedPid: PropTypes.number, 11 | sorting: PropTypes.PropTypes.shape({ 12 | path: PropTypes.string, 13 | how: PropTypes.string 14 | }), 15 | onSortingChange: PropTypes.func, 16 | onSelectedPidChange: PropTypes.func 17 | } 18 | 19 | render() { 20 | return ( 21 | 22 | 23 | 24 | Pid 29 | 30 | WebContents Domain 35 | 36 | Process Type 41 | 42 | Working Set Size 47 | 48 | % CPU 53 | 54 | Idle Wake Ups /s 59 | 60 | WebContents Id 65 | 66 | WebContents Type 71 | 72 | WebContents URL 77 | 78 | 79 | 80 | { 81 | this.props.processData.map(p => 82 | this.props.onSelectedPidChange(p.pid)} 86 | selected={this.props.selectedPid === p.pid} 87 | /> 88 | ) 89 | } 90 | 91 |
92 | ) 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /src/ui/ProcessManager.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { ipcRenderer } from 'electron'; 3 | import objectPath from 'object-path'; 4 | 5 | import ProcessTable from './ProcessTable'; 6 | import ToolBar from './ToolBar'; 7 | 8 | export default class ProcessManager extends React.Component { 9 | 10 | constructor(props) { 11 | super(props); 12 | this.state = { 13 | processData: null, 14 | selectedPid: null, 15 | sorting: { 16 | path: null, 17 | how: null 18 | } 19 | }; 20 | } 21 | 22 | UNSAFE_componentWillMount() { 23 | ipcRenderer.invoke('process-manager:defaultSorting') 24 | .then(defaultSorting => { 25 | this.setState({ sorting: defaultSorting }) 26 | }); 27 | ipcRenderer.on('process-manager:data', (_, data) => { 28 | this.setState({ processData: data }); 29 | }) 30 | } 31 | 32 | canKill() { 33 | if (!this.state.selectedPid) return false; 34 | const pids = this.state.processData.map(p => p.pid); 35 | 36 | // verify that select pid is in list of processes 37 | return pids.indexOf(this.state.selectedPid) !== -1; 38 | } 39 | 40 | canOpenDevTool() { 41 | return this.canKill() && this.getWebContentsIdForSelectedProcess() !== null; 42 | } 43 | 44 | getWebContentsIdForSelectedProcess() { 45 | const { processData, selectedPid } = this.state; 46 | if (!selectedPid) return null; 47 | 48 | const process = processData.find(p => p.pid === selectedPid); 49 | if (!process || !process.webContents || process.webContents.length === 0) return null; 50 | 51 | return process.webContents[0].id; 52 | } 53 | 54 | handleKillProcess() { 55 | const pid = this.state.selectedPid; 56 | if (!pid) return; 57 | ipcRenderer.send('process-manager:kill-process', pid); 58 | } 59 | 60 | handleOpenDevTool() { 61 | const webContentsId = this.getWebContentsIdForSelectedProcess(); 62 | ipcRenderer.send('process-manager:open-dev-tools', webContentsId); 63 | } 64 | 65 | getProcessData() { 66 | const { processData, sorting } = this.state; 67 | 68 | if (!sorting.path || !sorting.how) return processData; 69 | 70 | return processData.sort((p1, p2) => { 71 | const p1Metric = objectPath.get(p1, sorting.path); 72 | const p2Metric = objectPath.get(p2, sorting.path); 73 | 74 | if (p1Metric === p2Metric) return 0; 75 | const comp = p1Metric < p2Metric ? -1 : 1; 76 | 77 | return sorting.how == 'ascending' ? comp : -comp; 78 | }); 79 | } 80 | 81 | render () { 82 | const { processData } = this.state; 83 | if (!processData) return (No data); 84 | 85 | return ( 86 |
87 |
88 | 95 |
96 |
97 | this.setState({ sorting })} 102 | onSelectedPidChange={pid => this.setState({ selectedPid: pid })} 103 | /> 104 |
105 |
106 | ) 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /vendor/photon.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * ===================================================== 3 | * Photon v0.1.2 4 | * Copyright 2015 Connor Sears 5 | * Licensed under MIT (https://github.com/connors/proton/blob/master/LICENSE) 6 | * 7 | * v0.1.2 designed by @connors. 8 | * ===================================================== 9 | */ 10 | 11 | @charset "UTF-8"; 12 | audio, 13 | canvas, 14 | progress, 15 | video { 16 | vertical-align: baseline; 17 | } 18 | 19 | audio:not([controls]) { 20 | display: none; 21 | } 22 | 23 | a:active, 24 | a:hover { 25 | outline: 0; 26 | } 27 | 28 | abbr[title] { 29 | border-bottom: 1px dotted; 30 | } 31 | 32 | b, 33 | strong { 34 | font-weight: bold; 35 | } 36 | 37 | dfn { 38 | font-style: italic; 39 | } 40 | 41 | h1 { 42 | font-size: 2em; 43 | margin: 0.67em 0; 44 | } 45 | 46 | small { 47 | font-size: 80%; 48 | } 49 | 50 | sub, 51 | sup { 52 | font-size: 75%; 53 | line-height: 0; 54 | position: relative; 55 | vertical-align: baseline; 56 | } 57 | 58 | sup { 59 | top: -0.5em; 60 | } 61 | 62 | sub { 63 | bottom: -0.25em; 64 | } 65 | 66 | pre { 67 | overflow: auto; 68 | } 69 | 70 | code, 71 | kbd, 72 | pre, 73 | samp { 74 | font-family: monospace, monospace; 75 | font-size: 1em; 76 | } 77 | 78 | button, 79 | input, 80 | optgroup, 81 | select, 82 | textarea { 83 | color: inherit; 84 | font: inherit; 85 | margin: 0; 86 | } 87 | button:disabled { 88 | color: #c2c0c2; 89 | } 90 | 91 | input[type="number"]::-webkit-inner-spin-button, 92 | input[type="number"]::-webkit-outer-spin-button { 93 | height: auto; 94 | } 95 | 96 | input[type="search"] { 97 | -webkit-appearance: textfield; 98 | box-sizing: content-box; 99 | } 100 | 101 | input[type="search"]::-webkit-search-cancel-button, 102 | input[type="search"]::-webkit-search-decoration { 103 | -webkit-appearance: none; 104 | } 105 | 106 | fieldset { 107 | border: 1px solid #c0c0c0; 108 | margin: 0 2px; 109 | padding: 0.35em 0.625em 0.75em; 110 | } 111 | 112 | legend { 113 | border: 0; 114 | padding: 0; 115 | } 116 | 117 | table { 118 | border-collapse: collapse; 119 | border-spacing: 0; 120 | } 121 | 122 | td, 123 | th { 124 | padding: 0; 125 | } 126 | 127 | * { 128 | cursor: default; 129 | -webkit-user-drag: text; 130 | -webkit-user-select: none; 131 | -webkit-box-sizing: border-box; 132 | box-sizing: border-box; 133 | } 134 | 135 | html { 136 | height: 100%; 137 | width: 100%; 138 | overflow: hidden; 139 | } 140 | 141 | body { 142 | height: 100%; 143 | padding: 0; 144 | margin: 0; 145 | font-family: system, -apple-system, ".SFNSDisplay-Regular", "Helvetica Neue", Helvetica, "Segoe UI", sans-serif; 146 | font-size: 13px; 147 | line-height: 1.6; 148 | color: #333; 149 | background-color: transparent; 150 | } 151 | 152 | hr { 153 | margin: 15px 0; 154 | overflow: hidden; 155 | background: transparent; 156 | border: 0; 157 | border-bottom: 1px solid #ddd; 158 | } 159 | 160 | h1, h2, h3, h4, h5, h6 { 161 | margin-top: 20px; 162 | margin-bottom: 10px; 163 | font-weight: 500; 164 | white-space: nowrap; 165 | overflow: hidden; 166 | text-overflow: ellipsis; 167 | } 168 | 169 | h1 { 170 | font-size: 36px; 171 | } 172 | 173 | h2 { 174 | font-size: 30px; 175 | } 176 | 177 | h3 { 178 | font-size: 24px; 179 | } 180 | 181 | h4 { 182 | font-size: 18px; 183 | } 184 | 185 | h5 { 186 | font-size: 14px; 187 | } 188 | 189 | h6 { 190 | font-size: 12px; 191 | } 192 | 193 | .window { 194 | position: absolute; 195 | top: 0; 196 | right: 0; 197 | bottom: 0; 198 | left: 0; 199 | display: flex; 200 | flex-direction: column; 201 | background-color: #fff; 202 | } 203 | 204 | .window-content { 205 | position: relative; 206 | overflow-y: auto; 207 | display: flex; 208 | flex: 1; 209 | } 210 | 211 | .selectable-text { 212 | cursor: text; 213 | -webkit-user-select: text; 214 | } 215 | 216 | .text-center { 217 | text-align: center; 218 | } 219 | 220 | .text-right { 221 | text-align: right; 222 | } 223 | 224 | .text-left { 225 | text-align: left; 226 | } 227 | 228 | .pull-left { 229 | float: left; 230 | } 231 | 232 | .pull-right { 233 | float: right; 234 | } 235 | 236 | .padded { 237 | padding: 10px; 238 | } 239 | 240 | .padded-less { 241 | padding: 5px; 242 | } 243 | 244 | .padded-more { 245 | padding: 20px; 246 | } 247 | 248 | .padded-vertically { 249 | padding-top: 10px; 250 | padding-bottom: 10px; 251 | } 252 | 253 | .padded-vertically-less { 254 | padding-top: 5px; 255 | padding-bottom: 5px; 256 | } 257 | 258 | .padded-vertically-more { 259 | padding-top: 20px; 260 | padding-bottom: 20px; 261 | } 262 | 263 | .padded-horizontally { 264 | padding-right: 10px; 265 | padding-left: 10px; 266 | } 267 | 268 | .padded-horizontally-less { 269 | padding-right: 5px; 270 | padding-left: 5px; 271 | } 272 | 273 | .padded-horizontally-more { 274 | padding-right: 20px; 275 | padding-left: 20px; 276 | } 277 | 278 | .padded-top { 279 | padding-top: 10px; 280 | } 281 | 282 | .padded-top-less { 283 | padding-top: 5px; 284 | } 285 | 286 | .padded-top-more { 287 | padding-top: 20px; 288 | } 289 | 290 | .padded-bottom { 291 | padding-bottom: 10px; 292 | } 293 | 294 | .padded-bottom-less { 295 | padding-bottom: 5px; 296 | } 297 | 298 | .padded-bottom-more { 299 | padding-bottom: 20px; 300 | } 301 | 302 | .sidebar { 303 | background-color: #f5f5f4; 304 | } 305 | 306 | .draggable { 307 | -webkit-app-region: drag; 308 | } 309 | 310 | .clearfix:before, .clearfix:after { 311 | display: table; 312 | content: " "; 313 | } 314 | .clearfix:after { 315 | clear: both; 316 | } 317 | 318 | .btn { 319 | display: inline-block; 320 | padding: 3px 8px; 321 | margin-bottom: 0; 322 | font-size: 12px; 323 | line-height: 1.4; 324 | text-align: center; 325 | white-space: nowrap; 326 | vertical-align: middle; 327 | cursor: default; 328 | background-image: none; 329 | border: 1px solid transparent; 330 | border-radius: 4px; 331 | box-shadow: 0 1px 1px rgba(0, 0, 0, 0.06); 332 | -webkit-app-region: no-drag; 333 | } 334 | .btn:focus { 335 | outline: none; 336 | box-shadow: none; 337 | } 338 | 339 | .btn-mini { 340 | padding: 2px 6px; 341 | } 342 | 343 | .btn-large { 344 | padding: 6px 12px; 345 | } 346 | 347 | .btn-form { 348 | padding-right: 20px; 349 | padding-left: 20px; 350 | } 351 | 352 | .btn-default { 353 | color: #333; 354 | border-top-color: #c2c0c2; 355 | border-right-color: #c2c0c2; 356 | border-bottom-color: #a19fa1; 357 | border-left-color: #c2c0c2; 358 | background-color: #fcfcfc; 359 | background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #fcfcfc), color-stop(100%, #f1f1f1)); 360 | background-image: -webkit-linear-gradient(top, #fcfcfc 0%, #f1f1f1 100%); 361 | background-image: linear-gradient(to bottom, #fcfcfc 0%, #f1f1f1 100%); 362 | } 363 | .btn-default:active { 364 | background-color: #ddd; 365 | background-image: none; 366 | } 367 | 368 | .btn-primary, 369 | .btn-positive, 370 | .btn-negative, 371 | .btn-warning { 372 | color: #fff; 373 | text-shadow: 0 1px 1px rgba(0, 0, 0, 0.1); 374 | } 375 | 376 | .btn-primary { 377 | border-color: #388df8; 378 | border-bottom-color: #0866dc; 379 | background-color: #6eb4f7; 380 | background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #6eb4f7), color-stop(100%, #1a82fb)); 381 | background-image: -webkit-linear-gradient(top, #6eb4f7 0%, #1a82fb 100%); 382 | background-image: linear-gradient(to bottom, #6eb4f7 0%, #1a82fb 100%); 383 | } 384 | .btn-primary:active { 385 | background-color: #3e9bf4; 386 | background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #3e9bf4), color-stop(100%, #0469de)); 387 | background-image: -webkit-linear-gradient(top, #3e9bf4 0%, #0469de 100%); 388 | background-image: linear-gradient(to bottom, #3e9bf4 0%, #0469de 100%); 389 | } 390 | 391 | .btn-positive { 392 | border-color: #29a03b; 393 | border-bottom-color: #248b34; 394 | background-color: #5bd46d; 395 | background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #5bd46d), color-stop(100%, #29a03b)); 396 | background-image: -webkit-linear-gradient(top, #5bd46d 0%, #29a03b 100%); 397 | background-image: linear-gradient(to bottom, #5bd46d 0%, #29a03b 100%); 398 | } 399 | .btn-positive:active { 400 | background-color: #34c84a; 401 | background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #34c84a), color-stop(100%, #248b34)); 402 | background-image: -webkit-linear-gradient(top, #34c84a 0%, #248b34 100%); 403 | background-image: linear-gradient(to bottom, #34c84a 0%, #248b34 100%); 404 | } 405 | 406 | .btn-negative { 407 | border-color: #fb2f29; 408 | border-bottom-color: #fb1710; 409 | background-color: #fd918d; 410 | background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #fd918d), color-stop(100%, #fb2f29)); 411 | background-image: -webkit-linear-gradient(top, #fd918d 0%, #fb2f29 100%); 412 | background-image: linear-gradient(to bottom, #fd918d 0%, #fb2f29 100%); 413 | } 414 | .btn-negative:active { 415 | background-color: #fc605b; 416 | background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #fc605b), color-stop(100%, #fb1710)); 417 | background-image: -webkit-linear-gradient(top, #fc605b 0%, #fb1710 100%); 418 | background-image: linear-gradient(to bottom, #fc605b 0%, #fb1710 100%); 419 | } 420 | 421 | .btn-warning { 422 | border-color: #fcaa0e; 423 | border-bottom-color: #ee9d02; 424 | background-color: #fece72; 425 | background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #fece72), color-stop(100%, #fcaa0e)); 426 | background-image: -webkit-linear-gradient(top, #fece72 0%, #fcaa0e 100%); 427 | background-image: linear-gradient(to bottom, #fece72 0%, #fcaa0e 100%); 428 | } 429 | .btn-warning:active { 430 | background-color: #fdbc40; 431 | background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #fdbc40), color-stop(100%, #ee9d02)); 432 | background-image: -webkit-linear-gradient(top, #fdbc40 0%, #ee9d02 100%); 433 | background-image: linear-gradient(to bottom, #fdbc40 0%, #ee9d02 100%); 434 | } 435 | 436 | .btn .icon { 437 | float: left; 438 | width: 14px; 439 | height: 14px; 440 | margin-top: 1px; 441 | margin-bottom: 1px; 442 | color: #737475; 443 | font-size: 14px; 444 | line-height: 1; 445 | } 446 | 447 | .btn .icon-text { 448 | margin-right: 5px; 449 | } 450 | 451 | .btn-dropdown:after { 452 | font-family: "photon-entypo"; 453 | margin-left: 5px; 454 | content: ""; 455 | } 456 | 457 | .btn-group { 458 | position: relative; 459 | display: inline-block; 460 | vertical-align: middle; 461 | -webkit-app-region: no-drag; 462 | } 463 | .btn-group .btn { 464 | position: relative; 465 | float: left; 466 | } 467 | .btn-group .btn:focus, .btn-group .btn:active { 468 | z-index: 2; 469 | } 470 | .btn-group .btn.active { 471 | z-index: 3; 472 | } 473 | 474 | .btn-group .btn + .btn, 475 | .btn-group .btn + .btn-group, 476 | .btn-group .btn-group + .btn, 477 | .btn-group .btn-group + .btn-group { 478 | margin-left: -1px; 479 | } 480 | .btn-group > .btn:first-child { 481 | border-top-right-radius: 0; 482 | border-bottom-right-radius: 0; 483 | } 484 | .btn-group > .btn:last-child { 485 | border-top-left-radius: 0; 486 | border-bottom-left-radius: 0; 487 | } 488 | .btn-group > .btn:not(:first-child):not(:last-child) { 489 | border-radius: 0; 490 | } 491 | .btn-group .btn + .btn { 492 | border-left: 1px solid #c2c0c2; 493 | } 494 | .btn-group .btn + .btn.active { 495 | border-left: 0; 496 | } 497 | .btn-group .active { 498 | color: #fff; 499 | border: 1px solid transparent; 500 | background-color: #6d6c6d; 501 | background-image: none; 502 | } 503 | .btn-group .active .icon { 504 | color: #fff; 505 | } 506 | 507 | .toolbar { 508 | min-height: 22px; 509 | box-shadow: inset 0 1px 0 #f5f4f5; 510 | background-color: #e8e6e8; 511 | background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #e8e6e8), color-stop(100%, #d1cfd1)); 512 | background-image: -webkit-linear-gradient(top, #e8e6e8 0%, #d1cfd1 100%); 513 | background-image: linear-gradient(to bottom, #e8e6e8 0%, #d1cfd1 100%); 514 | } 515 | .toolbar:before, .toolbar:after { 516 | display: table; 517 | content: " "; 518 | } 519 | .toolbar:after { 520 | clear: both; 521 | } 522 | 523 | .toolbar-header { 524 | border-bottom: 1px solid #c2c0c2; 525 | } 526 | .toolbar-header .title { 527 | margin-top: 1px; 528 | } 529 | 530 | .toolbar-footer { 531 | border-top: 1px solid #c2c0c2; 532 | -webkit-app-region: drag; 533 | } 534 | 535 | .title { 536 | margin: 0; 537 | font-size: 12px; 538 | font-weight: 400; 539 | text-align: center; 540 | color: #555; 541 | cursor: default; 542 | } 543 | 544 | .toolbar-borderless { 545 | border-top: 0; 546 | border-bottom: 0; 547 | } 548 | 549 | .toolbar-actions { 550 | margin-top: 4px; 551 | margin-bottom: 3px; 552 | padding-right: 3px; 553 | padding-left: 3px; 554 | padding-bottom: 3px; 555 | -webkit-app-region: drag; 556 | } 557 | .toolbar-actions:before, .toolbar-actions:after { 558 | display: table; 559 | content: " "; 560 | } 561 | .toolbar-actions:after { 562 | clear: both; 563 | } 564 | .toolbar-actions > .btn, 565 | .toolbar-actions > .btn-group { 566 | margin-left: 4px; 567 | margin-right: 4px; 568 | } 569 | 570 | label { 571 | display: inline-block; 572 | font-size: 13px; 573 | margin-bottom: 5px; 574 | white-space: nowrap; 575 | overflow: hidden; 576 | text-overflow: ellipsis; 577 | } 578 | 579 | input[type="search"] { 580 | box-sizing: border-box; 581 | } 582 | 583 | input[type="radio"], 584 | input[type="checkbox"] { 585 | margin: 4px 0 0; 586 | line-height: normal; 587 | } 588 | 589 | .form-control { 590 | display: inline-block; 591 | width: 100%; 592 | min-height: 25px; 593 | padding: 5px 10px; 594 | font-size: 13px; 595 | line-height: 1.6; 596 | background-color: #fff; 597 | border: 1px solid #ddd; 598 | border-radius: 4px; 599 | outline: none; 600 | } 601 | .form-control:focus { 602 | border-color: #6db3fd; 603 | box-shadow: 3px 3px 0 #6db3fd, -3px -3px 0 #6db3fd, -3px 3px 0 #6db3fd, 3px -3px 0 #6db3fd; 604 | } 605 | 606 | textarea { 607 | height: auto; 608 | } 609 | 610 | .form-group { 611 | margin-bottom: 10px; 612 | } 613 | 614 | .radio, 615 | .checkbox { 616 | position: relative; 617 | display: block; 618 | margin-top: 10px; 619 | margin-bottom: 10px; 620 | } 621 | .radio label, 622 | .checkbox label { 623 | padding-left: 20px; 624 | margin-bottom: 0; 625 | font-weight: normal; 626 | } 627 | 628 | .radio input[type="radio"], 629 | .radio-inline input[type="radio"], 630 | .checkbox input[type="checkbox"], 631 | .checkbox-inline input[type="checkbox"] { 632 | position: absolute; 633 | margin-left: -20px; 634 | margin-top: 4px; 635 | } 636 | 637 | .form-actions .btn { 638 | margin-right: 10px; 639 | } 640 | .form-actions .btn:last-child { 641 | margin-right: 0; 642 | } 643 | 644 | .pane-group { 645 | position: absolute; 646 | top: 0; 647 | right: 0; 648 | bottom: 0; 649 | left: 0; 650 | display: flex; 651 | } 652 | 653 | .pane { 654 | position: relative; 655 | overflow-y: auto; 656 | flex: 1; 657 | border-left: 1px solid #ddd; 658 | } 659 | .pane:first-child { 660 | border-left: 0; 661 | } 662 | 663 | .pane-sm { 664 | max-width: 220px; 665 | min-width: 150px; 666 | } 667 | 668 | .pane-mini { 669 | width: 80px; 670 | flex: none; 671 | } 672 | 673 | .pane-one-fourth { 674 | width: 25%; 675 | flex: none; 676 | } 677 | 678 | .pane-one-third { 679 | width: 33.3%; 680 | } 681 | 682 | img { 683 | -webkit-user-drag: text; 684 | } 685 | 686 | .img-circle { 687 | border-radius: 50%; 688 | } 689 | 690 | .img-rounded { 691 | border-radius: 4px; 692 | } 693 | 694 | .list-group { 695 | width: 100%; 696 | list-style: none; 697 | margin: 0; 698 | padding: 0; 699 | } 700 | .list-group * { 701 | margin: 0; 702 | white-space: nowrap; 703 | overflow: hidden; 704 | text-overflow: ellipsis; 705 | } 706 | 707 | .list-group-item { 708 | padding: 10px; 709 | font-size: 12px; 710 | color: #414142; 711 | border-top: 1px solid #ddd; 712 | } 713 | .list-group-item:first-child { 714 | border-top: 0; 715 | } 716 | .list-group-item.active, .list-group-item.selected { 717 | color: #fff; 718 | background-color: #116cd6; 719 | } 720 | 721 | .list-group-header { 722 | padding: 10px; 723 | } 724 | 725 | .media-object { 726 | margin-top: 3px; 727 | } 728 | 729 | .media-object.pull-left { 730 | margin-right: 10px; 731 | } 732 | 733 | .media-object.pull-right { 734 | margin-left: 10px; 735 | } 736 | 737 | .media-body { 738 | overflow: hidden; 739 | } 740 | 741 | .nav-group { 742 | font-size: 14px; 743 | } 744 | 745 | .nav-group-item { 746 | padding: 2px 10px 2px 25px; 747 | display: block; 748 | color: #333; 749 | text-decoration: none; 750 | white-space: nowrap; 751 | overflow: hidden; 752 | text-overflow: ellipsis; 753 | } 754 | .nav-group-item:active, .nav-group-item.active { 755 | background-color: #dcdfe1; 756 | } 757 | .nav-group-item .icon { 758 | width: 19px; 759 | height: 18px; 760 | float: left; 761 | color: #737475; 762 | margin-top: -3px; 763 | margin-right: 7px; 764 | font-size: 18px; 765 | text-align: center; 766 | } 767 | 768 | .nav-group-title { 769 | margin: 0; 770 | padding: 10px 10px 2px; 771 | font-size: 12px; 772 | font-weight: 500; 773 | color: #666666; 774 | } 775 | 776 | @font-face { 777 | font-family: "photon-entypo"; 778 | src: url("../fonts/photon-entypo.eot"); 779 | src: url("../fonts/photon-entypo.eot?#iefix") format("eot"), url("../fonts/photon-entypo.woff") format("woff"), url("../fonts/photon-entypo.ttf") format("truetype"); 780 | font-weight: normal; 781 | font-style: normal; 782 | } 783 | .icon:before { 784 | position: relative; 785 | display: inline-block; 786 | font-family: "photon-entypo"; 787 | speak: none; 788 | font-size: 100%; 789 | font-style: normal; 790 | font-weight: normal; 791 | font-variant: normal; 792 | text-transform: none; 793 | line-height: 1; 794 | -webkit-font-smoothing: antialiased; 795 | -moz-osx-font-smoothing: grayscale; 796 | } 797 | 798 | .icon-note:before { 799 | content: '\e800'; 800 | } 801 | 802 | /* '' */ 803 | .icon-note-beamed:before { 804 | content: '\e801'; 805 | } 806 | 807 | /* '' */ 808 | .icon-music:before { 809 | content: '\e802'; 810 | } 811 | 812 | /* '' */ 813 | .icon-search:before { 814 | content: '\e803'; 815 | } 816 | 817 | /* '' */ 818 | .icon-flashlight:before { 819 | content: '\e804'; 820 | } 821 | 822 | /* '' */ 823 | .icon-mail:before { 824 | content: '\e805'; 825 | } 826 | 827 | /* '' */ 828 | .icon-heart:before { 829 | content: '\e806'; 830 | } 831 | 832 | /* '' */ 833 | .icon-heart-empty:before { 834 | content: '\e807'; 835 | } 836 | 837 | /* '' */ 838 | .icon-star:before { 839 | content: '\e808'; 840 | } 841 | 842 | /* '' */ 843 | .icon-star-empty:before { 844 | content: '\e809'; 845 | } 846 | 847 | /* '' */ 848 | .icon-user:before { 849 | content: '\e80a'; 850 | } 851 | 852 | /* '' */ 853 | .icon-users:before { 854 | content: '\e80b'; 855 | } 856 | 857 | /* '' */ 858 | .icon-user-add:before { 859 | content: '\e80c'; 860 | } 861 | 862 | /* '' */ 863 | .icon-video:before { 864 | content: '\e80d'; 865 | } 866 | 867 | /* '' */ 868 | .icon-picture:before { 869 | content: '\e80e'; 870 | } 871 | 872 | /* '' */ 873 | .icon-camera:before { 874 | content: '\e80f'; 875 | } 876 | 877 | /* '' */ 878 | .icon-layout:before { 879 | content: '\e810'; 880 | } 881 | 882 | /* '' */ 883 | .icon-menu:before { 884 | content: '\e811'; 885 | } 886 | 887 | /* '' */ 888 | .icon-check:before { 889 | content: '\e812'; 890 | } 891 | 892 | /* '' */ 893 | .icon-cancel:before { 894 | content: '\e813'; 895 | } 896 | 897 | /* '' */ 898 | .icon-cancel-circled:before { 899 | content: '\e814'; 900 | } 901 | 902 | /* '' */ 903 | .icon-cancel-squared:before { 904 | content: '\e815'; 905 | } 906 | 907 | /* '' */ 908 | .icon-plus:before { 909 | content: '\e816'; 910 | } 911 | 912 | /* '' */ 913 | .icon-plus-circled:before { 914 | content: '\e817'; 915 | } 916 | 917 | /* '' */ 918 | .icon-plus-squared:before { 919 | content: '\e818'; 920 | } 921 | 922 | /* '' */ 923 | .icon-minus:before { 924 | content: '\e819'; 925 | } 926 | 927 | /* '' */ 928 | .icon-minus-circled:before { 929 | content: '\e81a'; 930 | } 931 | 932 | /* '' */ 933 | .icon-minus-squared:before { 934 | content: '\e81b'; 935 | } 936 | 937 | /* '' */ 938 | .icon-help:before { 939 | content: '\e81c'; 940 | } 941 | 942 | /* '' */ 943 | .icon-help-circled:before { 944 | content: '\e81d'; 945 | } 946 | 947 | /* '' */ 948 | .icon-info:before { 949 | content: '\e81e'; 950 | } 951 | 952 | /* '' */ 953 | .icon-info-circled:before { 954 | content: '\e81f'; 955 | } 956 | 957 | /* '' */ 958 | .icon-back:before { 959 | content: '\e820'; 960 | } 961 | 962 | /* '' */ 963 | .icon-home:before { 964 | content: '\e821'; 965 | } 966 | 967 | /* '' */ 968 | .icon-link:before { 969 | content: '\e822'; 970 | } 971 | 972 | /* '' */ 973 | .icon-attach:before { 974 | content: '\e823'; 975 | } 976 | 977 | /* '' */ 978 | .icon-lock:before { 979 | content: '\e824'; 980 | } 981 | 982 | /* '' */ 983 | .icon-lock-open:before { 984 | content: '\e825'; 985 | } 986 | 987 | /* '' */ 988 | .icon-eye:before { 989 | content: '\e826'; 990 | } 991 | 992 | /* '' */ 993 | .icon-tag:before { 994 | content: '\e827'; 995 | } 996 | 997 | /* '' */ 998 | .icon-bookmark:before { 999 | content: '\e828'; 1000 | } 1001 | 1002 | /* '' */ 1003 | .icon-bookmarks:before { 1004 | content: '\e829'; 1005 | } 1006 | 1007 | /* '' */ 1008 | .icon-flag:before { 1009 | content: '\e82a'; 1010 | } 1011 | 1012 | /* '' */ 1013 | .icon-thumbs-up:before { 1014 | content: '\e82b'; 1015 | } 1016 | 1017 | /* '' */ 1018 | .icon-thumbs-down:before { 1019 | content: '\e82c'; 1020 | } 1021 | 1022 | /* '' */ 1023 | .icon-download:before { 1024 | content: '\e82d'; 1025 | } 1026 | 1027 | /* '' */ 1028 | .icon-upload:before { 1029 | content: '\e82e'; 1030 | } 1031 | 1032 | /* '' */ 1033 | .icon-upload-cloud:before { 1034 | content: '\e82f'; 1035 | } 1036 | 1037 | /* '' */ 1038 | .icon-reply:before { 1039 | content: '\e830'; 1040 | } 1041 | 1042 | /* '' */ 1043 | .icon-reply-all:before { 1044 | content: '\e831'; 1045 | } 1046 | 1047 | /* '' */ 1048 | .icon-forward:before { 1049 | content: '\e832'; 1050 | } 1051 | 1052 | /* '' */ 1053 | .icon-quote:before { 1054 | content: '\e833'; 1055 | } 1056 | 1057 | /* '' */ 1058 | .icon-code:before { 1059 | content: '\e834'; 1060 | } 1061 | 1062 | /* '' */ 1063 | .icon-export:before { 1064 | content: '\e835'; 1065 | } 1066 | 1067 | /* '' */ 1068 | .icon-pencil:before { 1069 | content: '\e836'; 1070 | } 1071 | 1072 | /* '' */ 1073 | .icon-feather:before { 1074 | content: '\e837'; 1075 | } 1076 | 1077 | /* '' */ 1078 | .icon-print:before { 1079 | content: '\e838'; 1080 | } 1081 | 1082 | /* '' */ 1083 | .icon-retweet:before { 1084 | content: '\e839'; 1085 | } 1086 | 1087 | /* '' */ 1088 | .icon-keyboard:before { 1089 | content: '\e83a'; 1090 | } 1091 | 1092 | /* '' */ 1093 | .icon-comment:before { 1094 | content: '\e83b'; 1095 | } 1096 | 1097 | /* '' */ 1098 | .icon-chat:before { 1099 | content: '\e83c'; 1100 | } 1101 | 1102 | /* '' */ 1103 | .icon-bell:before { 1104 | content: '\e83d'; 1105 | } 1106 | 1107 | /* '' */ 1108 | .icon-attention:before { 1109 | content: '\e83e'; 1110 | } 1111 | 1112 | /* '' */ 1113 | .icon-alert:before { 1114 | content: '\e83f'; 1115 | } 1116 | 1117 | /* '' */ 1118 | .icon-vcard:before { 1119 | content: '\e840'; 1120 | } 1121 | 1122 | /* '' */ 1123 | .icon-address:before { 1124 | content: '\e841'; 1125 | } 1126 | 1127 | /* '' */ 1128 | .icon-location:before { 1129 | content: '\e842'; 1130 | } 1131 | 1132 | /* '' */ 1133 | .icon-map:before { 1134 | content: '\e843'; 1135 | } 1136 | 1137 | /* '' */ 1138 | .icon-direction:before { 1139 | content: '\e844'; 1140 | } 1141 | 1142 | /* '' */ 1143 | .icon-compass:before { 1144 | content: '\e845'; 1145 | } 1146 | 1147 | /* '' */ 1148 | .icon-cup:before { 1149 | content: '\e846'; 1150 | } 1151 | 1152 | /* '' */ 1153 | .icon-trash:before { 1154 | content: '\e847'; 1155 | } 1156 | 1157 | /* '' */ 1158 | .icon-doc:before { 1159 | content: '\e848'; 1160 | } 1161 | 1162 | /* '' */ 1163 | .icon-docs:before { 1164 | content: '\e849'; 1165 | } 1166 | 1167 | /* '' */ 1168 | .icon-doc-landscape:before { 1169 | content: '\e84a'; 1170 | } 1171 | 1172 | /* '' */ 1173 | .icon-doc-text:before { 1174 | content: '\e84b'; 1175 | } 1176 | 1177 | /* '' */ 1178 | .icon-doc-text-inv:before { 1179 | content: '\e84c'; 1180 | } 1181 | 1182 | /* '' */ 1183 | .icon-newspaper:before { 1184 | content: '\e84d'; 1185 | } 1186 | 1187 | /* '' */ 1188 | .icon-book-open:before { 1189 | content: '\e84e'; 1190 | } 1191 | 1192 | /* '' */ 1193 | .icon-book:before { 1194 | content: '\e84f'; 1195 | } 1196 | 1197 | /* '' */ 1198 | .icon-folder:before { 1199 | content: '\e850'; 1200 | } 1201 | 1202 | /* '' */ 1203 | .icon-archive:before { 1204 | content: '\e851'; 1205 | } 1206 | 1207 | /* '' */ 1208 | .icon-box:before { 1209 | content: '\e852'; 1210 | } 1211 | 1212 | /* '' */ 1213 | .icon-rss:before { 1214 | content: '\e853'; 1215 | } 1216 | 1217 | /* '' */ 1218 | .icon-phone:before { 1219 | content: '\e854'; 1220 | } 1221 | 1222 | /* '' */ 1223 | .icon-cog:before { 1224 | content: '\e855'; 1225 | } 1226 | 1227 | /* '' */ 1228 | .icon-tools:before { 1229 | content: '\e856'; 1230 | } 1231 | 1232 | /* '' */ 1233 | .icon-share:before { 1234 | content: '\e857'; 1235 | } 1236 | 1237 | /* '' */ 1238 | .icon-shareable:before { 1239 | content: '\e858'; 1240 | } 1241 | 1242 | /* '' */ 1243 | .icon-basket:before { 1244 | content: '\e859'; 1245 | } 1246 | 1247 | /* '' */ 1248 | .icon-bag:before { 1249 | content: '\e85a'; 1250 | } 1251 | 1252 | /* '' */ 1253 | .icon-calendar:before { 1254 | content: '\e85b'; 1255 | } 1256 | 1257 | /* '' */ 1258 | .icon-login:before { 1259 | content: '\e85c'; 1260 | } 1261 | 1262 | /* '' */ 1263 | .icon-logout:before { 1264 | content: '\e85d'; 1265 | } 1266 | 1267 | /* '' */ 1268 | .icon-mic:before { 1269 | content: '\e85e'; 1270 | } 1271 | 1272 | /* '' */ 1273 | .icon-mute:before { 1274 | content: '\e85f'; 1275 | } 1276 | 1277 | /* '' */ 1278 | .icon-sound:before { 1279 | content: '\e860'; 1280 | } 1281 | 1282 | /* '' */ 1283 | .icon-volume:before { 1284 | content: '\e861'; 1285 | } 1286 | 1287 | /* '' */ 1288 | .icon-clock:before { 1289 | content: '\e862'; 1290 | } 1291 | 1292 | /* '' */ 1293 | .icon-hourglass:before { 1294 | content: '\e863'; 1295 | } 1296 | 1297 | /* '' */ 1298 | .icon-lamp:before { 1299 | content: '\e864'; 1300 | } 1301 | 1302 | /* '' */ 1303 | .icon-light-down:before { 1304 | content: '\e865'; 1305 | } 1306 | 1307 | /* '' */ 1308 | .icon-light-up:before { 1309 | content: '\e866'; 1310 | } 1311 | 1312 | /* '' */ 1313 | .icon-adjust:before { 1314 | content: '\e867'; 1315 | } 1316 | 1317 | /* '' */ 1318 | .icon-block:before { 1319 | content: '\e868'; 1320 | } 1321 | 1322 | /* '' */ 1323 | .icon-resize-full:before { 1324 | content: '\e869'; 1325 | } 1326 | 1327 | /* '' */ 1328 | .icon-resize-small:before { 1329 | content: '\e86a'; 1330 | } 1331 | 1332 | /* '' */ 1333 | .icon-popup:before { 1334 | content: '\e86b'; 1335 | } 1336 | 1337 | /* '' */ 1338 | .icon-publish:before { 1339 | content: '\e86c'; 1340 | } 1341 | 1342 | /* '' */ 1343 | .icon-window:before { 1344 | content: '\e86d'; 1345 | } 1346 | 1347 | /* '' */ 1348 | .icon-arrow-combo:before { 1349 | content: '\e86e'; 1350 | } 1351 | 1352 | /* '' */ 1353 | .icon-down-circled:before { 1354 | content: '\e86f'; 1355 | } 1356 | 1357 | /* '' */ 1358 | .icon-left-circled:before { 1359 | content: '\e870'; 1360 | } 1361 | 1362 | /* '' */ 1363 | .icon-right-circled:before { 1364 | content: '\e871'; 1365 | } 1366 | 1367 | /* '' */ 1368 | .icon-up-circled:before { 1369 | content: '\e872'; 1370 | } 1371 | 1372 | /* '' */ 1373 | .icon-down-open:before { 1374 | content: '\e873'; 1375 | } 1376 | 1377 | /* '' */ 1378 | .icon-left-open:before { 1379 | content: '\e874'; 1380 | } 1381 | 1382 | /* '' */ 1383 | .icon-right-open:before { 1384 | content: '\e875'; 1385 | } 1386 | 1387 | /* '' */ 1388 | .icon-up-open:before { 1389 | content: '\e876'; 1390 | } 1391 | 1392 | /* '' */ 1393 | .icon-down-open-mini:before { 1394 | content: '\e877'; 1395 | } 1396 | 1397 | /* '' */ 1398 | .icon-left-open-mini:before { 1399 | content: '\e878'; 1400 | } 1401 | 1402 | /* '' */ 1403 | .icon-right-open-mini:before { 1404 | content: '\e879'; 1405 | } 1406 | 1407 | /* '' */ 1408 | .icon-up-open-mini:before { 1409 | content: '\e87a'; 1410 | } 1411 | 1412 | /* '' */ 1413 | .icon-down-open-big:before { 1414 | content: '\e87b'; 1415 | } 1416 | 1417 | /* '' */ 1418 | .icon-left-open-big:before { 1419 | content: '\e87c'; 1420 | } 1421 | 1422 | /* '' */ 1423 | .icon-right-open-big:before { 1424 | content: '\e87d'; 1425 | } 1426 | 1427 | /* '' */ 1428 | .icon-up-open-big:before { 1429 | content: '\e87e'; 1430 | } 1431 | 1432 | /* '' */ 1433 | .icon-down:before { 1434 | content: '\e87f'; 1435 | } 1436 | 1437 | /* '' */ 1438 | .icon-left:before { 1439 | content: '\e880'; 1440 | } 1441 | 1442 | /* '' */ 1443 | .icon-right:before { 1444 | content: '\e881'; 1445 | } 1446 | 1447 | /* '' */ 1448 | .icon-up:before { 1449 | content: '\e882'; 1450 | } 1451 | 1452 | /* '' */ 1453 | .icon-down-dir:before { 1454 | content: '\e883'; 1455 | } 1456 | 1457 | /* '' */ 1458 | .icon-left-dir:before { 1459 | content: '\e884'; 1460 | } 1461 | 1462 | /* '' */ 1463 | .icon-right-dir:before { 1464 | content: '\e885'; 1465 | } 1466 | 1467 | /* '' */ 1468 | .icon-up-dir:before { 1469 | content: '\e886'; 1470 | } 1471 | 1472 | /* '' */ 1473 | .icon-down-bold:before { 1474 | content: '\e887'; 1475 | } 1476 | 1477 | /* '' */ 1478 | .icon-left-bold:before { 1479 | content: '\e888'; 1480 | } 1481 | 1482 | /* '' */ 1483 | .icon-right-bold:before { 1484 | content: '\e889'; 1485 | } 1486 | 1487 | /* '' */ 1488 | .icon-up-bold:before { 1489 | content: '\e88a'; 1490 | } 1491 | 1492 | /* '' */ 1493 | .icon-down-thin:before { 1494 | content: '\e88b'; 1495 | } 1496 | 1497 | /* '' */ 1498 | .icon-left-thin:before { 1499 | content: '\e88c'; 1500 | } 1501 | 1502 | /* '' */ 1503 | .icon-right-thin:before { 1504 | content: '\e88d'; 1505 | } 1506 | 1507 | /* '' */ 1508 | .icon-up-thin:before { 1509 | content: '\e88e'; 1510 | } 1511 | 1512 | /* '' */ 1513 | .icon-ccw:before { 1514 | content: '\e88f'; 1515 | } 1516 | 1517 | /* '' */ 1518 | .icon-cw:before { 1519 | content: '\e890'; 1520 | } 1521 | 1522 | /* '' */ 1523 | .icon-arrows-ccw:before { 1524 | content: '\e891'; 1525 | } 1526 | 1527 | /* '' */ 1528 | .icon-level-down:before { 1529 | content: '\e892'; 1530 | } 1531 | 1532 | /* '' */ 1533 | .icon-level-up:before { 1534 | content: '\e893'; 1535 | } 1536 | 1537 | /* '' */ 1538 | .icon-shuffle:before { 1539 | content: '\e894'; 1540 | } 1541 | 1542 | /* '' */ 1543 | .icon-loop:before { 1544 | content: '\e895'; 1545 | } 1546 | 1547 | /* '' */ 1548 | .icon-switch:before { 1549 | content: '\e896'; 1550 | } 1551 | 1552 | /* '' */ 1553 | .icon-play:before { 1554 | content: '\e897'; 1555 | } 1556 | 1557 | /* '' */ 1558 | .icon-stop:before { 1559 | content: '\e898'; 1560 | } 1561 | 1562 | /* '' */ 1563 | .icon-pause:before { 1564 | content: '\e899'; 1565 | } 1566 | 1567 | /* '' */ 1568 | .icon-record:before { 1569 | content: '\e89a'; 1570 | } 1571 | 1572 | /* '' */ 1573 | .icon-to-end:before { 1574 | content: '\e89b'; 1575 | } 1576 | 1577 | /* '' */ 1578 | .icon-to-start:before { 1579 | content: '\e89c'; 1580 | } 1581 | 1582 | /* '' */ 1583 | .icon-fast-forward:before { 1584 | content: '\e89d'; 1585 | } 1586 | 1587 | /* '' */ 1588 | .icon-fast-backward:before { 1589 | content: '\e89e'; 1590 | } 1591 | 1592 | /* '' */ 1593 | .icon-progress-0:before { 1594 | content: '\e89f'; 1595 | } 1596 | 1597 | /* '' */ 1598 | .icon-progress-1:before { 1599 | content: '\e8a0'; 1600 | } 1601 | 1602 | /* '' */ 1603 | .icon-progress-2:before { 1604 | content: '\e8a1'; 1605 | } 1606 | 1607 | /* '' */ 1608 | .icon-progress-3:before { 1609 | content: '\e8a2'; 1610 | } 1611 | 1612 | /* '' */ 1613 | .icon-target:before { 1614 | content: '\e8a3'; 1615 | } 1616 | 1617 | /* '' */ 1618 | .icon-palette:before { 1619 | content: '\e8a4'; 1620 | } 1621 | 1622 | /* '' */ 1623 | .icon-list:before { 1624 | content: '\e8a5'; 1625 | } 1626 | 1627 | /* '' */ 1628 | .icon-list-add:before { 1629 | content: '\e8a6'; 1630 | } 1631 | 1632 | /* '' */ 1633 | .icon-signal:before { 1634 | content: '\e8a7'; 1635 | } 1636 | 1637 | /* '' */ 1638 | .icon-trophy:before { 1639 | content: '\e8a8'; 1640 | } 1641 | 1642 | /* '' */ 1643 | .icon-battery:before { 1644 | content: '\e8a9'; 1645 | } 1646 | 1647 | /* '' */ 1648 | .icon-back-in-time:before { 1649 | content: '\e8aa'; 1650 | } 1651 | 1652 | /* '' */ 1653 | .icon-monitor:before { 1654 | content: '\e8ab'; 1655 | } 1656 | 1657 | /* '' */ 1658 | .icon-mobile:before { 1659 | content: '\e8ac'; 1660 | } 1661 | 1662 | /* '' */ 1663 | .icon-network:before { 1664 | content: '\e8ad'; 1665 | } 1666 | 1667 | /* '' */ 1668 | .icon-cd:before { 1669 | content: '\e8ae'; 1670 | } 1671 | 1672 | /* '' */ 1673 | .icon-inbox:before { 1674 | content: '\e8af'; 1675 | } 1676 | 1677 | /* '' */ 1678 | .icon-install:before { 1679 | content: '\e8b0'; 1680 | } 1681 | 1682 | /* '' */ 1683 | .icon-globe:before { 1684 | content: '\e8b1'; 1685 | } 1686 | 1687 | /* '' */ 1688 | .icon-cloud:before { 1689 | content: '\e8b2'; 1690 | } 1691 | 1692 | /* '' */ 1693 | .icon-cloud-thunder:before { 1694 | content: '\e8b3'; 1695 | } 1696 | 1697 | /* '' */ 1698 | .icon-flash:before { 1699 | content: '\e8b4'; 1700 | } 1701 | 1702 | /* '' */ 1703 | .icon-moon:before { 1704 | content: '\e8b5'; 1705 | } 1706 | 1707 | /* '' */ 1708 | .icon-flight:before { 1709 | content: '\e8b6'; 1710 | } 1711 | 1712 | /* '' */ 1713 | .icon-paper-plane:before { 1714 | content: '\e8b7'; 1715 | } 1716 | 1717 | /* '' */ 1718 | .icon-leaf:before { 1719 | content: '\e8b8'; 1720 | } 1721 | 1722 | /* '' */ 1723 | .icon-lifebuoy:before { 1724 | content: '\e8b9'; 1725 | } 1726 | 1727 | /* '' */ 1728 | .icon-mouse:before { 1729 | content: '\e8ba'; 1730 | } 1731 | 1732 | /* '' */ 1733 | .icon-briefcase:before { 1734 | content: '\e8bb'; 1735 | } 1736 | 1737 | /* '' */ 1738 | .icon-suitcase:before { 1739 | content: '\e8bc'; 1740 | } 1741 | 1742 | /* '' */ 1743 | .icon-dot:before { 1744 | content: '\e8bd'; 1745 | } 1746 | 1747 | /* '' */ 1748 | .icon-dot-2:before { 1749 | content: '\e8be'; 1750 | } 1751 | 1752 | /* '' */ 1753 | .icon-dot-3:before { 1754 | content: '\e8bf'; 1755 | } 1756 | 1757 | /* '' */ 1758 | .icon-brush:before { 1759 | content: '\e8c0'; 1760 | } 1761 | 1762 | /* '' */ 1763 | .icon-magnet:before { 1764 | content: '\e8c1'; 1765 | } 1766 | 1767 | /* '' */ 1768 | .icon-infinity:before { 1769 | content: '\e8c2'; 1770 | } 1771 | 1772 | /* '' */ 1773 | .icon-erase:before { 1774 | content: '\e8c3'; 1775 | } 1776 | 1777 | /* '' */ 1778 | .icon-chart-pie:before { 1779 | content: '\e8c4'; 1780 | } 1781 | 1782 | /* '' */ 1783 | .icon-chart-line:before { 1784 | content: '\e8c5'; 1785 | } 1786 | 1787 | /* '' */ 1788 | .icon-chart-bar:before { 1789 | content: '\e8c6'; 1790 | } 1791 | 1792 | /* '' */ 1793 | .icon-chart-area:before { 1794 | content: '\e8c7'; 1795 | } 1796 | 1797 | /* '' */ 1798 | .icon-tape:before { 1799 | content: '\e8c8'; 1800 | } 1801 | 1802 | /* '' */ 1803 | .icon-graduation-cap:before { 1804 | content: '\e8c9'; 1805 | } 1806 | 1807 | /* '' */ 1808 | .icon-language:before { 1809 | content: '\e8ca'; 1810 | } 1811 | 1812 | /* '' */ 1813 | .icon-ticket:before { 1814 | content: '\e8cb'; 1815 | } 1816 | 1817 | /* '' */ 1818 | .icon-water:before { 1819 | content: '\e8cc'; 1820 | } 1821 | 1822 | /* '' */ 1823 | .icon-droplet:before { 1824 | content: '\e8cd'; 1825 | } 1826 | 1827 | /* '' */ 1828 | .icon-air:before { 1829 | content: '\e8ce'; 1830 | } 1831 | 1832 | /* '' */ 1833 | .icon-credit-card:before { 1834 | content: '\e8cf'; 1835 | } 1836 | 1837 | /* '' */ 1838 | .icon-floppy:before { 1839 | content: '\e8d0'; 1840 | } 1841 | 1842 | /* '' */ 1843 | .icon-clipboard:before { 1844 | content: '\e8d1'; 1845 | } 1846 | 1847 | /* '' */ 1848 | .icon-megaphone:before { 1849 | content: '\e8d2'; 1850 | } 1851 | 1852 | /* '' */ 1853 | .icon-database:before { 1854 | content: '\e8d3'; 1855 | } 1856 | 1857 | /* '' */ 1858 | .icon-drive:before { 1859 | content: '\e8d4'; 1860 | } 1861 | 1862 | /* '' */ 1863 | .icon-bucket:before { 1864 | content: '\e8d5'; 1865 | } 1866 | 1867 | /* '' */ 1868 | .icon-thermometer:before { 1869 | content: '\e8d6'; 1870 | } 1871 | 1872 | /* '' */ 1873 | .icon-key:before { 1874 | content: '\e8d7'; 1875 | } 1876 | 1877 | /* '' */ 1878 | .icon-flow-cascade:before { 1879 | content: '\e8d8'; 1880 | } 1881 | 1882 | /* '' */ 1883 | .icon-flow-branch:before { 1884 | content: '\e8d9'; 1885 | } 1886 | 1887 | /* '' */ 1888 | .icon-flow-tree:before { 1889 | content: '\e8da'; 1890 | } 1891 | 1892 | /* '' */ 1893 | .icon-flow-line:before { 1894 | content: '\e8db'; 1895 | } 1896 | 1897 | /* '' */ 1898 | .icon-flow-parallel:before { 1899 | content: '\e8dc'; 1900 | } 1901 | 1902 | /* '' */ 1903 | .icon-rocket:before { 1904 | content: '\e8dd'; 1905 | } 1906 | 1907 | /* '' */ 1908 | .icon-gauge:before { 1909 | content: '\e8de'; 1910 | } 1911 | 1912 | /* '' */ 1913 | .icon-traffic-cone:before { 1914 | content: '\e8df'; 1915 | } 1916 | 1917 | /* '' */ 1918 | .icon-cc:before { 1919 | content: '\e8e0'; 1920 | } 1921 | 1922 | /* '' */ 1923 | .icon-cc-by:before { 1924 | content: '\e8e1'; 1925 | } 1926 | 1927 | /* '' */ 1928 | .icon-cc-nc:before { 1929 | content: '\e8e2'; 1930 | } 1931 | 1932 | /* '' */ 1933 | .icon-cc-nc-eu:before { 1934 | content: '\e8e3'; 1935 | } 1936 | 1937 | /* '' */ 1938 | .icon-cc-nc-jp:before { 1939 | content: '\e8e4'; 1940 | } 1941 | 1942 | /* '' */ 1943 | .icon-cc-sa:before { 1944 | content: '\e8e5'; 1945 | } 1946 | 1947 | /* '' */ 1948 | .icon-cc-nd:before { 1949 | content: '\e8e6'; 1950 | } 1951 | 1952 | /* '' */ 1953 | .icon-cc-pd:before { 1954 | content: '\e8e7'; 1955 | } 1956 | 1957 | /* '' */ 1958 | .icon-cc-zero:before { 1959 | content: '\e8e8'; 1960 | } 1961 | 1962 | /* '' */ 1963 | .icon-cc-share:before { 1964 | content: '\e8e9'; 1965 | } 1966 | 1967 | /* '' */ 1968 | .icon-cc-remix:before { 1969 | content: '\e8ea'; 1970 | } 1971 | 1972 | /* '' */ 1973 | .icon-github:before { 1974 | content: '\e8eb'; 1975 | } 1976 | 1977 | /* '' */ 1978 | .icon-github-circled:before { 1979 | content: '\e8ec'; 1980 | } 1981 | 1982 | /* '' */ 1983 | .icon-flickr:before { 1984 | content: '\e8ed'; 1985 | } 1986 | 1987 | /* '' */ 1988 | .icon-flickr-circled:before { 1989 | content: '\e8ee'; 1990 | } 1991 | 1992 | /* '' */ 1993 | .icon-vimeo:before { 1994 | content: '\e8ef'; 1995 | } 1996 | 1997 | /* '' */ 1998 | .icon-vimeo-circled:before { 1999 | content: '\e8f0'; 2000 | } 2001 | 2002 | /* '' */ 2003 | .icon-twitter:before { 2004 | content: '\e8f1'; 2005 | } 2006 | 2007 | /* '' */ 2008 | .icon-twitter-circled:before { 2009 | content: '\e8f2'; 2010 | } 2011 | 2012 | /* '' */ 2013 | .icon-facebook:before { 2014 | content: '\e8f3'; 2015 | } 2016 | 2017 | /* '' */ 2018 | .icon-facebook-circled:before { 2019 | content: '\e8f4'; 2020 | } 2021 | 2022 | /* '' */ 2023 | .icon-facebook-squared:before { 2024 | content: '\e8f5'; 2025 | } 2026 | 2027 | /* '' */ 2028 | .icon-gplus:before { 2029 | content: '\e8f6'; 2030 | } 2031 | 2032 | /* '' */ 2033 | .icon-gplus-circled:before { 2034 | content: '\e8f7'; 2035 | } 2036 | 2037 | /* '' */ 2038 | .icon-pinterest:before { 2039 | content: '\e8f8'; 2040 | } 2041 | 2042 | /* '' */ 2043 | .icon-pinterest-circled:before { 2044 | content: '\e8f9'; 2045 | } 2046 | 2047 | /* '' */ 2048 | .icon-tumblr:before { 2049 | content: '\e8fa'; 2050 | } 2051 | 2052 | /* '' */ 2053 | .icon-tumblr-circled:before { 2054 | content: '\e8fb'; 2055 | } 2056 | 2057 | /* '' */ 2058 | .icon-linkedin:before { 2059 | content: '\e8fc'; 2060 | } 2061 | 2062 | /* '' */ 2063 | .icon-linkedin-circled:before { 2064 | content: '\e8fd'; 2065 | } 2066 | 2067 | /* '' */ 2068 | .icon-dribbble:before { 2069 | content: '\e8fe'; 2070 | } 2071 | 2072 | /* '' */ 2073 | .icon-dribbble-circled:before { 2074 | content: '\e8ff'; 2075 | } 2076 | 2077 | /* '' */ 2078 | .icon-stumbleupon:before { 2079 | content: '\e900'; 2080 | } 2081 | 2082 | /* '' */ 2083 | .icon-stumbleupon-circled:before { 2084 | content: '\e901'; 2085 | } 2086 | 2087 | /* '' */ 2088 | .icon-lastfm:before { 2089 | content: '\e902'; 2090 | } 2091 | 2092 | /* '' */ 2093 | .icon-lastfm-circled:before { 2094 | content: '\e903'; 2095 | } 2096 | 2097 | /* '' */ 2098 | .icon-rdio:before { 2099 | content: '\e904'; 2100 | } 2101 | 2102 | /* '' */ 2103 | .icon-rdio-circled:before { 2104 | content: '\e905'; 2105 | } 2106 | 2107 | /* '' */ 2108 | .icon-spotify:before { 2109 | content: '\e906'; 2110 | } 2111 | 2112 | /* '' */ 2113 | .icon-spotify-circled:before { 2114 | content: '\e907'; 2115 | } 2116 | 2117 | /* '' */ 2118 | .icon-qq:before { 2119 | content: '\e908'; 2120 | } 2121 | 2122 | /* '' */ 2123 | .icon-instagram:before { 2124 | content: '\e909'; 2125 | } 2126 | 2127 | /* '' */ 2128 | .icon-dropbox:before { 2129 | content: '\e90a'; 2130 | } 2131 | 2132 | /* '' */ 2133 | .icon-evernote:before { 2134 | content: '\e90b'; 2135 | } 2136 | 2137 | /* '' */ 2138 | .icon-flattr:before { 2139 | content: '\e90c'; 2140 | } 2141 | 2142 | /* '' */ 2143 | .icon-skype:before { 2144 | content: '\e90d'; 2145 | } 2146 | 2147 | /* '' */ 2148 | .icon-skype-circled:before { 2149 | content: '\e90e'; 2150 | } 2151 | 2152 | /* '' */ 2153 | .icon-renren:before { 2154 | content: '\e90f'; 2155 | } 2156 | 2157 | /* '' */ 2158 | .icon-sina-weibo:before { 2159 | content: '\e910'; 2160 | } 2161 | 2162 | /* '' */ 2163 | .icon-paypal:before { 2164 | content: '\e911'; 2165 | } 2166 | 2167 | /* '' */ 2168 | .icon-picasa:before { 2169 | content: '\e912'; 2170 | } 2171 | 2172 | /* '' */ 2173 | .icon-soundcloud:before { 2174 | content: '\e913'; 2175 | } 2176 | 2177 | /* '' */ 2178 | .icon-mixi:before { 2179 | content: '\e914'; 2180 | } 2181 | 2182 | /* '' */ 2183 | .icon-behance:before { 2184 | content: '\e915'; 2185 | } 2186 | 2187 | /* '' */ 2188 | .icon-google-circles:before { 2189 | content: '\e916'; 2190 | } 2191 | 2192 | /* '' */ 2193 | .icon-vkontakte:before { 2194 | content: '\e917'; 2195 | } 2196 | 2197 | /* '' */ 2198 | .icon-smashing:before { 2199 | content: '\e918'; 2200 | } 2201 | 2202 | /* '' */ 2203 | .icon-sweden:before { 2204 | content: '\e919'; 2205 | } 2206 | 2207 | /* '' */ 2208 | .icon-db-shape:before { 2209 | content: '\e91a'; 2210 | } 2211 | 2212 | /* '' */ 2213 | .icon-logo-db:before { 2214 | content: '\e91b'; 2215 | } 2216 | 2217 | /* '' */ 2218 | table { 2219 | width: 100%; 2220 | border: 0; 2221 | border-collapse: separate; 2222 | font-size: 12px; 2223 | text-align: left; 2224 | } 2225 | 2226 | thead { 2227 | background-color: #f5f5f4; 2228 | } 2229 | 2230 | tbody { 2231 | background-color: #fff; 2232 | } 2233 | 2234 | .table-striped tr:nth-child(even) { 2235 | background-color: #f5f5f4; 2236 | } 2237 | 2238 | tr:active, 2239 | .table-striped tr:active:nth-child(even) { 2240 | color: #fff; 2241 | background-color: #116cd6; 2242 | } 2243 | 2244 | .table-striped tr.selected { 2245 | color: #fff; 2246 | background-color: #116cd6; 2247 | } 2248 | 2249 | thead tr:active { 2250 | color: #333; 2251 | background-color: #f5f5f4; 2252 | } 2253 | 2254 | th { 2255 | font-weight: normal; 2256 | border-right: 1px solid #ddd; 2257 | border-bottom: 1px solid #ddd; 2258 | } 2259 | 2260 | th, 2261 | td { 2262 | padding: 2px 15px; 2263 | white-space: nowrap; 2264 | overflow: hidden; 2265 | text-overflow: ellipsis; 2266 | } 2267 | th:last-child, 2268 | td:last-child { 2269 | border-right: 0; 2270 | } 2271 | 2272 | .tab-group { 2273 | margin-top: -1px; 2274 | display: flex; 2275 | border-top: 1px solid #989698; 2276 | border-bottom: 1px solid #989698; 2277 | } 2278 | 2279 | .tab-item { 2280 | position: relative; 2281 | flex: 1; 2282 | padding: 3px; 2283 | font-size: 12px; 2284 | text-align: center; 2285 | border-left: 1px solid #989698; 2286 | background-color: #b8b6b8; 2287 | background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #b8b6b8), color-stop(100%, #b0aeb0)); 2288 | background-image: -webkit-linear-gradient(top, #b8b6b8 0%, #b0aeb0 100%); 2289 | background-image: linear-gradient(to bottom, #b8b6b8 0%, #b0aeb0 100%); 2290 | } 2291 | .tab-item:first-child { 2292 | border-left: 0; 2293 | } 2294 | .tab-item.active { 2295 | background-color: #d4d2d4; 2296 | background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #d4d2d4), color-stop(100%, #cccacc)); 2297 | background-image: -webkit-linear-gradient(top, #d4d2d4 0%, #cccacc 100%); 2298 | background-image: linear-gradient(to bottom, #d4d2d4 0%, #cccacc 100%); 2299 | } 2300 | .tab-item .icon-close-tab { 2301 | position: absolute; 2302 | top: 50%; 2303 | left: 5px; 2304 | width: 15px; 2305 | height: 15px; 2306 | font-size: 15px; 2307 | line-height: 15px; 2308 | text-align: center; 2309 | color: #666; 2310 | opacity: 0; 2311 | transition: opacity .1s linear, background-color .1s linear; 2312 | border-radius: 3px; 2313 | transform: translateY(-50%); 2314 | z-index: 10; 2315 | } 2316 | .tab-item:after { 2317 | position: absolute; 2318 | top: 0; 2319 | right: 0; 2320 | bottom: 0; 2321 | left: 0; 2322 | content: ""; 2323 | background-color: rgba(0, 0, 0, 0.08); 2324 | opacity: 0; 2325 | transition: opacity .1s linear; 2326 | z-index: 1; 2327 | } 2328 | .tab-item:hover:not(.active):after { 2329 | opacity: 1; 2330 | } 2331 | .tab-item:hover .icon-close-tab { 2332 | opacity: 1; 2333 | } 2334 | .tab-item .icon-close-tab:hover { 2335 | background-color: rgba(0, 0, 0, 0.08); 2336 | } 2337 | 2338 | .tab-item-fixed { 2339 | flex: none; 2340 | padding: 3px 10px; 2341 | } 2342 | --------------------------------------------------------------------------------