├── dist
├── web
│ └── .gitkeep
└── electron
│ └── .gitkeep
├── static
└── .gitkeep
├── src
├── renderer
│ ├── assets
│ │ ├── .gitkeep
│ │ ├── avatar.png
│ │ ├── photon
│ │ │ ├── fonts
│ │ │ │ ├── photon-entypo.eot
│ │ │ │ ├── photon-entypo.ttf
│ │ │ │ └── photon-entypo.woff
│ │ │ └── css
│ │ │ │ ├── photon.min.css
│ │ │ │ └── photon.css
│ │ └── bin-packing
│ │ │ ├── packer.js
│ │ │ └── packer.growing.js
│ ├── store
│ │ ├── index.js
│ │ └── modules
│ │ │ ├── index.js
│ │ │ ├── Setting.js
│ │ │ ├── App.js
│ │ │ └── BMPList.js
│ ├── router
│ │ └── index.js
│ ├── main.js
│ ├── components
│ │ ├── Help.vue
│ │ ├── BMPList.vue
│ │ └── Setting.vue
│ └── App.vue
├── main
│ ├── index.dev.js
│ └── index.js
└── index.ejs
├── .eslintignore
├── donate.png
├── untitiled.png
├── images
└── usage.png
├── .gitignore
├── .vscode
└── settings.json
├── .travis.yml
├── appveyor.yml
├── .eslintrc.js
├── README.md
├── untitiled.xml
├── LICENSE
├── .electron-vue
├── dev-client.js
├── webpack.main.config.js
├── build.js
├── webpack.web.config.js
├── dev-runner.js
└── webpack.renderer.config.js
├── .babelrc
└── package.json
/dist/web/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/static/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/dist/electron/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/renderer/assets/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.eslintignore:
--------------------------------------------------------------------------------
1 | src/renderer/assets/
2 |
--------------------------------------------------------------------------------
/donate.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/elisaday/bmfont-js/HEAD/donate.png
--------------------------------------------------------------------------------
/untitiled.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/elisaday/bmfont-js/HEAD/untitiled.png
--------------------------------------------------------------------------------
/images/usage.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/elisaday/bmfont-js/HEAD/images/usage.png
--------------------------------------------------------------------------------
/src/renderer/assets/avatar.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/elisaday/bmfont-js/HEAD/src/renderer/assets/avatar.png
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | dist/
3 | build/*
4 | !build/icons
5 | node_modules/
6 | npm-debug.log
7 | npm-debug.log.*
8 | thumbs.db
9 | !.gitkeep
10 |
--------------------------------------------------------------------------------
/src/renderer/assets/photon/fonts/photon-entypo.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/elisaday/bmfont-js/HEAD/src/renderer/assets/photon/fonts/photon-entypo.eot
--------------------------------------------------------------------------------
/src/renderer/assets/photon/fonts/photon-entypo.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/elisaday/bmfont-js/HEAD/src/renderer/assets/photon/fonts/photon-entypo.ttf
--------------------------------------------------------------------------------
/src/renderer/assets/photon/fonts/photon-entypo.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/elisaday/bmfont-js/HEAD/src/renderer/assets/photon/fonts/photon-entypo.woff
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "editor.insertSpaces": true,
3 | "editor.tabSize": 2,
4 |
5 | "eslint.validate": [
6 | "javascript",
7 | "javascriptreact",
8 | "vue"
9 | ],
10 |
11 | "editor.codeActionsOnSave": {
12 | "source.fixAll.eslint": true
13 | }
14 | }
--------------------------------------------------------------------------------
/src/renderer/store/index.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import Vuex from 'vuex'
3 |
4 | import {
5 | createPersistedState
6 | // createSharedMutations
7 | } from 'vuex-electron'
8 |
9 | import modules from './modules'
10 |
11 | Vue.use(Vuex)
12 |
13 | export default new Vuex.Store({
14 | modules,
15 | plugins: [
16 | createPersistedState()
17 | // createSharedMutations()
18 | ],
19 | strict: process.env.NODE_ENV !== 'production'
20 | })
21 |
--------------------------------------------------------------------------------
/src/renderer/store/modules/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * The file enables `@/store/index.js` to import all vuex modules
3 | * in a one-shot manner. There should not be any reason to edit this file.
4 | */
5 |
6 | const files = require.context('.', false, /\.js$/)
7 | const modules = {}
8 |
9 | files.keys().forEach(key => {
10 | if (key === './index.js') return
11 | modules[key.replace(/(\.\/|\.js)/g, '')] = files(key).default
12 | })
13 |
14 | export default modules
15 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | matrix:
2 | include:
3 | - os: osx
4 | osx_image: xcode12.2
5 | language: node_js
6 | node_js: "14"
7 |
8 | - os: windows
9 | language: node_js
10 | node_js: "14"
11 |
12 | - os: linux
13 | language: node_js
14 | node_js: "14"
15 |
16 | cache:
17 | directories:
18 | - node_modules
19 | - $HOME/.cache/electron
20 | - $HOME/.cache/electron-builder
21 |
22 | script:
23 | npm install
24 | npm run build
25 |
26 | branches:
27 | only:
28 | - master
--------------------------------------------------------------------------------
/appveyor.yml:
--------------------------------------------------------------------------------
1 | version: 0.1.{build}
2 |
3 | branches:
4 | only:
5 | - master
6 |
7 | image: Visual Studio 2017
8 | platform:
9 | - x64
10 |
11 | cache:
12 | - node_modules
13 | - '%APPDATA%\npm-cache'
14 | - '%USERPROFILE%\.electron'
15 | - '%USERPROFILE%\AppData\Local\Yarn\cache'
16 |
17 | init:
18 | - git config --global core.autocrlf input
19 |
20 | install:
21 | - ps: Install-Product node 8 x64
22 | - git reset --hard HEAD
23 | - yarn
24 | - node --version
25 |
26 | build_script:
27 | - yarn build
28 |
29 | test: off
30 |
--------------------------------------------------------------------------------
/src/renderer/router/index.js:
--------------------------------------------------------------------------------
1 |
2 | const BMPList = r => require.ensure([], () => r(require('@/components/BMPList')), 'BMPList')
3 | const Setting = r => require.ensure([], () => r(require('@/components/Setting')), 'Setting')
4 | const Help = r => require.ensure([], () => r(require('@/components/Help')), 'Help')
5 |
6 | export default [
7 | {
8 | path: '/bmp-list',
9 | component: BMPList
10 | },
11 | {
12 | path: '/setting',
13 | component: Setting
14 | },
15 | {
16 | path: '/help',
17 | component: Help
18 | },
19 | {
20 | path: '*',
21 | redirect: '/help'
22 | }
23 | ]
24 |
--------------------------------------------------------------------------------
/src/renderer/main.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import VueRouter from 'vue-router'
3 |
4 | import App from './App'
5 | import routes from './router'
6 | import store from './store'
7 |
8 | import '@/assets/photon/css/photon.css'
9 |
10 | const process = require('process')
11 |
12 | if (!process.env.IS_WEB) Vue.use(require('vue-electron'))
13 | Vue.config.productionTip = false
14 |
15 | Vue.use(VueRouter)
16 |
17 | const router = new VueRouter({
18 | routes: routes
19 | })
20 |
21 | /* eslint-disable no-new */
22 | new Vue({
23 | components: { App },
24 | router,
25 | store,
26 | template: ' '
27 | }).$mount('#app')
28 |
--------------------------------------------------------------------------------
/src/main/index.dev.js:
--------------------------------------------------------------------------------
1 | /**
2 | * This file is used specifically and only for development. It installs
3 | * `electron-debug` & `vue-devtools`. There shouldn't be any need to
4 | * modify this file, but it can be used to extend your development
5 | * environment.
6 | */
7 |
8 | /* eslint-disable */
9 |
10 | // Install `electron-debug` with `devtron`
11 | require('electron-debug')({ showDevTools: true })
12 |
13 | // Install `vue-devtools`
14 | require('electron').app.on('ready', () => {
15 | let installExtension = require('electron-devtools-installer')
16 | installExtension.default(installExtension.VUEJS_DEVTOOLS)
17 | .then(() => {})
18 | .catch(err => {
19 | console.log('Unable to install `vue-devtools`: \n', err)
20 | })
21 | })
22 |
23 | // Require `main` process to boot app
24 | require('./index')
--------------------------------------------------------------------------------
/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | root: true,
3 | parser: 'vue-eslint-parser',
4 | parserOptions: {
5 | parser: 'babel-eslint',
6 | sourceType: 'module'
7 | },
8 | env: {
9 | browser: true,
10 | node: true
11 | },
12 | extends: [
13 | 'plugin:vue/recommended',
14 | 'standard'
15 | ],
16 | globals: {
17 | __static: true
18 | },
19 | plugins: [
20 | 'vue'
21 | ],
22 | rules: {
23 | 'no-async-promise-executor': 0,
24 | // "no-new": 0,
25 | // "no-trailing-spaces": 0,
26 | // "comma-dangle": 0,
27 | // allow paren-less arrow functions
28 | 'arrow-parens': 0,
29 | // allow async-await
30 | 'generator-star-spacing': 0,
31 | // allow debugger during development
32 | 'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # bmfont-js
2 |
3 | [1]: https://api.travis-ci.org/elisaday/bmfont-js.svg?branch=master
4 | [2]: https://travis-ci.org/elisaday/bmfont-js
5 | [3]: https://img.shields.io/badge/code_style-standard-brightgreen.svg
6 | [4]: https://standardjs.com
7 |
8 | [![Build Status][1]][2] [![JavaScript Style Guide][3]][4]
9 |
10 | 用Electron制作的BMFont,虽然比原版BMFont功能少,但是更加好用。
11 |
12 | ---
13 |
14 | ## 发布包下载
15 | [最新版本](https://github.com/elisaday/bmfont-js/releases/latest)
16 |
17 | 遇到问题欢迎到Issus中讨论。
18 |
19 | ---
20 |
21 | ## 使用方法
22 |
23 | 
24 |
25 | ---
26 |
27 | ## 运行方法
28 |
29 | ``` bash
30 | # install dependencies
31 | npm install
32 |
33 | # serve with hot reload at localhost:9080
34 | npm run dev
35 |
36 | ```
37 |
38 | ---
39 |
40 | 
41 |
42 | 欢迎使用支付宝扫描上方二维码进行捐赠,捐赠款项将用于后续开发和维护。
43 |
44 | 谢谢关注
45 |
--------------------------------------------------------------------------------
/src/index.ejs:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | bmfont-js
6 | <% if (htmlWebpackPlugin.options.nodeModules) { %>
7 |
8 |
11 | <% } %>
12 |
13 |
14 |
15 |
16 | <% if (!require('process').browser) { %>
17 |
20 | <% } %>
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/untitiled.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2018 Zeb
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/.electron-vue/dev-client.js:
--------------------------------------------------------------------------------
1 | const hotClient = require('webpack-hot-middleware/client?noInfo=true&reload=true')
2 |
3 | hotClient.subscribe(event => {
4 | /**
5 | * Reload browser when HTMLWebpackPlugin emits a new index.html
6 | *
7 | * Currently disabled until jantimon/html-webpack-plugin#680 is resolved.
8 | * https://github.com/SimulatedGREG/electron-vue/issues/437
9 | * https://github.com/jantimon/html-webpack-plugin/issues/680
10 | */
11 | // if (event.action === 'reload') {
12 | // window.location.reload()
13 | // }
14 |
15 | /**
16 | * Notify `mainWindow` when `main` process is compiling,
17 | * giving notice for an expected reload of the `electron` process
18 | */
19 | if (event.action === 'compiling') {
20 | document.body.innerHTML += `
21 |
34 |
35 |
36 | Compiling Main Process...
37 |
38 | `
39 | }
40 | })
41 |
--------------------------------------------------------------------------------
/.electron-vue/webpack.main.config.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | process.env.BABEL_ENV = 'main'
4 |
5 | const path = require('path')
6 | const { dependencies } = require('../package.json')
7 | const webpack = require('webpack')
8 |
9 | const MinifyPlugin = require("babel-minify-webpack-plugin")
10 |
11 | let mainConfig = {
12 | entry: {
13 | main: path.join(__dirname, '../src/main/index.js')
14 | },
15 | externals: [
16 | ...Object.keys(dependencies || {})
17 | ],
18 | module: {
19 | rules: [
20 | {
21 | test: /\.(js)$/,
22 | enforce: 'pre',
23 | exclude: /node_modules/,
24 | use: {
25 | loader: 'eslint-loader',
26 | options: {
27 | formatter: require('eslint-friendly-formatter')
28 | }
29 | }
30 | },
31 | {
32 | test: /\.js$/,
33 | use: 'babel-loader',
34 | exclude: /node_modules/
35 | },
36 | {
37 | test: /\.node$/,
38 | use: 'node-loader'
39 | }
40 | ]
41 | },
42 | node: {
43 | __dirname: process.env.NODE_ENV !== 'production',
44 | __filename: process.env.NODE_ENV !== 'production'
45 | },
46 | output: {
47 | filename: '[name].js',
48 | libraryTarget: 'commonjs2',
49 | path: path.join(__dirname, '../dist/electron')
50 | },
51 | plugins: [
52 | new webpack.NoEmitOnErrorsPlugin()
53 | ],
54 | resolve: {
55 | extensions: ['.js', '.json', '.node']
56 | },
57 | target: 'electron-main'
58 | }
59 |
60 | /**
61 | * Adjust mainConfig for development settings
62 | */
63 | if (process.env.NODE_ENV !== 'production') {
64 | mainConfig.plugins.push(
65 | new webpack.DefinePlugin({
66 | '__static': `"${path.join(__dirname, '../static').replace(/\\/g, '\\\\')}"`
67 | })
68 | )
69 | }
70 |
71 | /**
72 | * Adjust mainConfig for production settings
73 | */
74 | if (process.env.NODE_ENV === 'production') {
75 | mainConfig.plugins.push(
76 | new MinifyPlugin(),
77 | new webpack.DefinePlugin({
78 | 'process.env.NODE_ENV': '"production"'
79 | })
80 | )
81 | }
82 |
83 | module.exports = mainConfig
84 |
--------------------------------------------------------------------------------
/src/renderer/store/modules/Setting.js:
--------------------------------------------------------------------------------
1 | const state = {
2 | padding: 1,
3 | NPower2: true,
4 | sameWH: true,
5 | autoSize: true,
6 | textureWidth: 1024,
7 | textureHeight: 1024,
8 | outputPath: 'untitiled.png',
9 | packAlgo: 'Bin-Packing'
10 | }
11 |
12 | const mutations = {
13 | LOAD (state, save) {
14 | save = save.setting
15 | if (save !== undefined) {
16 | if (save.padding !== undefined) state.padding = Number(save.padding)
17 | if (save.NPower2 !== undefined) state.NPower2 = save.NPower2
18 | if (save.sameWH !== undefined) state.sameWH = save.sameWH
19 | if (save.autoSize !== undefined) state.autoSize = save.autoSize
20 | if (save.textureWidth !== undefined) state.textureWidth = save.textureWidth
21 | if (save.textureHeight !== undefined) state.textureHeight = save.textureHeight
22 | if (save.outputPath !== undefined) state.outputPath = save.outputPath
23 | if (save.packAlgo !== undefined) state.packAlgo = save.packAlgo
24 | }
25 | },
26 | ON_NEW_PROJ (state) {
27 | state.padding = 1
28 | state.NPower2 = true
29 | state.sameWH = true
30 | state.autoSize = true
31 | state.textureWidth = 1024
32 | state.textureHeight = 1024
33 | state.outputPath = 'untitiled.png'
34 | state.packAlgo = 'Bin-Packing'
35 | },
36 | ENABLE_AUTO_SIZE (state, autoSize) {
37 | state.autoSize = autoSize
38 | },
39 | SET_TEXTURE_WIDTH (state, width) {
40 | state.textureWidth = Number(width)
41 | },
42 | SET_TEXTURE_HEIGHT (state, height) {
43 | state.textureHeight = Number(height)
44 | },
45 | SET_PADDING (state, padding) {
46 | state.padding = Number(padding)
47 | },
48 | ENABLE_NPOWER2 (state, enabled) {
49 | state.NPower2 = enabled
50 | },
51 | ENABLE_SAME_WH (state, enabled) {
52 | state.sameWH = enabled
53 | },
54 | SET_OUTPUT_PATH (state, outputPath) {
55 | state.outputPath = outputPath
56 | },
57 | SET_PACK_ALGO (state, algo) {
58 | state.packAlgo = algo
59 | }
60 | }
61 |
62 | const actions = {
63 | }
64 |
65 | export default {
66 | state,
67 | mutations,
68 | actions
69 | }
70 |
--------------------------------------------------------------------------------
/src/renderer/assets/bin-packing/packer.js:
--------------------------------------------------------------------------------
1 | /******************************************************************************
2 |
3 | This is a very simple binary tree based bin packing algorithm that is initialized
4 | with a fixed width and height and will fit each block into the first node where
5 | it fits and then split that node into 2 parts (down and right) to track the
6 | remaining whitespace.
7 |
8 | Best results occur when the input blocks are sorted by height, or even better
9 | when sorted by max(width,height).
10 |
11 | Inputs:
12 | ------
13 |
14 | w: width of target rectangle
15 | h: height of target rectangle
16 | blocks: array of any objects that have .w and .h attributes
17 |
18 | Outputs:
19 | -------
20 |
21 | marks each block that fits with a .fit attribute pointing to a
22 | node with .x and .y coordinates
23 |
24 | Example:
25 | -------
26 |
27 | var blocks = [
28 | { w: 100, h: 100 },
29 | { w: 100, h: 100 },
30 | { w: 80, h: 80 },
31 | { w: 80, h: 80 },
32 | etc
33 | etc
34 | ];
35 |
36 | var packer = new Packer(500, 500);
37 | packer.fit(blocks);
38 |
39 | for(var n = 0 ; n < blocks.length ; n++) {
40 | var block = blocks[n];
41 | if (block.fit) {
42 | Draw(block.fit.x, block.fit.y, block.w, block.h);
43 | }
44 | }
45 |
46 |
47 | ******************************************************************************/
48 |
49 | Packer = function(w, h) {
50 | this.init(w, h);
51 | };
52 |
53 | Packer.prototype = {
54 |
55 | init: function(w, h) {
56 | this.root = { x: 0, y: 0, w: w, h: h };
57 | },
58 |
59 | fit: function(blocks) {
60 | var n, node, block;
61 | for (n = 0; n < blocks.length; n++) {
62 | block = blocks[n];
63 | if (node = this.findNode(this.root, block.w, block.h))
64 | block.fit = this.splitNode(node, block.w, block.h);
65 | }
66 | },
67 |
68 | findNode: function(root, w, h) {
69 | if (root.used)
70 | return this.findNode(root.right, w, h) || this.findNode(root.down, w, h);
71 | else if ((w <= root.w) && (h <= root.h))
72 | return root;
73 | else
74 | return null;
75 | },
76 |
77 | splitNode: function(node, w, h) {
78 | node.used = true;
79 | node.down = { x: node.x, y: node.y + h, w: node.w, h: node.h - h };
80 | node.right = { x: node.x + w, y: node.y, w: node.w - w, h: h };
81 | return node;
82 | }
83 |
84 | }
85 |
86 | module.exports = Packer
--------------------------------------------------------------------------------
/src/renderer/components/Help.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | 点击
6 |
10 |
11 |
12 | 切换到设置面板,设置好各项参数
13 |
14 |
15 | 点击
16 |
20 |
21 |
22 | 切换到图片列表,编辑字符图片
23 |
24 |
25 | 点击
26 |
27 |
28 |
29 | 发布字体配置和合并后的贴图
30 |
31 |
32 | 点击
33 |
37 |
38 |
39 | 返回这里的帮助页面
40 |
41 |
42 |
43 |
44 |
45 |
46 |
50 |
51 | Github
52 |
53 |
57 |
58 | E-Mail
59 |
60 |
61 |
62 |
63 |
64 |
96 |
97 |
137 |
--------------------------------------------------------------------------------
/src/main/index.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | import { app, BrowserWindow, Menu } from 'electron'
4 | const path = require('path')
5 | const ipcMain = require('electron').ipcMain
6 |
7 | /**
8 | * Set `__static` path to static files in production
9 | * https://simulatedgreg.gitbooks.io/electron-vue/content/en/using-static-assets.html
10 | */
11 | let showDevTools = true
12 | if (process.env.NODE_ENV !== 'development') {
13 | global.__static = require('path').join(__dirname, '/static').replace(/\\/g, '\\\\')
14 | showDevTools = false
15 | }
16 |
17 | let mainWindow
18 | const winURL = process.env.NODE_ENV === 'development'
19 | ? 'http://localhost:9080'
20 | : path.join('file://', __dirname, '/index.html')
21 |
22 | if (process.platform === 'darwin') {
23 | const template = [
24 | {
25 | label: 'Application',
26 | submenu: [
27 | { label: 'Quit', accelerator: 'Command+Q', click: function () { app.quit() } }
28 | ]
29 | },
30 | {
31 | label: 'Edit',
32 | submenu: [
33 | { label: 'Copy', accelerator: 'CmdOrCtrl+C', selector: 'copy:' },
34 | { label: 'Paste', accelerator: 'CmdOrCtrl+V', selector: 'paste:' }
35 | ]
36 | }
37 | ]
38 | Menu.setApplicationMenu(Menu.buildFromTemplate(template))
39 | } else {
40 | Menu.setApplicationMenu(null)
41 | }
42 |
43 | function createWindow () {
44 | /**
45 | * Initial window options
46 | */
47 | mainWindow = new BrowserWindow({
48 | useContentSize: true,
49 | width: 1440,
50 | height: 800,
51 | minWidth: 600,
52 | minHeight: 400,
53 | acceptFirstMouse: true,
54 | titleBarStyle: 'hidden',
55 | frame: false,
56 | webPreferences: {
57 | nodeIntegration: true,
58 | devTools: showDevTools,
59 | webviewTag: true,
60 | enableRemoteModule: true
61 | }
62 | })
63 |
64 | mainWindow.loadURL(winURL)
65 |
66 | mainWindow.on('closed', () => {
67 | mainWindow = null
68 | })
69 |
70 | mainWindow.on('focus', (event) => {
71 | event.sender.send('focus')
72 | })
73 | }
74 |
75 | app.on('ready', createWindow)
76 |
77 | app.on('window-all-closed', () => {
78 | if (process.platform !== 'darwin') {
79 | app.quit()
80 | }
81 | })
82 |
83 | app.on('activate', () => {
84 | if (mainWindow === null) {
85 | createWindow()
86 | }
87 | })
88 |
89 | ipcMain.on('window-min', function () {
90 | mainWindow.minimize()
91 | })
92 |
93 | // 接收最大化命令
94 | ipcMain.on('window-max', function () {
95 | if (mainWindow.isMaximized()) {
96 | mainWindow.restore()
97 | } else {
98 | mainWindow.maximize()
99 | }
100 | })
101 |
102 | // 接收关闭命令
103 | ipcMain.on('window-close', function () {
104 | mainWindow.close()
105 | })
106 |
107 | /**
108 | * Auto Updater
109 | *
110 | * Uncomment the following code below and install `electron-updater` to
111 | * support auto updating. Code Signing with a valid certificate is required.
112 | * https://simulatedgreg.gitbooks.io/electron-vue/content/en/using-electron-builder.html#auto-updating
113 | */
114 |
115 | /*
116 | import { autoUpdater } from 'electron-updater'
117 |
118 | autoUpdater.on('update-downloaded', () => {
119 | autoUpdater.quitAndInstall()
120 | })
121 |
122 | app.on('ready', () => {
123 | if (process.env.NODE_ENV === 'production') autoUpdater.checkForUpdates()
124 | })
125 | */
126 |
--------------------------------------------------------------------------------
/src/renderer/components/BMPList.vue:
--------------------------------------------------------------------------------
1 |
2 |
55 |
56 |
57 |
115 |
116 |
136 |
--------------------------------------------------------------------------------
/.electron-vue/build.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | process.env.NODE_ENV = 'production'
4 |
5 | const { say } = require('cfonts')
6 | const chalk = require('chalk')
7 | const del = require('del')
8 | const { spawn } = require('child_process')
9 | const webpack = require('webpack')
10 | const Multispinner = require('multispinner')
11 |
12 |
13 | const mainConfig = require('./webpack.main.config')
14 | const rendererConfig = require('./webpack.renderer.config')
15 | const webConfig = require('./webpack.web.config')
16 |
17 | const doneLog = chalk.bgGreen.white(' DONE ') + ' '
18 | const errorLog = chalk.bgRed.white(' ERROR ') + ' '
19 | const okayLog = chalk.bgBlue.white(' OKAY ') + ' '
20 | const isCI = process.env.CI || false
21 |
22 | if (process.env.BUILD_TARGET === 'clean') clean()
23 | else if (process.env.BUILD_TARGET === 'web') web()
24 | else build()
25 |
26 | function clean () {
27 | del.sync(['build/*', '!build/icons', '!build/icons/icon.*'])
28 | console.log(`\n${doneLog}\n`)
29 | process.exit()
30 | }
31 |
32 | function build () {
33 | greeting()
34 |
35 | del.sync(['dist/electron/*', '!.gitkeep'])
36 |
37 | const tasks = ['main', 'renderer']
38 | const m = new Multispinner(tasks, {
39 | preText: 'building',
40 | postText: 'process'
41 | })
42 |
43 | let results = ''
44 |
45 | m.on('success', () => {
46 | process.stdout.write('\x1B[2J\x1B[0f')
47 | console.log(`\n\n${results}`)
48 | console.log(`${okayLog}take it away ${chalk.yellow('`electron-builder`')}\n`)
49 | process.exit()
50 | })
51 |
52 | pack(mainConfig).then(result => {
53 | results += result + '\n\n'
54 | m.success('main')
55 | }).catch(err => {
56 | m.error('main')
57 | console.log(`\n ${errorLog}failed to build main process`)
58 | console.error(`\n${err}\n`)
59 | process.exit(1)
60 | })
61 |
62 | pack(rendererConfig).then(result => {
63 | results += result + '\n\n'
64 | m.success('renderer')
65 | }).catch(err => {
66 | m.error('renderer')
67 | console.log(`\n ${errorLog}failed to build renderer process`)
68 | console.error(`\n${err}\n`)
69 | process.exit(1)
70 | })
71 | }
72 |
73 | function pack (config) {
74 | return new Promise((resolve, reject) => {
75 | config.mode = 'production'
76 | webpack(config, (err, stats) => {
77 | if (err) reject(err.stack || err)
78 | else if (stats.hasErrors()) {
79 | let err = ''
80 |
81 | stats.toString({
82 | chunks: false,
83 | colors: true
84 | })
85 | .split(/\r?\n/)
86 | .forEach(line => {
87 | err += ` ${line}\n`
88 | })
89 |
90 | reject(err)
91 | } else {
92 | resolve(stats.toString({
93 | chunks: false,
94 | colors: true
95 | }))
96 | }
97 | })
98 | })
99 | }
100 |
101 | function web () {
102 | del.sync(['dist/web/*', '!.gitkeep'])
103 | webConfig.mode = 'production'
104 | webpack(webConfig, (err, stats) => {
105 | if (err || stats.hasErrors()) console.log(err)
106 |
107 | console.log(stats.toString({
108 | chunks: false,
109 | colors: true
110 | }))
111 |
112 | process.exit()
113 | })
114 | }
115 |
116 | function greeting () {
117 | const cols = process.stdout.columns
118 | let text = ''
119 |
120 | if (cols > 85) text = 'lets-build'
121 | else if (cols > 60) text = 'lets-|build'
122 | else text = false
123 |
124 | if (text && !isCI) {
125 | say(text, {
126 | colors: ['yellow'],
127 | font: 'simple3d',
128 | space: false
129 | })
130 | } else console.log(chalk.yellow.bold('\n lets-build'))
131 | console.log()
132 | }
--------------------------------------------------------------------------------
/src/renderer/store/modules/App.js:
--------------------------------------------------------------------------------
1 | import { remote } from 'electron'
2 | import * as fs from 'fs'
3 | import { promisify } from 'util'
4 |
5 | const writeFile = promisify(fs.writeFile)
6 | const readFile = promisify(fs.readFile)
7 |
8 | const state = {
9 | projPathName: null,
10 | modified: false
11 | }
12 |
13 | async function saveProj (rootState, savePath) {
14 | const save = {
15 | setting: rootState.Setting,
16 | bmpList: rootState.BMPList
17 | }
18 | await writeFile(savePath, JSON.stringify(save), { encoding: 'utf8' })
19 | }
20 |
21 | async function openProj (commit) {
22 | let projPath = remote.dialog.showOpenDialog({
23 | title: '打开BMFont工程',
24 | properties: [
25 | 'openFile'
26 | ],
27 | filters: [
28 | { name: 'BMFont Project File', extensions: ['bfp'] },
29 | { name: 'All Files', extensions: ['*'] }
30 | ]
31 | })
32 | if (projPath === undefined) return
33 |
34 | projPath = projPath[0]
35 |
36 | try {
37 | const data = await readFile(projPath, { encoding: 'utf8' })
38 | const json = JSON.parse(data)
39 | commit('LOAD', json)
40 | commit('ON_PROJ_SAVED', projPath)
41 | } catch (e) {
42 | console.log(e)
43 | }
44 | }
45 |
46 | async function checkProjModified () {
47 | if (state.modified) {
48 | const choice = remote.dialog.showMessageBox({
49 | type: 'question',
50 | title: 'BMFont.js',
51 | message: '工程已经更改,是否保存当前工程?',
52 | defaultId: 0,
53 | noLink: true,
54 | buttons: ['保存', '不保存', '取消']
55 | })
56 | return choice
57 | } else {
58 | return 1
59 | }
60 | }
61 |
62 | function confirmExit () {
63 | const choice = remote.dialog.showMessageBox({
64 | type: 'question',
65 | title: 'BMFont.js',
66 | message: '确定要退出吗?',
67 | defaultId: 0,
68 | noLink: true,
69 | buttons: ['退出', '取消']
70 | })
71 | if (choice === 0) {
72 | remote.getCurrentWindow().close()
73 | }
74 | }
75 |
76 | const mutations = {
77 | ON_NEW_PROJ (state) {
78 | state.projPathName = null
79 | state.modified = false
80 | },
81 |
82 | ON_PROJ_MODIFIED (state) {
83 | if (state.projPathName === null) {
84 | state.projPathName = '未命名'
85 | }
86 | state.modified = true
87 | },
88 |
89 | ON_PROJ_SAVED (state, projPathName) {
90 | state.projPathName = projPathName
91 | state.modified = false
92 | }
93 | }
94 |
95 | const actions = {
96 | async NEW_PROJ ({ commit, dispatch }) {
97 | const choice = await checkProjModified()
98 | if (choice === 0) {
99 | await dispatch('SAVE_PROJ')
100 | commit('ON_NEW_PROJ')
101 | } else if (choice === 1) {
102 | commit('ON_NEW_PROJ')
103 | }
104 | },
105 |
106 | async OPEN_PROJ ({ commit, dispatch }) {
107 | const choice = await checkProjModified()
108 | if (choice === 0) {
109 | await dispatch('SAVE_PROJ')
110 | openProj(commit)
111 | } else if (choice === 1) {
112 | openProj(commit)
113 | }
114 | },
115 |
116 | async SAVE_PROJ ({ state, commit, rootState }) {
117 | if (state.projPathName === null) return
118 | const savePath = remote.dialog.showSaveDialog({
119 | title: '保存BMFont工程',
120 | filters: [
121 | { name: 'BMFont Project File', extensions: ['bfp'] },
122 | { name: 'All Files', extensions: ['*'] }
123 | ]
124 | })
125 | if (savePath === undefined) return
126 | await saveProj(rootState, savePath)
127 | commit('ON_PROJ_SAVED', savePath)
128 | },
129 |
130 | async CONFIRM_EXIT ({ dispatch }) {
131 | const choice = await checkProjModified()
132 | if (choice === 0) {
133 | await dispatch('SAVE_PROJ')
134 | confirmExit()
135 | } else if (choice === 1) {
136 | confirmExit()
137 | }
138 | }
139 | }
140 |
141 | export default {
142 | state,
143 | mutations,
144 | actions
145 | }
146 |
--------------------------------------------------------------------------------
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "comments": false,
3 | "env": {
4 | "main": {
5 | "presets": [
6 | [
7 | "@babel/preset-env",
8 | {
9 | "targets": {
10 | "node": 7
11 | }
12 | }
13 | ]
14 | ],
15 | "plugins": [
16 | "@babel/plugin-syntax-dynamic-import",
17 | "@babel/plugin-syntax-import-meta",
18 | "@babel/plugin-proposal-class-properties",
19 | "@babel/plugin-proposal-json-strings",
20 | [
21 | "@babel/plugin-proposal-decorators",
22 | {
23 | "legacy": true
24 | }
25 | ],
26 | "@babel/plugin-proposal-function-sent",
27 | "@babel/plugin-proposal-export-namespace-from",
28 | "@babel/plugin-proposal-numeric-separator",
29 | "@babel/plugin-proposal-throw-expressions",
30 | "@babel/plugin-proposal-export-default-from",
31 | "@babel/plugin-proposal-logical-assignment-operators",
32 | "@babel/plugin-proposal-optional-chaining",
33 | [
34 | "@babel/plugin-proposal-pipeline-operator",
35 | {
36 | "proposal": "minimal"
37 | }
38 | ],
39 | "@babel/plugin-proposal-nullish-coalescing-operator",
40 | "@babel/plugin-proposal-do-expressions",
41 | "@babel/plugin-proposal-function-bind"
42 | ]
43 | },
44 | "renderer": {
45 | "presets": [
46 | [
47 | "@babel/preset-env",
48 | {
49 | "modules": false
50 | }
51 | ]
52 | ],
53 | "plugins": [
54 | "@babel/plugin-syntax-dynamic-import",
55 | "@babel/plugin-syntax-import-meta",
56 | "@babel/plugin-proposal-class-properties",
57 | "@babel/plugin-proposal-json-strings",
58 | [
59 | "@babel/plugin-proposal-decorators",
60 | {
61 | "legacy": true
62 | }
63 | ],
64 | "@babel/plugin-proposal-function-sent",
65 | "@babel/plugin-proposal-export-namespace-from",
66 | "@babel/plugin-proposal-numeric-separator",
67 | "@babel/plugin-proposal-throw-expressions",
68 | "@babel/plugin-proposal-export-default-from",
69 | "@babel/plugin-proposal-logical-assignment-operators",
70 | "@babel/plugin-proposal-optional-chaining",
71 | [
72 | "@babel/plugin-proposal-pipeline-operator",
73 | {
74 | "proposal": "minimal"
75 | }
76 | ],
77 | "@babel/plugin-proposal-nullish-coalescing-operator",
78 | "@babel/plugin-proposal-do-expressions",
79 | "@babel/plugin-proposal-function-bind"
80 | ]
81 | },
82 | "web": {
83 | "presets": [
84 | [
85 | "@babel/preset-env",
86 | {
87 | "modules": false
88 | }
89 | ]
90 | ],
91 | "plugins": [
92 | "@babel/plugin-syntax-dynamic-import",
93 | "@babel/plugin-syntax-import-meta",
94 | "@babel/plugin-proposal-class-properties",
95 | "@babel/plugin-proposal-json-strings",
96 | [
97 | "@babel/plugin-proposal-decorators",
98 | {
99 | "legacy": true
100 | }
101 | ],
102 | "@babel/plugin-proposal-function-sent",
103 | "@babel/plugin-proposal-export-namespace-from",
104 | "@babel/plugin-proposal-numeric-separator",
105 | "@babel/plugin-proposal-throw-expressions",
106 | "@babel/plugin-proposal-export-default-from",
107 | "@babel/plugin-proposal-logical-assignment-operators",
108 | "@babel/plugin-proposal-optional-chaining",
109 | [
110 | "@babel/plugin-proposal-pipeline-operator",
111 | {
112 | "proposal": "minimal"
113 | }
114 | ],
115 | "@babel/plugin-proposal-nullish-coalescing-operator",
116 | "@babel/plugin-proposal-do-expressions",
117 | "@babel/plugin-proposal-function-bind"
118 | ]
119 | }
120 | },
121 | "plugins": [
122 | [
123 | "@babel/plugin-transform-runtime",
124 | {
125 | "corejs": 2
126 | }
127 | ]
128 | ]
129 | }
130 |
--------------------------------------------------------------------------------
/src/renderer/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
70 |
71 |
74 |
75 |
76 |
77 |
78 |
156 |
157 |
168 |
--------------------------------------------------------------------------------
/src/renderer/store/modules/BMPList.js:
--------------------------------------------------------------------------------
1 | import { remote } from 'electron'
2 | import GrowingPacker from '@/assets/bin-packing/packer.growing.js'
3 | import Packer from '@/assets/bin-packing/packer.js'
4 | import * as path from 'path'
5 | import * as xmlbuilder from 'xmlbuilder'
6 | import * as fs from 'fs'
7 | import { promisify } from 'util'
8 | import Jimp from 'jimp/es'
9 |
10 | const writeFile = promisify(fs.writeFile)
11 |
12 | const state = {
13 | bmpList: []
14 | }
15 |
16 | function calculateSize (w, h, setting) {
17 | if (setting.NPower2) {
18 | [w, h] = expandSize(w, h)
19 | }
20 | if (setting.sameWH) {
21 | const s = Math.max(w, h)
22 | w = s
23 | h = s
24 | }
25 | return [w, h]
26 | }
27 |
28 | function packingImages (imgList, setting) {
29 | let packer
30 | let w, h
31 | if (setting.autoSize) {
32 | packer = new GrowingPacker()
33 | } else {
34 | [w, h] = calculateSize(setting.textureWidth, setting.textureHeight, setting)
35 | packer = new Packer(w, h)
36 | }
37 | const blocks = []
38 | for (const img of imgList) {
39 | blocks.push({ w: img.bitmap.width + setting.padding, h: img.bitmap.height + setting.padding })
40 | }
41 | packer.fit(blocks)
42 | if (setting.autoSize) {
43 | [w, h] = calculateSize(packer.root.w, packer.root.h, setting)
44 | }
45 | return [blocks, w, h]
46 | }
47 |
48 | function expandSize (w, h) {
49 | w = 2 ** Math.ceil(Math.log(w) / Math.log(2))
50 | h = 2 ** Math.ceil(Math.log(h) / Math.log(2))
51 | return [w, h]
52 | }
53 |
54 | function validateBlocks (blocks) {
55 | for (const b of blocks) {
56 | if (!b.fit || !b.fit.used) {
57 | return false
58 | }
59 | }
60 | return true
61 | }
62 |
63 | async function loadAllImages (bmpList) {
64 | const imgList = []
65 | for (const bmp of bmpList) {
66 | const img = await Jimp.read(bmp.filePath)
67 | imgList.push(img)
68 | }
69 | return imgList
70 | }
71 |
72 | async function saveFNT (blocks, bmpList, imgList, fntPath) {
73 | const doc = xmlbuilder.create('font')
74 | const elem = doc.ele('chars', { count: blocks.length })
75 | for (const idx in blocks) {
76 | const block = blocks[idx].fit
77 | const char = bmpList[idx].char
78 | const bmp = imgList[idx].bitmap
79 | elem.ele('char', { id: char.charCodeAt(0), x: block.x, y: block.y, width: bmp.width, height: bmp.height, xadvance: bmp.width })
80 | }
81 | const xml = elem.end({ pretty: true })
82 | await writeFile(fntPath, xml, { encoding: 'utf8' })
83 | }
84 |
85 | const mutations = {
86 | LOAD (state, save) {
87 | save = save.bmpList
88 | if (save !== undefined) {
89 | if (save.bmpList !== undefined) {
90 | for (const bmp of save.bmpList) {
91 | if (bmp.filePath !== undefined && bmp.char !== undefined) {
92 | state.bmpList.push({ filePath: bmp.filePath, char: bmp.char })
93 | }
94 | }
95 | }
96 | }
97 | },
98 |
99 | ON_NEW_PROJ (state) {
100 | state.bmpList = []
101 | },
102 |
103 | APPEND_BMP (state, { filePath, char }) {
104 | state.bmpList.push({ filePath: filePath, char: char })
105 | },
106 |
107 | REMOVE_BMP (state, index) {
108 | if (index < 0 || index >= state.bmpList.length) return
109 | state.bmpList.splice(index, 1)
110 | },
111 |
112 | CHANGE_CHAR (state, { index, char }) {
113 | if (index < 0 || index >= state.bmpList.length) return
114 | state.bmpList[index].char = char
115 | },
116 |
117 | ORDER_BY_PATH (state) {
118 | state.bmpList.sort((a, b) => {
119 | if (a.filePath < b.filePath) return -1
120 | else if (a.filePath > b.filePath) return 1
121 | return 0
122 | })
123 | }
124 | }
125 |
126 | const actions = {
127 | async PUBLISH ({ state, rootState }) {
128 | if (state.bmpList.length === 0) return
129 |
130 | const setting = rootState.Setting
131 | try {
132 | const imgList = await loadAllImages(state.bmpList)
133 | const [blocks, w, h] = packingImages(imgList, setting)
134 | if (!validateBlocks(blocks)) {
135 | remote.dialog.showErrorBox('', '贴图太小了,不能容纳所有的字符')
136 | return
137 | }
138 |
139 | const resultImg = await new Jimp(w, h)
140 | for (const idx in blocks) {
141 | const block = blocks[idx]
142 | const img = imgList[idx]
143 | resultImg.composite(img, block.fit.x, block.fit.y)
144 | }
145 | await resultImg.write(setting.outputPath)
146 | const ext = path.extname(setting.outputPath)
147 | const fntPath = setting.outputPath.substring(0, setting.outputPath.length - ext.length) + '.xml'
148 | saveFNT(blocks, state.bmpList, imgList, fntPath)
149 | } catch (e) {
150 | console.dir(e)
151 | remote.dialog.showErrorBox('', '请检查字符图片文件是否正确\n' + e.message)
152 | }
153 | }
154 | }
155 |
156 | export default {
157 | state,
158 | mutations,
159 | actions
160 | }
161 |
--------------------------------------------------------------------------------
/.electron-vue/webpack.web.config.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | process.env.BABEL_ENV = 'web'
4 |
5 | const path = require('path')
6 | const webpack = require('webpack')
7 |
8 | const MinifyPlugin = require("babel-minify-webpack-plugin")
9 | const CopyWebpackPlugin = require('copy-webpack-plugin')
10 | const MiniCssExtractPlugin = require('mini-css-extract-plugin')
11 | const HtmlWebpackPlugin = require('html-webpack-plugin')
12 | const { VueLoaderPlugin } = require('vue-loader')
13 |
14 | let webConfig = {
15 | devtool: '#cheap-module-eval-source-map',
16 | entry: {
17 | web: path.join(__dirname, '../src/renderer/main.js')
18 | },
19 | module: {
20 | rules: [
21 | {
22 | test: /\.(js|vue)$/,
23 | enforce: 'pre',
24 | exclude: /node_modules/,
25 | use: {
26 | loader: 'eslint-loader',
27 | options: {
28 | formatter: require('eslint-friendly-formatter')
29 | }
30 | }
31 | },
32 | {
33 | test: /\.scss$/,
34 | use: ['vue-style-loader', 'css-loader', 'sass-loader']
35 | },
36 | {
37 | test: /\.sass$/,
38 | use: ['vue-style-loader', 'css-loader', 'sass-loader?indentedSyntax']
39 | },
40 | {
41 | test: /\.less$/,
42 | use: ['vue-style-loader', 'css-loader', 'less-loader']
43 | },
44 | {
45 | test: /\.css$/,
46 | use: ['vue-style-loader', 'css-loader']
47 | },
48 | {
49 | test: /\.html$/,
50 | use: 'vue-html-loader'
51 | },
52 | {
53 | test: /\.js$/,
54 | use: 'babel-loader',
55 | include: [ path.resolve(__dirname, '../src/renderer') ],
56 | exclude: /node_modules/
57 | },
58 | {
59 | test: /\.vue$/,
60 | use: {
61 | loader: 'vue-loader',
62 | options: {
63 | extractCSS: true,
64 | loaders: {
65 | sass: 'vue-style-loader!css-loader!sass-loader?indentedSyntax=1',
66 | scss: 'vue-style-loader!css-loader!sass-loader',
67 | less: 'vue-style-loader!css-loader!less-loader'
68 | }
69 | }
70 | }
71 | },
72 | {
73 | test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
74 | use: {
75 | loader: 'url-loader',
76 | options: {
77 | limit: 10000,
78 | name: 'imgs/[name].[ext]',
79 | esModule: false,
80 | }
81 | }
82 | },
83 | {
84 | test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
85 | loader: 'url-loader',
86 | options: {
87 | limit: 10000,
88 | name: 'media/[name]--[folder].[ext]',
89 | esModule: false,
90 | }
91 | },
92 | {
93 | test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
94 | use: {
95 | loader: 'url-loader',
96 | options: {
97 | limit: 10000,
98 | name: 'fonts/[name].[ext]',
99 | esModule: false,
100 | }
101 | }
102 | }
103 | ]
104 | },
105 | plugins: [
106 | new VueLoaderPlugin(),
107 | new MiniCssExtractPlugin({filename: 'styles.css'}),
108 | new HtmlWebpackPlugin({
109 | filename: 'index.html',
110 | template: path.resolve(__dirname, '../src/index.ejs'),
111 | minify: {
112 | collapseWhitespace: true,
113 | removeAttributeQuotes: true,
114 | removeComments: true
115 | },
116 | nodeModules: false
117 | }),
118 | new webpack.DefinePlugin({
119 | 'process.env.IS_WEB': 'true'
120 | }),
121 | new webpack.HotModuleReplacementPlugin(),
122 | new webpack.NoEmitOnErrorsPlugin()
123 | ],
124 | output: {
125 | filename: '[name].js',
126 | path: path.join(__dirname, '../dist/web')
127 | },
128 | resolve: {
129 | alias: {
130 | '@': path.join(__dirname, '../src/renderer'),
131 | 'vue$': 'vue/dist/vue.esm.js'
132 | },
133 | extensions: ['.js', '.vue', '.json', '.css']
134 | },
135 | target: 'web'
136 | }
137 |
138 | /**
139 | * Adjust webConfig for production settings
140 | */
141 | if (process.env.NODE_ENV === 'production') {
142 | webConfig.devtool = ''
143 |
144 | webConfig.plugins.push(
145 | new MinifyPlugin(),
146 | new CopyWebpackPlugin(
147 | {
148 | patterns: [
149 | {
150 | from: path.join(__dirname, '../static'),
151 | to: path.join(__dirname, '../dist/web/static'),
152 | globOptions: {
153 | dot: true,
154 | gitignore: true,
155 | ignore: [".*"],
156 | },
157 | }
158 | ]
159 | }
160 | ),
161 | new webpack.DefinePlugin({
162 | 'process.env.NODE_ENV': '"production"'
163 | }),
164 | new webpack.LoaderOptionsPlugin({
165 | minimize: true
166 | })
167 | )
168 | }
169 |
170 | module.exports = webConfig
171 |
--------------------------------------------------------------------------------
/src/renderer/assets/bin-packing/packer.growing.js:
--------------------------------------------------------------------------------
1 | /******************************************************************************
2 |
3 | This is a binary tree based bin packing algorithm that is more complex than
4 | the simple Packer (packer.js). Instead of starting off with a fixed width and
5 | height, it starts with the width and height of the first block passed and then
6 | grows as necessary to accomodate each subsequent block. As it grows it attempts
7 | to maintain a roughly square ratio by making 'smart' choices about whether to
8 | grow right or down.
9 |
10 | When growing, the algorithm can only grow to the right OR down. Therefore, if
11 | the new block is BOTH wider and taller than the current target then it will be
12 | rejected. This makes it very important to initialize with a sensible starting
13 | width and height. If you are providing sorted input (largest first) then this
14 | will not be an issue.
15 |
16 | A potential way to solve this limitation would be to allow growth in BOTH
17 | directions at once, but this requires maintaining a more complex tree
18 | with 3 children (down, right and center) and that complexity can be avoided
19 | by simply chosing a sensible starting block.
20 |
21 | Best results occur when the input blocks are sorted by height, or even better
22 | when sorted by max(width,height).
23 |
24 | Inputs:
25 | ------
26 |
27 | blocks: array of any objects that have .w and .h attributes
28 |
29 | Outputs:
30 | -------
31 |
32 | marks each block that fits with a .fit attribute pointing to a
33 | node with .x and .y coordinates
34 |
35 | Example:
36 | -------
37 |
38 | var blocks = [
39 | { w: 100, h: 100 },
40 | { w: 100, h: 100 },
41 | { w: 80, h: 80 },
42 | { w: 80, h: 80 },
43 | etc
44 | etc
45 | ];
46 |
47 | var packer = new GrowingPacker();
48 | packer.fit(blocks);
49 |
50 | for(var n = 0 ; n < blocks.length ; n++) {
51 | var block = blocks[n];
52 | if (block.fit) {
53 | Draw(block.fit.x, block.fit.y, block.w, block.h);
54 | }
55 | }
56 |
57 |
58 | ******************************************************************************/
59 |
60 | GrowingPacker = function() { };
61 |
62 | GrowingPacker.prototype = {
63 |
64 | fit: function(blocks) {
65 | var n, node, block, len = blocks.length;
66 | var w = len > 0 ? blocks[0].w : 0;
67 | var h = len > 0 ? blocks[0].h : 0;
68 | this.root = { x: 0, y: 0, w: w, h: h };
69 | for (n = 0; n < len ; n++) {
70 | block = blocks[n];
71 | if (node = this.findNode(this.root, block.w, block.h))
72 | block.fit = this.splitNode(node, block.w, block.h);
73 | else
74 | block.fit = this.growNode(block.w, block.h);
75 | }
76 | },
77 |
78 | findNode: function(root, w, h) {
79 | if (root.used)
80 | return this.findNode(root.right, w, h) || this.findNode(root.down, w, h);
81 | else if ((w <= root.w) && (h <= root.h))
82 | return root;
83 | else
84 | return null;
85 | },
86 |
87 | splitNode: function(node, w, h) {
88 | node.used = true;
89 | node.down = { x: node.x, y: node.y + h, w: node.w, h: node.h - h };
90 | node.right = { x: node.x + w, y: node.y, w: node.w - w, h: h };
91 | return node;
92 | },
93 |
94 | growNode: function(w, h) {
95 | var canGrowDown = (w <= this.root.w);
96 | var canGrowRight = (h <= this.root.h);
97 |
98 | var shouldGrowRight = canGrowRight && (this.root.h >= (this.root.w + w)); // attempt to keep square-ish by growing right when height is much greater than width
99 | var shouldGrowDown = canGrowDown && (this.root.w >= (this.root.h + h)); // attempt to keep square-ish by growing down when width is much greater than height
100 |
101 | if (shouldGrowRight)
102 | return this.growRight(w, h);
103 | else if (shouldGrowDown)
104 | return this.growDown(w, h);
105 | else if (canGrowRight)
106 | return this.growRight(w, h);
107 | else if (canGrowDown)
108 | return this.growDown(w, h);
109 | else
110 | return null; // need to ensure sensible root starting size to avoid this happening
111 | },
112 |
113 | growRight: function(w, h) {
114 | this.root = {
115 | used: true,
116 | x: 0,
117 | y: 0,
118 | w: this.root.w + w,
119 | h: this.root.h,
120 | down: this.root,
121 | right: { x: this.root.w, y: 0, w: w, h: this.root.h }
122 | };
123 | if (node = this.findNode(this.root, w, h))
124 | return this.splitNode(node, w, h);
125 | else
126 | return null;
127 | },
128 |
129 | growDown: function(w, h) {
130 | this.root = {
131 | used: true,
132 | x: 0,
133 | y: 0,
134 | w: this.root.w,
135 | h: this.root.h + h,
136 | down: { x: 0, y: this.root.h, w: this.root.w, h: h },
137 | right: this.root
138 | };
139 | if (node = this.findNode(this.root, w, h))
140 | return this.splitNode(node, w, h);
141 | else
142 | return null;
143 | }
144 |
145 | }
146 |
147 | module.exports = GrowingPacker
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "bmfont-js",
3 | "version": "1.0.1",
4 | "author": "zeb ",
5 | "description": "bitmap font generator",
6 | "license": "see LICENSE file",
7 | "main": "./dist/electron/main.js",
8 | "scripts": {
9 | "build": "node .electron-vue/build.js && electron-builder",
10 | "build:dir": "node .electron-vue/build.js && electron-builder --dir",
11 | "build:clean": "cross-env BUILD_TARGET=clean node .electron-vue/build.js",
12 | "build:web": "cross-env BUILD_TARGET=web node .electron-vue/build.js",
13 | "dev": "node .electron-vue/dev-runner.js",
14 | "lint": "eslint --ext .js,.vue -f ./node_modules/eslint-friendly-formatter src",
15 | "lint:fix": "eslint --ext .js,.vue -f ./node_modules/eslint-friendly-formatter --fix src",
16 | "pack": "npm run pack:main && npm run pack:renderer",
17 | "pack:main": "cross-env NODE_ENV=production webpack --progress --colors --config .electron-vue/webpack.main.config.js",
18 | "pack:renderer": "cross-env NODE_ENV=production webpack --progress --colors --config .electron-vue/webpack.renderer.config.js",
19 | "test": "npm run standard",
20 | "postinstall": "npm run lint:fix",
21 | "standard": "standard --plugin html \"**/*.{js,vue}\"",
22 | "standard:fix": "standard --plugin html \"**/*.{js,vue}\" --fix"
23 | },
24 | "build": {
25 | "productName": "bmfont-js",
26 | "appId": "com.zebplay.bmfont",
27 | "directories": {
28 | "output": "build"
29 | },
30 | "files": [
31 | "dist/electron/**/*"
32 | ],
33 | "dmg": {
34 | "contents": [
35 | {
36 | "x": 410,
37 | "y": 150,
38 | "type": "link",
39 | "path": "/Applications"
40 | },
41 | {
42 | "x": 130,
43 | "y": 150,
44 | "type": "file"
45 | }
46 | ]
47 | },
48 | "mac": {
49 | "icon": "build/icons/icon.icns"
50 | },
51 | "win": {
52 | "icon": "build/icons/icon.ico"
53 | },
54 | "linux": {
55 | "icon": "build/icons"
56 | }
57 | },
58 | "standard": {
59 | "ignore": [
60 | "src/renderer/assets/**"
61 | ]
62 | },
63 | "dependencies": {
64 | "jimp": "^0.11.0",
65 | "tar": "^4.4.18",
66 | "vue": "^2.6.14",
67 | "vue-electron": "^1.0.6",
68 | "vue-router": "^3.5.3",
69 | "vuex": "^3.6.2",
70 | "vuex-electron": "^1.0.0",
71 | "xmlbuilder": "^10.0.0"
72 | },
73 | "devDependencies": {
74 | "@babel/core": "^7.12.16",
75 | "@babel/plugin-proposal-class-properties": "^7.12.13",
76 | "@babel/plugin-proposal-decorators": "^7.12.13",
77 | "@babel/plugin-proposal-do-expressions": "^7.12.13",
78 | "@babel/plugin-proposal-export-default-from": "^7.12.13",
79 | "@babel/plugin-proposal-export-namespace-from": "^7.12.13",
80 | "@babel/plugin-proposal-function-bind": "^7.12.13",
81 | "@babel/plugin-proposal-function-sent": "^7.12.13",
82 | "@babel/plugin-proposal-json-strings": "^7.12.13",
83 | "@babel/plugin-proposal-logical-assignment-operators": "^7.12.13",
84 | "@babel/plugin-proposal-nullish-coalescing-operator": "^7.12.13",
85 | "@babel/plugin-proposal-numeric-separator": "^7.12.13",
86 | "@babel/plugin-proposal-optional-chaining": "^7.12.16",
87 | "@babel/plugin-proposal-pipeline-operator": "^7.12.13",
88 | "@babel/plugin-proposal-throw-expressions": "^7.12.13",
89 | "@babel/plugin-syntax-dynamic-import": "^7.8.3",
90 | "@babel/plugin-syntax-import-meta": "^7.10.4",
91 | "@babel/plugin-transform-runtime": "^7.12.15",
92 | "@babel/preset-env": "^7.12.16",
93 | "@babel/register": "^7.12.13",
94 | "@babel/runtime-corejs2": "^7.12.13",
95 | "ajv": "^7.1.0",
96 | "babel-eslint": "^10.1.0",
97 | "babel-loader": "^8.2.3",
98 | "babel-minify-webpack-plugin": "^0.3.1",
99 | "cfonts": "^2.9.1",
100 | "chalk": "^4.1.2",
101 | "copy-webpack-plugin": "^6.4.1",
102 | "cross-env": "^7.0.3",
103 | "css-loader": "^3.6.0",
104 | "del": "^6.0.0",
105 | "devtron": "^1.4.0",
106 | "electron": "^11.5.0",
107 | "electron-builder": "^22.9.1",
108 | "electron-debug": "^3.2.0",
109 | "electron-devtools-installer": "^3.1.1",
110 | "eslint": "^7.20.0",
111 | "eslint-config-standard": "^16.0.3",
112 | "eslint-friendly-formatter": "^4.0.1",
113 | "eslint-loader": "^4.0.2",
114 | "eslint-plugin-html": "^6.1.1",
115 | "eslint-plugin-import": "^2.22.1",
116 | "eslint-plugin-node": "^11.0.0",
117 | "eslint-plugin-promise": "^4.3.1",
118 | "eslint-plugin-standard": "^5.0.0",
119 | "eslint-plugin-vue": "^7.5.0",
120 | "file-loader": "^6.2.0",
121 | "html-webpack-plugin": "^3.2.0",
122 | "mini-css-extract-plugin": "^1.3.6",
123 | "multispinner": "^0.2.1",
124 | "node-loader": "^1.0.2",
125 | "node-sass": "^5.0.0",
126 | "sass-loader": "^10.1.1",
127 | "style-loader": "^2.0.0",
128 | "url-loader": "^4.1.1",
129 | "vue-html-loader": "^1.2.4",
130 | "vue-loader": "^15.9.8",
131 | "vue-style-loader": "^4.1.3",
132 | "vue-template-compiler": "^2.6.14",
133 | "webpack": "^4.46.0",
134 | "webpack-cli": "^4.5.0",
135 | "webpack-dev-server": "^3.11.2",
136 | "webpack-hot-middleware": "^2.25.1",
137 | "webpack-merge": "^5.7.3"
138 | }
139 | }
140 |
--------------------------------------------------------------------------------
/.electron-vue/dev-runner.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | const chalk = require('chalk')
4 | const electron = require('electron')
5 | const path = require('path')
6 | const { say } = require('cfonts')
7 | const { spawn } = require('child_process')
8 | const webpack = require('webpack')
9 | const WebpackDevServer = require('webpack-dev-server')
10 | const webpackHotMiddleware = require('webpack-hot-middleware')
11 |
12 | const mainConfig = require('./webpack.main.config')
13 | const rendererConfig = require('./webpack.renderer.config')
14 |
15 | let electronProcess = null
16 | let manualRestart = false
17 | let hotMiddleware
18 |
19 | function logStats (proc, data) {
20 | let log = ''
21 |
22 | log += chalk.yellow.bold(`┏ ${proc} Process ${new Array((19 - proc.length) + 1).join('-')}`)
23 | log += '\n\n'
24 |
25 | if (typeof data === 'object') {
26 | data.toString({
27 | colors: true,
28 | chunks: false
29 | }).split(/\r?\n/).forEach(line => {
30 | log += ' ' + line + '\n'
31 | })
32 | } else {
33 | log += ` ${data}\n`
34 | }
35 |
36 | log += '\n' + chalk.yellow.bold(`┗ ${new Array(28 + 1).join('-')}`) + '\n'
37 |
38 | console.log(log)
39 | }
40 |
41 | function startRenderer () {
42 | return new Promise((resolve, reject) => {
43 | rendererConfig.entry.renderer = [path.join(__dirname, 'dev-client')].concat(rendererConfig.entry.renderer)
44 | rendererConfig.mode = 'development'
45 | const compiler = webpack(rendererConfig)
46 | hotMiddleware = webpackHotMiddleware(compiler, {
47 | log: false,
48 | heartbeat: 2500
49 | })
50 |
51 | compiler.hooks.compilation.tap('compilation', compilation => {
52 | compilation.hooks.htmlWebpackPluginAfterEmit.tapAsync('html-webpack-plugin-after-emit', (data, cb) => {
53 | hotMiddleware.publish({ action: 'reload' })
54 | cb()
55 | })
56 | })
57 |
58 | compiler.hooks.done.tap('done', stats => {
59 | logStats('Renderer', stats)
60 | })
61 |
62 | const server = new WebpackDevServer(
63 | compiler,
64 | {
65 | contentBase: path.join(__dirname, '../'),
66 | quiet: true,
67 | before (app, ctx) {
68 | app.use(hotMiddleware)
69 | ctx.middleware.waitUntilValid(() => {
70 | resolve()
71 | })
72 | }
73 | }
74 | )
75 |
76 | server.listen(9080)
77 | })
78 | }
79 |
80 | function startMain () {
81 | return new Promise((resolve, reject) => {
82 | mainConfig.entry.main = [path.join(__dirname, '../src/main/index.dev.js')].concat(mainConfig.entry.main)
83 | mainConfig.mode = 'development'
84 | const compiler = webpack(mainConfig)
85 |
86 | compiler.hooks.watchRun.tapAsync('watch-run', (compilation, done) => {
87 | logStats('Main', chalk.white.bold('compiling...'))
88 | hotMiddleware.publish({ action: 'compiling' })
89 | done()
90 | })
91 |
92 | compiler.watch({}, (err, stats) => {
93 | if (err) {
94 | console.log(err)
95 | return
96 | }
97 |
98 | logStats('Main', stats)
99 |
100 | if (electronProcess && electronProcess.kill) {
101 | manualRestart = true
102 | process.kill(electronProcess.pid)
103 | electronProcess = null
104 | startElectron()
105 |
106 | setTimeout(() => {
107 | manualRestart = false
108 | }, 5000)
109 | }
110 |
111 | resolve()
112 | })
113 | })
114 | }
115 |
116 | function startElectron () {
117 | var args = [
118 | '--inspect=5858',
119 | path.join(__dirname, '../dist/electron/main.js')
120 | ]
121 |
122 | // detect yarn or npm and process commandline args accordingly
123 | if (process.env.npm_execpath.endsWith('yarn.js')) {
124 | args = args.concat(process.argv.slice(3))
125 | } else if (process.env.npm_execpath.endsWith('npm-cli.js')) {
126 | args = args.concat(process.argv.slice(2))
127 | }
128 |
129 | electronProcess = spawn(electron, args)
130 |
131 | electronProcess.stdout.on('data', data => {
132 | electronLog(data, 'blue')
133 | })
134 | electronProcess.stderr.on('data', data => {
135 | electronLog(data, 'red')
136 | })
137 |
138 | electronProcess.on('close', () => {
139 | if (!manualRestart) process.exit()
140 | })
141 | }
142 |
143 | function electronLog (data, color) {
144 | let log = ''
145 | data = data.toString().split(/\r?\n/)
146 | data.forEach(line => {
147 | log += ` ${line}\n`
148 | })
149 | if (/[0-9A-z]+/.test(log)) {
150 | console.log(
151 | chalk[color].bold('┏ Electron -------------------') +
152 | '\n\n' +
153 | log +
154 | chalk[color].bold('┗ ----------------------------') +
155 | '\n'
156 | )
157 | }
158 | }
159 |
160 | function greeting () {
161 | const cols = process.stdout.columns
162 | let text = ''
163 |
164 | if (cols > 104) text = 'electron-vue'
165 | else if (cols > 76) text = 'electron-|vue'
166 | else text = false
167 |
168 | if (text) {
169 | say(text, {
170 | colors: ['yellow'],
171 | font: 'simple3d',
172 | space: false
173 | })
174 | } else console.log(chalk.yellow.bold('\n electron-vue'))
175 | console.log(chalk.blue(' getting ready...') + '\n')
176 | }
177 |
178 | function init () {
179 | greeting()
180 |
181 | Promise.all([startRenderer(), startMain()])
182 | .then(() => {
183 | startElectron()
184 | })
185 | .catch(err => {
186 | console.error(err)
187 | })
188 | }
189 |
190 | init()
--------------------------------------------------------------------------------
/src/renderer/components/Setting.vue:
--------------------------------------------------------------------------------
1 |
2 |
75 |
76 |
77 |
166 |
167 |
209 |
--------------------------------------------------------------------------------
/.electron-vue/webpack.renderer.config.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | process.env.BABEL_ENV = 'renderer'
4 |
5 | const path = require('path')
6 | const { dependencies } = require('../package.json')
7 | const webpack = require('webpack')
8 |
9 | const MinifyPlugin = require("babel-minify-webpack-plugin")
10 | const CopyWebpackPlugin = require('copy-webpack-plugin')
11 | const MiniCssExtractPlugin = require('mini-css-extract-plugin')
12 | const HtmlWebpackPlugin = require('html-webpack-plugin')
13 | const { VueLoaderPlugin } = require('vue-loader')
14 |
15 | /**
16 | * List of node_modules to include in webpack bundle
17 | *
18 | * Required for specific packages like Vue UI libraries
19 | * that provide pure *.vue files that need compiling
20 | * https://simulatedgreg.gitbooks.io/electron-vue/content/en/webpack-configurations.html#white-listing-externals
21 | */
22 | let whiteListedModules = ['vue']
23 |
24 | let rendererConfig = {
25 | devtool: '#cheap-module-eval-source-map',
26 | entry: {
27 | renderer: path.join(__dirname, '../src/renderer/main.js')
28 | },
29 | externals: [
30 | ...Object.keys(dependencies || {}).filter(d => !whiteListedModules.includes(d))
31 | ],
32 | module: {
33 | rules: [
34 | {
35 | test: /\.(js|vue)$/,
36 | enforce: 'pre',
37 | exclude: /node_modules/,
38 | use: {
39 | loader: 'eslint-loader',
40 | options: {
41 | formatter: require('eslint-friendly-formatter')
42 | }
43 | }
44 | },
45 | {
46 | test: /\.scss$/,
47 | use: ['vue-style-loader', 'css-loader', 'sass-loader']
48 | },
49 | {
50 | test: /\.sass$/,
51 | use: ['vue-style-loader', 'css-loader', 'sass-loader?indentedSyntax']
52 | },
53 | {
54 | test: /\.less$/,
55 | use: ['vue-style-loader', 'css-loader', 'less-loader']
56 | },
57 | {
58 | test: /\.css$/,
59 | use: ['vue-style-loader', 'css-loader']
60 | },
61 | {
62 | test: /\.html$/,
63 | use: 'vue-html-loader'
64 | },
65 | {
66 | test: /\.js$/,
67 | use: 'babel-loader',
68 | exclude: /node_modules/
69 | },
70 | {
71 | test: /\.node$/,
72 | use: 'node-loader'
73 | },
74 | {
75 | test: /\.vue$/,
76 | use: {
77 | loader: 'vue-loader',
78 | options: {
79 | extractCSS: process.env.NODE_ENV === 'production',
80 | loaders: {
81 | sass: 'vue-style-loader!css-loader!sass-loader?indentedSyntax=1',
82 | scss: 'vue-style-loader!css-loader!sass-loader',
83 | less: 'vue-style-loader!css-loader!less-loader'
84 | }
85 | }
86 | }
87 | },
88 | {
89 | test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
90 | use: {
91 | loader: 'url-loader',
92 | options: {
93 | esModule: false,
94 | limit: 10000,
95 | name: 'imgs/[name]--[folder].[ext]'
96 | }
97 | }
98 | },
99 | {
100 | test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
101 | loader: 'url-loader',
102 | options: {
103 | limit: 10000,
104 | name: 'media/[name]--[folder].[ext]',
105 | esModule: false,
106 | }
107 | },
108 | {
109 | test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
110 | use: {
111 | loader: 'url-loader',
112 | options: {
113 | limit: 10000,
114 | name: 'fonts/[name]--[folder].[ext]',
115 | esModule: false,
116 | }
117 | }
118 | }
119 | ]
120 | },
121 | node: {
122 | __dirname: process.env.NODE_ENV !== 'production',
123 | __filename: process.env.NODE_ENV !== 'production'
124 | },
125 | plugins: [
126 | new VueLoaderPlugin(),
127 | new MiniCssExtractPlugin({filename: 'styles.css'}),
128 | new HtmlWebpackPlugin({
129 | filename: 'index.html',
130 | template: path.resolve(__dirname, '../src/index.ejs'),
131 | minify: {
132 | collapseWhitespace: true,
133 | removeAttributeQuotes: true,
134 | removeComments: true
135 | },
136 | nodeModules: process.env.NODE_ENV !== 'production'
137 | ? path.resolve(__dirname, '../node_modules')
138 | : false
139 | }),
140 | new webpack.HotModuleReplacementPlugin(),
141 | new webpack.NoEmitOnErrorsPlugin()
142 | ],
143 | output: {
144 | filename: '[name].js',
145 | libraryTarget: 'commonjs2',
146 | path: path.join(__dirname, '../dist/electron')
147 | },
148 | resolve: {
149 | alias: {
150 | '@': path.join(__dirname, '../src/renderer'),
151 | 'vue$': 'vue/dist/vue.esm.js'
152 | },
153 | extensions: ['.js', '.vue', '.json', '.css', '.node']
154 | },
155 | target: 'electron-renderer'
156 | }
157 |
158 | /**
159 | * Adjust rendererConfig for development settings
160 | */
161 | if (process.env.NODE_ENV !== 'production') {
162 | rendererConfig.plugins.push(
163 | new webpack.DefinePlugin({
164 | '__static': `"${path.join(__dirname, '../static').replace(/\\/g, '\\\\')}"`
165 | })
166 | )
167 | }
168 |
169 | /**
170 | * Adjust rendererConfig for production settings
171 | */
172 | if (process.env.NODE_ENV === 'production') {
173 | rendererConfig.devtool = ''
174 |
175 | rendererConfig.plugins.push(
176 | new MinifyPlugin(),
177 | new CopyWebpackPlugin(
178 | {
179 | patterns: [
180 | {
181 | from: path.join(__dirname, '../static'),
182 | to: path.join(__dirname, '../dist/electron/static'),
183 | globOptions: {
184 | dot: true,
185 | gitignore: true,
186 | ignore: [".*"],
187 | },
188 | },
189 | ]
190 | }
191 | ),
192 | new webpack.DefinePlugin({
193 | 'process.env.NODE_ENV': '"production"'
194 | }),
195 | new webpack.LoaderOptionsPlugin({
196 | minimize: true
197 | })
198 | )
199 | }
200 |
201 | module.exports = rendererConfig
202 |
--------------------------------------------------------------------------------
/src/renderer/assets/photon/css/photon.min.css:
--------------------------------------------------------------------------------
1 | @charset "UTF-8";/*!
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 | */audio,canvas,progress,sub,sup,video{vertical-align:baseline}body,html{height:100%}hr,html,label{overflow:hidden}.clearfix:after,.toolbar-actions:after,.toolbar:after{clear:both}*,img{-webkit-user-drag:text}.list-group *,.nav-group-item,h1,h2,h3,h4,h5,h6,label,td,th{white-space:nowrap;text-overflow:ellipsis}audio:not([controls]){display:none}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}dfn{font-style:italic}h1{margin:.67em 0;font-size:36px}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative}sup{top:-.5em}.pane-group,.window{top:0;left:0;right:0}sub{bottom:-.25em}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}legend{border:0;padding:0}*{cursor:default;-webkit-user-select:none;-webkit-box-sizing:border-box;box-sizing:border-box}html{width:100%}body{padding:0;margin:0;font-family:system,-apple-system,".SFNSDisplay-Regular","Helvetica Neue",Helvetica,"Segoe UI",sans-serif;font-size:13px;line-height:1.6;color:#333;background-color:transparent}.btn-dropdown:after,.icon:before{font-family:photon-entypo}hr{margin:15px 0;background:0 0;border:0;border-bottom:1px solid #ddd}h1,h2,h3,h4,h5,h6{margin-top:20px;margin-bottom:10px;font-weight:500;overflow:hidden}.btn .icon,.toolbar-header .title{margin-top:1px}h2{font-size:30px}h3{font-size:24px}h4{font-size:18px}h5{font-size:14px}.btn,h6{font-size:12px}.window{position:absolute;bottom:0;display:flex;flex-direction:column;background-color:#fff}.window-content{position:relative;overflow-y:auto;display:flex;flex:1}.selectable-text{cursor:text;-webkit-user-select:text}.btn,.title{cursor:default}.text-center{text-align:center}.text-right{text-align:right}.text-left{text-align:left}.btn,.title{text-align:center}.pull-left{float:left}.pull-right{float:right}.padded{padding:10px}.padded-less{padding:5px}.padded-more{padding:20px}.padded-vertically{padding-top:10px;padding-bottom:10px}.padded-vertically-less{padding-top:5px;padding-bottom:5px}.padded-vertically-more{padding-top:20px;padding-bottom:20px}.padded-horizontally{padding-right:10px;padding-left:10px}.padded-horizontally-less{padding-right:5px;padding-left:5px}.padded-horizontally-more{padding-right:20px;padding-left:20px}.padded-top{padding-top:10px}.padded-top-less{padding-top:5px}.padded-top-more{padding-top:20px}.padded-bottom{padding-bottom:10px}.padded-bottom-less{padding-bottom:5px}.padded-bottom-more{padding-bottom:20px}.sidebar{background-color:#f5f5f4}.draggable{-webkit-app-region:drag}.btn,.btn-group{vertical-align:middle;-webkit-app-region:no-drag}.clearfix:after,.clearfix:before{display:table;content:" "}.btn{display:inline-block;padding:3px 8px;margin-bottom:0;line-height:1.4;white-space:nowrap;background-image:none;border:1px solid transparent;border-radius:4px;box-shadow:0 1px 1px rgba(0,0,0,.06)}.btn:focus{outline:0;box-shadow:none}.btn-mini{padding:2px 6px}.btn-large{padding:6px 12px}.btn-form{padding-right:20px;padding-left:20px}.btn-default{color:#333;background-color:#fcfcfc;background-image:-webkit-gradient(linear,left top,left bottom,color-stop(0,#fcfcfc),color-stop(100%,#f1f1f1));background-image:-webkit-linear-gradient(top,#fcfcfc 0,#f1f1f1 100%);background-image:linear-gradient(to bottom,#fcfcfc 0,#f1f1f1 100%);border-color:#c2c0c2 #c2c0c2 #a19fa1}.btn-default:active{background-color:#ddd;background-image:none}.btn-negative,.btn-positive,.btn-primary,.btn-warning{color:#fff;text-shadow:0 1px 1px rgba(0,0,0,.1)}.btn-primary{border-color:#388df8 #388df8 #0866dc;background-color:#6eb4f7;background-image:-webkit-gradient(linear,left top,left bottom,color-stop(0,#6eb4f7),color-stop(100%,#1a82fb));background-image:-webkit-linear-gradient(top,#6eb4f7 0,#1a82fb 100%);background-image:linear-gradient(to bottom,#6eb4f7 0,#1a82fb 100%)}.btn-primary:active{background-color:#3e9bf4;background-image:-webkit-gradient(linear,left top,left bottom,color-stop(0,#3e9bf4),color-stop(100%,#0469de));background-image:-webkit-linear-gradient(top,#3e9bf4 0,#0469de 100%);background-image:linear-gradient(to bottom,#3e9bf4 0,#0469de 100%)}.btn-positive{border-color:#29a03b #29a03b #248b34;background-color:#5bd46d;background-image:-webkit-gradient(linear,left top,left bottom,color-stop(0,#5bd46d),color-stop(100%,#29a03b));background-image:-webkit-linear-gradient(top,#5bd46d 0,#29a03b 100%);background-image:linear-gradient(to bottom,#5bd46d 0,#29a03b 100%)}.btn-positive:active{background-color:#34c84a;background-image:-webkit-gradient(linear,left top,left bottom,color-stop(0,#34c84a),color-stop(100%,#248b34));background-image:-webkit-linear-gradient(top,#34c84a 0,#248b34 100%);background-image:linear-gradient(to bottom,#34c84a 0,#248b34 100%)}.btn-negative{border-color:#fb2f29 #fb2f29 #fb1710;background-color:#fd918d;background-image:-webkit-gradient(linear,left top,left bottom,color-stop(0,#fd918d),color-stop(100%,#fb2f29));background-image:-webkit-linear-gradient(top,#fd918d 0,#fb2f29 100%);background-image:linear-gradient(to bottom,#fd918d 0,#fb2f29 100%)}.btn-negative:active{background-color:#fc605b;background-image:-webkit-gradient(linear,left top,left bottom,color-stop(0,#fc605b),color-stop(100%,#fb1710));background-image:-webkit-linear-gradient(top,#fc605b 0,#fb1710 100%);background-image:linear-gradient(to bottom,#fc605b 0,#fb1710 100%)}.btn-warning{border-color:#fcaa0e #fcaa0e #ee9d02;background-color:#fece72;background-image:-webkit-gradient(linear,left top,left bottom,color-stop(0,#fece72),color-stop(100%,#fcaa0e));background-image:-webkit-linear-gradient(top,#fece72 0,#fcaa0e 100%);background-image:linear-gradient(to bottom,#fece72 0,#fcaa0e 100%)}.btn-warning:active{background-color:#fdbc40;background-image:-webkit-gradient(linear,left top,left bottom,color-stop(0,#fdbc40),color-stop(100%,#ee9d02));background-image:-webkit-linear-gradient(top,#fdbc40 0,#ee9d02 100%);background-image:linear-gradient(to bottom,#fdbc40 0,#ee9d02 100%)}.btn .icon{float:left;width:14px;height:14px;margin-bottom:1px;color:#737475;font-size:14px;line-height:1}.btn .icon-text{margin-right:5px}.btn-dropdown:after{margin-left:5px;content:""}.btn-group{position:relative;display:inline-block}.toolbar-actions:after,.toolbar-actions:before,.toolbar:after,.toolbar:before{display:table;content:" "}.btn-group .btn{position:relative;float:left}.btn-group .btn:active,.btn-group .btn:focus{z-index:2}.btn-group .btn.active{z-index:3}.btn-group .btn+.btn,.btn-group .btn+.btn-group,.btn-group .btn-group+.btn,.btn-group .btn-group+.btn-group{margin-left:-1px}.btn-group>.btn:first-child{border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn:last-child{border-top-left-radius:0;border-bottom-left-radius:0}.btn-group>.btn:not(:first-child):not(:last-child){border-radius:0}.btn-group .btn+.btn{border-left:1px solid #c2c0c2}.btn-group .btn+.btn.active{border-left:0}.btn-group .active{color:#fff;border:1px solid transparent;background-color:#6d6c6d;background-image:none}.btn-group .active .icon{color:#fff}.toolbar{min-height:22px;box-shadow:inset 0 1px 0 #f5f4f5;background-color:#e8e6e8;background-image:-webkit-gradient(linear,left top,left bottom,color-stop(0,#e8e6e8),color-stop(100%,#d1cfd1));background-image:-webkit-linear-gradient(top,#e8e6e8 0,#d1cfd1 100%);background-image:linear-gradient(to bottom,#e8e6e8 0,#d1cfd1 100%)}.toolbar-header{border-bottom:1px solid #c2c0c2}.toolbar-footer{border-top:1px solid #c2c0c2;-webkit-app-region:drag}.title{margin:0;font-size:12px;font-weight:400;color:#555}.toolbar-borderless{border-top:0;border-bottom:0}.toolbar-actions{margin-top:4px;margin-bottom:3px;padding-right:3px;padding-left:3px;padding-bottom:3px;-webkit-app-region:drag}.form-control,label{display:inline-block;font-size:13px}.toolbar-actions>.btn,.toolbar-actions>.btn-group{margin-left:4px;margin-right:4px}label{margin-bottom:5px}input[type=search]{-webkit-appearance:textfield;box-sizing:border-box}input[type=checkbox],input[type=radio]{margin:4px 0 0;line-height:normal}.checkbox,.form-group,.radio{margin-bottom:10px}.form-control{width:100%;min-height:25px;padding:5px 10px;line-height:1.6;background-color:#fff;border:1px solid #ddd;border-radius:4px;outline:0}.form-control:focus{border-color:#6db3fd;box-shadow:3px 3px 0 #6db3fd,-3px -3px 0 #6db3fd,-3px 3px 0 #6db3fd,3px -3px 0 #6db3fd}textarea{height:auto}.checkbox,.radio{position:relative;display:block;margin-top:10px}.checkbox label,.radio label{padding-left:20px;margin-bottom:0;font-weight:400}.checkbox input[type=checkbox],.checkbox-inline input[type=checkbox],.radio input[type=radio],.radio-inline input[type=radio]{position:absolute;margin-left:-20px;margin-top:4px}.form-actions .btn{margin-right:10px}.form-actions .btn:last-child{margin-right:0}.pane-group{position:absolute;bottom:0;display:flex}.icon:before,.pane,.tab-item{position:relative}.pane{overflow-y:auto;flex:1;border-left:1px solid #ddd}.list-group *,.media-body,.nav-group-item,td,th{overflow:hidden}.pane:first-child{border-left:0}.pane-sm{max-width:220px;min-width:150px}.pane-mini{width:80px;flex:none}.pane-one-fourth{width:25%;flex:none}.pane-one-third{width:33.3%}.img-circle{border-radius:50%}.img-rounded{border-radius:4px}.list-group{width:100%;list-style:none;margin:0;padding:0}.list-group *{margin:0}.list-group-item{padding:10px;font-size:12px;color:#414142;border-top:1px solid #ddd}.list-group-item:first-child{border-top:0}.list-group-item.active,.list-group-item.selected{color:#fff;background-color:#116cd6}.list-group-header{padding:10px}.media-object{margin-top:3px}.media-object.pull-left{margin-right:10px}.media-object.pull-right{margin-left:10px}.nav-group{font-size:14px}.nav-group-item{padding:2px 10px 2px 25px;display:block;color:#333;text-decoration:none}.nav-group-item.active,.nav-group-item:active{background-color:#dcdfe1}.nav-group-item .icon{width:19px;height:18px;float:left;color:#737475;margin-top:-3px;margin-right:7px;font-size:18px;text-align:center}.nav-group-title{margin:0;padding:10px 10px 2px;font-size:12px;font-weight:500;color:#666}.icon:before,th{font-weight:400}@font-face{font-family:photon-entypo;src:url(../fonts/photon-entypo.eot);src:url(../fonts/photon-entypo.eot?#iefix) format("eot"),url(../fonts/photon-entypo.woff) format("woff"),url(../fonts/photon-entypo.ttf) format("truetype");font-weight:400;font-style:normal}.icon:before{display:inline-block;speak:none;font-size:100%;font-style:normal;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.icon-note:before{content:'\e800'}.icon-note-beamed:before{content:'\e801'}.icon-music:before{content:'\e802'}.icon-search:before{content:'\e803'}.icon-flashlight:before{content:'\e804'}.icon-mail:before{content:'\e805'}.icon-heart:before{content:'\e806'}.icon-heart-empty:before{content:'\e807'}.icon-star:before{content:'\e808'}.icon-star-empty:before{content:'\e809'}.icon-user:before{content:'\e80a'}.icon-users:before{content:'\e80b'}.icon-user-add:before{content:'\e80c'}.icon-video:before{content:'\e80d'}.icon-picture:before{content:'\e80e'}.icon-camera:before{content:'\e80f'}.icon-layout:before{content:'\e810'}.icon-menu:before{content:'\e811'}.icon-check:before{content:'\e812'}.icon-cancel:before{content:'\e813'}.icon-cancel-circled:before{content:'\e814'}.icon-cancel-squared:before{content:'\e815'}.icon-plus:before{content:'\e816'}.icon-plus-circled:before{content:'\e817'}.icon-plus-squared:before{content:'\e818'}.icon-minus:before{content:'\e819'}.icon-minus-circled:before{content:'\e81a'}.icon-minus-squared:before{content:'\e81b'}.icon-help:before{content:'\e81c'}.icon-help-circled:before{content:'\e81d'}.icon-info:before{content:'\e81e'}.icon-info-circled:before{content:'\e81f'}.icon-back:before{content:'\e820'}.icon-home:before{content:'\e821'}.icon-link:before{content:'\e822'}.icon-attach:before{content:'\e823'}.icon-lock:before{content:'\e824'}.icon-lock-open:before{content:'\e825'}.icon-eye:before{content:'\e826'}.icon-tag:before{content:'\e827'}.icon-bookmark:before{content:'\e828'}.icon-bookmarks:before{content:'\e829'}.icon-flag:before{content:'\e82a'}.icon-thumbs-up:before{content:'\e82b'}.icon-thumbs-down:before{content:'\e82c'}.icon-download:before{content:'\e82d'}.icon-upload:before{content:'\e82e'}.icon-upload-cloud:before{content:'\e82f'}.icon-reply:before{content:'\e830'}.icon-reply-all:before{content:'\e831'}.icon-forward:before{content:'\e832'}.icon-quote:before{content:'\e833'}.icon-code:before{content:'\e834'}.icon-export:before{content:'\e835'}.icon-pencil:before{content:'\e836'}.icon-feather:before{content:'\e837'}.icon-print:before{content:'\e838'}.icon-retweet:before{content:'\e839'}.icon-keyboard:before{content:'\e83a'}.icon-comment:before{content:'\e83b'}.icon-chat:before{content:'\e83c'}.icon-bell:before{content:'\e83d'}.icon-attention:before{content:'\e83e'}.icon-alert:before{content:'\e83f'}.icon-vcard:before{content:'\e840'}.icon-address:before{content:'\e841'}.icon-location:before{content:'\e842'}.icon-map:before{content:'\e843'}.icon-direction:before{content:'\e844'}.icon-compass:before{content:'\e845'}.icon-cup:before{content:'\e846'}.icon-trash:before{content:'\e847'}.icon-doc:before{content:'\e848'}.icon-docs:before{content:'\e849'}.icon-doc-landscape:before{content:'\e84a'}.icon-doc-text:before{content:'\e84b'}.icon-doc-text-inv:before{content:'\e84c'}.icon-newspaper:before{content:'\e84d'}.icon-book-open:before{content:'\e84e'}.icon-book:before{content:'\e84f'}.icon-folder:before{content:'\e850'}.icon-archive:before{content:'\e851'}.icon-box:before{content:'\e852'}.icon-rss:before{content:'\e853'}.icon-phone:before{content:'\e854'}.icon-cog:before{content:'\e855'}.icon-tools:before{content:'\e856'}.icon-share:before{content:'\e857'}.icon-shareable:before{content:'\e858'}.icon-basket:before{content:'\e859'}.icon-bag:before{content:'\e85a'}.icon-calendar:before{content:'\e85b'}.icon-login:before{content:'\e85c'}.icon-logout:before{content:'\e85d'}.icon-mic:before{content:'\e85e'}.icon-mute:before{content:'\e85f'}.icon-sound:before{content:'\e860'}.icon-volume:before{content:'\e861'}.icon-clock:before{content:'\e862'}.icon-hourglass:before{content:'\e863'}.icon-lamp:before{content:'\e864'}.icon-light-down:before{content:'\e865'}.icon-light-up:before{content:'\e866'}.icon-adjust:before{content:'\e867'}.icon-block:before{content:'\e868'}.icon-resize-full:before{content:'\e869'}.icon-resize-small:before{content:'\e86a'}.icon-popup:before{content:'\e86b'}.icon-publish:before{content:'\e86c'}.icon-window:before{content:'\e86d'}.icon-arrow-combo:before{content:'\e86e'}.icon-down-circled:before{content:'\e86f'}.icon-left-circled:before{content:'\e870'}.icon-right-circled:before{content:'\e871'}.icon-up-circled:before{content:'\e872'}.icon-down-open:before{content:'\e873'}.icon-left-open:before{content:'\e874'}.icon-right-open:before{content:'\e875'}.icon-up-open:before{content:'\e876'}.icon-down-open-mini:before{content:'\e877'}.icon-left-open-mini:before{content:'\e878'}.icon-right-open-mini:before{content:'\e879'}.icon-up-open-mini:before{content:'\e87a'}.icon-down-open-big:before{content:'\e87b'}.icon-left-open-big:before{content:'\e87c'}.icon-right-open-big:before{content:'\e87d'}.icon-up-open-big:before{content:'\e87e'}.icon-down:before{content:'\e87f'}.icon-left:before{content:'\e880'}.icon-right:before{content:'\e881'}.icon-up:before{content:'\e882'}.icon-down-dir:before{content:'\e883'}.icon-left-dir:before{content:'\e884'}.icon-right-dir:before{content:'\e885'}.icon-up-dir:before{content:'\e886'}.icon-down-bold:before{content:'\e887'}.icon-left-bold:before{content:'\e888'}.icon-right-bold:before{content:'\e889'}.icon-up-bold:before{content:'\e88a'}.icon-down-thin:before{content:'\e88b'}.icon-left-thin:before{content:'\e88c'}.icon-right-thin:before{content:'\e88d'}.icon-up-thin:before{content:'\e88e'}.icon-ccw:before{content:'\e88f'}.icon-cw:before{content:'\e890'}.icon-arrows-ccw:before{content:'\e891'}.icon-level-down:before{content:'\e892'}.icon-level-up:before{content:'\e893'}.icon-shuffle:before{content:'\e894'}.icon-loop:before{content:'\e895'}.icon-switch:before{content:'\e896'}.icon-play:before{content:'\e897'}.icon-stop:before{content:'\e898'}.icon-pause:before{content:'\e899'}.icon-record:before{content:'\e89a'}.icon-to-end:before{content:'\e89b'}.icon-to-start:before{content:'\e89c'}.icon-fast-forward:before{content:'\e89d'}.icon-fast-backward:before{content:'\e89e'}.icon-progress-0:before{content:'\e89f'}.icon-progress-1:before{content:'\e8a0'}.icon-progress-2:before{content:'\e8a1'}.icon-progress-3:before{content:'\e8a2'}.icon-target:before{content:'\e8a3'}.icon-palette:before{content:'\e8a4'}.icon-list:before{content:'\e8a5'}.icon-list-add:before{content:'\e8a6'}.icon-signal:before{content:'\e8a7'}.icon-trophy:before{content:'\e8a8'}.icon-battery:before{content:'\e8a9'}.icon-back-in-time:before{content:'\e8aa'}.icon-monitor:before{content:'\e8ab'}.icon-mobile:before{content:'\e8ac'}.icon-network:before{content:'\e8ad'}.icon-cd:before{content:'\e8ae'}.icon-inbox:before{content:'\e8af'}.icon-install:before{content:'\e8b0'}.icon-globe:before{content:'\e8b1'}.icon-cloud:before{content:'\e8b2'}.icon-cloud-thunder:before{content:'\e8b3'}.icon-flash:before{content:'\e8b4'}.icon-moon:before{content:'\e8b5'}.icon-flight:before{content:'\e8b6'}.icon-paper-plane:before{content:'\e8b7'}.icon-leaf:before{content:'\e8b8'}.icon-lifebuoy:before{content:'\e8b9'}.icon-mouse:before{content:'\e8ba'}.icon-briefcase:before{content:'\e8bb'}.icon-suitcase:before{content:'\e8bc'}.icon-dot:before{content:'\e8bd'}.icon-dot-2:before{content:'\e8be'}.icon-dot-3:before{content:'\e8bf'}.icon-brush:before{content:'\e8c0'}.icon-magnet:before{content:'\e8c1'}.icon-infinity:before{content:'\e8c2'}.icon-erase:before{content:'\e8c3'}.icon-chart-pie:before{content:'\e8c4'}.icon-chart-line:before{content:'\e8c5'}.icon-chart-bar:before{content:'\e8c6'}.icon-chart-area:before{content:'\e8c7'}.icon-tape:before{content:'\e8c8'}.icon-graduation-cap:before{content:'\e8c9'}.icon-language:before{content:'\e8ca'}.icon-ticket:before{content:'\e8cb'}.icon-water:before{content:'\e8cc'}.icon-droplet:before{content:'\e8cd'}.icon-air:before{content:'\e8ce'}.icon-credit-card:before{content:'\e8cf'}.icon-floppy:before{content:'\e8d0'}.icon-clipboard:before{content:'\e8d1'}.icon-megaphone:before{content:'\e8d2'}.icon-database:before{content:'\e8d3'}.icon-drive:before{content:'\e8d4'}.icon-bucket:before{content:'\e8d5'}.icon-thermometer:before{content:'\e8d6'}.icon-key:before{content:'\e8d7'}.icon-flow-cascade:before{content:'\e8d8'}.icon-flow-branch:before{content:'\e8d9'}.icon-flow-tree:before{content:'\e8da'}.icon-flow-line:before{content:'\e8db'}.icon-flow-parallel:before{content:'\e8dc'}.icon-rocket:before{content:'\e8dd'}.icon-gauge:before{content:'\e8de'}.icon-traffic-cone:before{content:'\e8df'}.icon-cc:before{content:'\e8e0'}.icon-cc-by:before{content:'\e8e1'}.icon-cc-nc:before{content:'\e8e2'}.icon-cc-nc-eu:before{content:'\e8e3'}.icon-cc-nc-jp:before{content:'\e8e4'}.icon-cc-sa:before{content:'\e8e5'}.icon-cc-nd:before{content:'\e8e6'}.icon-cc-pd:before{content:'\e8e7'}.icon-cc-zero:before{content:'\e8e8'}.icon-cc-share:before{content:'\e8e9'}.icon-cc-remix:before{content:'\e8ea'}.icon-github:before{content:'\e8eb'}.icon-github-circled:before{content:'\e8ec'}.icon-flickr:before{content:'\e8ed'}.icon-flickr-circled:before{content:'\e8ee'}.icon-vimeo:before{content:'\e8ef'}.icon-vimeo-circled:before{content:'\e8f0'}.icon-twitter:before{content:'\e8f1'}.icon-twitter-circled:before{content:'\e8f2'}.icon-facebook:before{content:'\e8f3'}.icon-facebook-circled:before{content:'\e8f4'}.icon-facebook-squared:before{content:'\e8f5'}.icon-gplus:before{content:'\e8f6'}.icon-gplus-circled:before{content:'\e8f7'}.icon-pinterest:before{content:'\e8f8'}.icon-pinterest-circled:before{content:'\e8f9'}.icon-tumblr:before{content:'\e8fa'}.icon-tumblr-circled:before{content:'\e8fb'}.icon-linkedin:before{content:'\e8fc'}.icon-linkedin-circled:before{content:'\e8fd'}.icon-dribbble:before{content:'\e8fe'}.icon-dribbble-circled:before{content:'\e8ff'}.icon-stumbleupon:before{content:'\e900'}.icon-stumbleupon-circled:before{content:'\e901'}.icon-lastfm:before{content:'\e902'}.icon-lastfm-circled:before{content:'\e903'}.icon-rdio:before{content:'\e904'}.icon-rdio-circled:before{content:'\e905'}.icon-spotify:before{content:'\e906'}.icon-spotify-circled:before{content:'\e907'}.icon-qq:before{content:'\e908'}.icon-instagram:before{content:'\e909'}.icon-dropbox:before{content:'\e90a'}.icon-evernote:before{content:'\e90b'}.icon-flattr:before{content:'\e90c'}.icon-skype:before{content:'\e90d'}.icon-skype-circled:before{content:'\e90e'}.icon-renren:before{content:'\e90f'}.icon-sina-weibo:before{content:'\e910'}.icon-paypal:before{content:'\e911'}.icon-picasa:before{content:'\e912'}.icon-soundcloud:before{content:'\e913'}.icon-mixi:before{content:'\e914'}.icon-behance:before{content:'\e915'}.icon-google-circles:before{content:'\e916'}.icon-vkontakte:before{content:'\e917'}.icon-smashing:before{content:'\e918'}.icon-sweden:before{content:'\e919'}.icon-db-shape:before{content:'\e91a'}.icon-logo-db:before{content:'\e91b'}table{border-spacing:0;width:100%;border:0;border-collapse:separate;font-size:12px;text-align:left}.table-striped tr:nth-child(even),thead{background-color:#f5f5f4}tbody{background-color:#fff}.table-striped tr:active:nth-child(even),tr:active{color:#fff;background-color:#116cd6}thead tr:active{color:#333;background-color:#f5f5f4}th{border-right:1px solid #ddd;border-bottom:1px solid #ddd}td,th{padding:2px 15px}td:last-child,th:last-child{border-right:0}.tab-group{margin-top:-1px;display:flex;border-top:1px solid #989698;border-bottom:1px solid #989698}.tab-item{flex:1;padding:3px;font-size:12px;text-align:center;border-left:1px solid #989698;background-color:#b8b6b8;background-image:-webkit-gradient(linear,left top,left bottom,color-stop(0,#b8b6b8),color-stop(100%,#b0aeb0));background-image:-webkit-linear-gradient(top,#b8b6b8 0,#b0aeb0 100%);background-image:linear-gradient(to bottom,#b8b6b8 0,#b0aeb0 100%)}.tab-item:first-child{border-left:0}.tab-item.active{background-color:#d4d2d4;background-image:-webkit-gradient(linear,left top,left bottom,color-stop(0,#d4d2d4),color-stop(100%,#cccacc));background-image:-webkit-linear-gradient(top,#d4d2d4 0,#cccacc 100%);background-image:linear-gradient(to bottom,#d4d2d4 0,#cccacc 100%)}.tab-item .icon-close-tab:hover,.tab-item:after{background-color:rgba(0,0,0,.08)}.tab-item .icon-close-tab{position:absolute;top:50%;left:5px;width:15px;height:15px;font-size:15px;line-height:15px;text-align:center;color:#666;opacity:0;transition:opacity .1s linear,background-color .1s linear;border-radius:3px;transform:translateY(-50%);z-index:10}.tab-item:after{position:absolute;top:0;right:0;bottom:0;left:0;content:"";opacity:0;transition:opacity .1s linear;z-index:1}.tab-item:hover .icon-close-tab,.tab-item:hover:not(.active):after{opacity:1}.tab-item-fixed{flex:none;padding:3px 10px}
--------------------------------------------------------------------------------
/src/renderer/assets/photon/css/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 |
88 | input[type="number"]::-webkit-inner-spin-button,
89 | input[type="number"]::-webkit-outer-spin-button {
90 | height: auto;
91 | }
92 |
93 | input[type="search"] {
94 | -webkit-appearance: textfield;
95 | box-sizing: content-box;
96 | }
97 |
98 | input[type="search"]::-webkit-search-cancel-button,
99 | input[type="search"]::-webkit-search-decoration {
100 | -webkit-appearance: none;
101 | }
102 |
103 | fieldset {
104 | border: 1px solid #c0c0c0;
105 | margin: 0 2px;
106 | padding: 0.35em 0.625em 0.75em;
107 | }
108 |
109 | legend {
110 | border: 0;
111 | padding: 0;
112 | }
113 |
114 | table {
115 | border-collapse: collapse;
116 | border-spacing: 0;
117 | }
118 |
119 | td,
120 | th {
121 | padding: 0;
122 | }
123 |
124 | * {
125 | cursor: default;
126 | -webkit-user-drag: text;
127 | -webkit-user-select: none;
128 | -webkit-box-sizing: border-box;
129 | box-sizing: border-box;
130 | }
131 |
132 | html {
133 | height: 100%;
134 | width: 100%;
135 | overflow: hidden;
136 | }
137 |
138 | body {
139 | height: 100%;
140 | padding: 0;
141 | margin: 0;
142 | font-family: system, -apple-system, ".SFNSDisplay-Regular", "Helvetica Neue", Helvetica, "Segoe UI", sans-serif;
143 | font-size: 13px;
144 | line-height: 1.6;
145 | color: #333;
146 | background-color: transparent;
147 | }
148 |
149 | hr {
150 | margin: 15px 0;
151 | overflow: hidden;
152 | background: transparent;
153 | border: 0;
154 | border-bottom: 1px solid #ddd;
155 | }
156 |
157 | h1, h2, h3, h4, h5, h6 {
158 | margin-top: 20px;
159 | margin-bottom: 10px;
160 | font-weight: 500;
161 | white-space: nowrap;
162 | overflow: hidden;
163 | text-overflow: ellipsis;
164 | }
165 |
166 | h1 {
167 | font-size: 36px;
168 | }
169 |
170 | h2 {
171 | font-size: 30px;
172 | }
173 |
174 | h3 {
175 | font-size: 24px;
176 | }
177 |
178 | h4 {
179 | font-size: 18px;
180 | }
181 |
182 | h5 {
183 | font-size: 14px;
184 | }
185 |
186 | h6 {
187 | font-size: 12px;
188 | }
189 |
190 | .window {
191 | position: absolute;
192 | top: 0;
193 | right: 0;
194 | bottom: 0;
195 | left: 0;
196 | display: flex;
197 | flex-direction: column;
198 | background-color: #fff;
199 | }
200 |
201 | .window-content {
202 | position: relative;
203 | overflow-y: auto;
204 | display: flex;
205 | flex: 1;
206 | }
207 |
208 | .selectable-text {
209 | cursor: text;
210 | -webkit-user-select: text;
211 | }
212 |
213 | .text-center {
214 | text-align: center;
215 | }
216 |
217 | .text-right {
218 | text-align: right;
219 | }
220 |
221 | .text-left {
222 | text-align: left;
223 | }
224 |
225 | .pull-left {
226 | float: left;
227 | }
228 |
229 | .pull-right {
230 | float: right;
231 | }
232 |
233 | .padded {
234 | padding: 10px;
235 | }
236 |
237 | .padded-less {
238 | padding: 5px;
239 | }
240 |
241 | .padded-more {
242 | padding: 20px;
243 | }
244 |
245 | .padded-vertically {
246 | padding-top: 10px;
247 | padding-bottom: 10px;
248 | }
249 |
250 | .padded-vertically-less {
251 | padding-top: 5px;
252 | padding-bottom: 5px;
253 | }
254 |
255 | .padded-vertically-more {
256 | padding-top: 20px;
257 | padding-bottom: 20px;
258 | }
259 |
260 | .padded-horizontally {
261 | padding-right: 10px;
262 | padding-left: 10px;
263 | }
264 |
265 | .padded-horizontally-less {
266 | padding-right: 5px;
267 | padding-left: 5px;
268 | }
269 |
270 | .padded-horizontally-more {
271 | padding-right: 20px;
272 | padding-left: 20px;
273 | }
274 |
275 | .padded-top {
276 | padding-top: 10px;
277 | }
278 |
279 | .padded-top-less {
280 | padding-top: 5px;
281 | }
282 |
283 | .padded-top-more {
284 | padding-top: 20px;
285 | }
286 |
287 | .padded-bottom {
288 | padding-bottom: 10px;
289 | }
290 |
291 | .padded-bottom-less {
292 | padding-bottom: 5px;
293 | }
294 |
295 | .padded-bottom-more {
296 | padding-bottom: 20px;
297 | }
298 |
299 | .sidebar {
300 | background-color: #f5f5f4;
301 | }
302 |
303 | .draggable {
304 | -webkit-app-region: drag;
305 | }
306 |
307 | .clearfix:before, .clearfix:after {
308 | display: table;
309 | content: " ";
310 | }
311 | .clearfix:after {
312 | clear: both;
313 | }
314 |
315 | .btn {
316 | display: inline-block;
317 | padding: 3px 8px;
318 | margin-bottom: 0;
319 | font-size: 12px;
320 | line-height: 1.4;
321 | text-align: center;
322 | white-space: nowrap;
323 | vertical-align: middle;
324 | cursor: default;
325 | background-image: none;
326 | border: 1px solid transparent;
327 | border-radius: 4px;
328 | box-shadow: 0 1px 1px rgba(0, 0, 0, 0.06);
329 | -webkit-app-region: no-drag;
330 | }
331 | .btn:focus {
332 | outline: none;
333 | box-shadow: none;
334 | }
335 |
336 | .btn-mini {
337 | padding: 2px 6px;
338 | }
339 |
340 | .btn-large {
341 | padding: 6px 12px;
342 | }
343 |
344 | .btn-form {
345 | padding-right: 20px;
346 | padding-left: 20px;
347 | }
348 |
349 | .btn-default {
350 | color: #333;
351 | border-top-color: #c2c0c2;
352 | border-right-color: #c2c0c2;
353 | border-bottom-color: #a19fa1;
354 | border-left-color: #c2c0c2;
355 | background-color: #fcfcfc;
356 | background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #fcfcfc), color-stop(100%, #f1f1f1));
357 | background-image: -webkit-linear-gradient(top, #fcfcfc 0%, #f1f1f1 100%);
358 | background-image: linear-gradient(to bottom, #fcfcfc 0%, #f1f1f1 100%);
359 | }
360 | .btn-default:active {
361 | background-color: #ddd;
362 | background-image: none;
363 | }
364 |
365 | .btn-primary,
366 | .btn-positive,
367 | .btn-negative,
368 | .btn-warning {
369 | color: #fff;
370 | text-shadow: 0 1px 1px rgba(0, 0, 0, 0.1);
371 | }
372 |
373 | .btn-primary {
374 | border-color: #388df8;
375 | border-bottom-color: #0866dc;
376 | background-color: #6eb4f7;
377 | background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #6eb4f7), color-stop(100%, #1a82fb));
378 | background-image: -webkit-linear-gradient(top, #6eb4f7 0%, #1a82fb 100%);
379 | background-image: linear-gradient(to bottom, #6eb4f7 0%, #1a82fb 100%);
380 | }
381 | .btn-primary:active {
382 | background-color: #3e9bf4;
383 | background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #3e9bf4), color-stop(100%, #0469de));
384 | background-image: -webkit-linear-gradient(top, #3e9bf4 0%, #0469de 100%);
385 | background-image: linear-gradient(to bottom, #3e9bf4 0%, #0469de 100%);
386 | }
387 |
388 | .btn-positive {
389 | border-color: #29a03b;
390 | border-bottom-color: #248b34;
391 | background-color: #5bd46d;
392 | background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #5bd46d), color-stop(100%, #29a03b));
393 | background-image: -webkit-linear-gradient(top, #5bd46d 0%, #29a03b 100%);
394 | background-image: linear-gradient(to bottom, #5bd46d 0%, #29a03b 100%);
395 | }
396 | .btn-positive:active {
397 | background-color: #34c84a;
398 | background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #34c84a), color-stop(100%, #248b34));
399 | background-image: -webkit-linear-gradient(top, #34c84a 0%, #248b34 100%);
400 | background-image: linear-gradient(to bottom, #34c84a 0%, #248b34 100%);
401 | }
402 |
403 | .btn-negative {
404 | border-color: #fb2f29;
405 | border-bottom-color: #fb1710;
406 | background-color: #fd918d;
407 | background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #fd918d), color-stop(100%, #fb2f29));
408 | background-image: -webkit-linear-gradient(top, #fd918d 0%, #fb2f29 100%);
409 | background-image: linear-gradient(to bottom, #fd918d 0%, #fb2f29 100%);
410 | }
411 | .btn-negative:active {
412 | background-color: #fc605b;
413 | background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #fc605b), color-stop(100%, #fb1710));
414 | background-image: -webkit-linear-gradient(top, #fc605b 0%, #fb1710 100%);
415 | background-image: linear-gradient(to bottom, #fc605b 0%, #fb1710 100%);
416 | }
417 |
418 | .btn-warning {
419 | border-color: #fcaa0e;
420 | border-bottom-color: #ee9d02;
421 | background-color: #fece72;
422 | background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #fece72), color-stop(100%, #fcaa0e));
423 | background-image: -webkit-linear-gradient(top, #fece72 0%, #fcaa0e 100%);
424 | background-image: linear-gradient(to bottom, #fece72 0%, #fcaa0e 100%);
425 | }
426 | .btn-warning:active {
427 | background-color: #fdbc40;
428 | background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #fdbc40), color-stop(100%, #ee9d02));
429 | background-image: -webkit-linear-gradient(top, #fdbc40 0%, #ee9d02 100%);
430 | background-image: linear-gradient(to bottom, #fdbc40 0%, #ee9d02 100%);
431 | }
432 |
433 | .btn .icon {
434 | float: left;
435 | width: 14px;
436 | height: 14px;
437 | margin-top: 1px;
438 | margin-bottom: 1px;
439 | color: #737475;
440 | font-size: 14px;
441 | line-height: 1;
442 | }
443 |
444 | .btn .icon-text {
445 | margin-right: 5px;
446 | }
447 |
448 | .btn-dropdown:after {
449 | font-family: "photon-entypo";
450 | margin-left: 5px;
451 | content: "";
452 | }
453 |
454 | .btn-group {
455 | position: relative;
456 | display: inline-block;
457 | vertical-align: middle;
458 | -webkit-app-region: no-drag;
459 | }
460 | .btn-group .btn {
461 | position: relative;
462 | float: left;
463 | }
464 | .btn-group .btn:focus, .btn-group .btn:active {
465 | z-index: 2;
466 | }
467 | .btn-group .btn.active {
468 | z-index: 3;
469 | }
470 |
471 | .btn-group .btn + .btn,
472 | .btn-group .btn + .btn-group,
473 | .btn-group .btn-group + .btn,
474 | .btn-group .btn-group + .btn-group {
475 | margin-left: -1px;
476 | }
477 | .btn-group > .btn:first-child {
478 | border-top-right-radius: 0;
479 | border-bottom-right-radius: 0;
480 | }
481 | .btn-group > .btn:last-child {
482 | border-top-left-radius: 0;
483 | border-bottom-left-radius: 0;
484 | }
485 | .btn-group > .btn:not(:first-child):not(:last-child) {
486 | border-radius: 0;
487 | }
488 | .btn-group .btn + .btn {
489 | border-left: 1px solid #c2c0c2;
490 | }
491 | .btn-group .btn + .btn.active {
492 | border-left: 0;
493 | }
494 | .btn-group .active {
495 | color: #fff;
496 | border: 1px solid transparent;
497 | background-color: #6d6c6d;
498 | background-image: none;
499 | }
500 | .btn-group .active .icon {
501 | color: #fff;
502 | }
503 |
504 | .toolbar {
505 | min-height: 22px;
506 | box-shadow: inset 0 1px 0 #f5f4f5;
507 | background-color: #e8e6e8;
508 | background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #e8e6e8), color-stop(100%, #d1cfd1));
509 | background-image: -webkit-linear-gradient(top, #e8e6e8 0%, #d1cfd1 100%);
510 | background-image: linear-gradient(to bottom, #e8e6e8 0%, #d1cfd1 100%);
511 | }
512 | .toolbar:before, .toolbar:after {
513 | display: table;
514 | content: " ";
515 | }
516 | .toolbar:after {
517 | clear: both;
518 | }
519 |
520 | .toolbar-header {
521 | border-bottom: 1px solid #c2c0c2;
522 | }
523 | .toolbar-header .title {
524 | margin-top: 1px;
525 | }
526 |
527 | .toolbar-footer {
528 | border-top: 1px solid #c2c0c2;
529 | -webkit-app-region: drag;
530 | }
531 |
532 | .title {
533 | margin: 0;
534 | font-size: 12px;
535 | font-weight: 400;
536 | text-align: center;
537 | color: #555;
538 | cursor: default;
539 | }
540 |
541 | .toolbar-borderless {
542 | border-top: 0;
543 | border-bottom: 0;
544 | }
545 |
546 | .toolbar-actions {
547 | margin-top: 4px;
548 | margin-bottom: 3px;
549 | padding-right: 3px;
550 | padding-left: 3px;
551 | padding-bottom: 3px;
552 | -webkit-app-region: drag;
553 | }
554 | .toolbar-actions:before, .toolbar-actions:after {
555 | display: table;
556 | content: " ";
557 | }
558 | .toolbar-actions:after {
559 | clear: both;
560 | }
561 | .toolbar-actions > .btn,
562 | .toolbar-actions > .btn-group {
563 | margin-left: 4px;
564 | margin-right: 4px;
565 | }
566 |
567 | label {
568 | display: inline-block;
569 | font-size: 13px;
570 | margin-bottom: 5px;
571 | white-space: nowrap;
572 | overflow: hidden;
573 | text-overflow: ellipsis;
574 | }
575 |
576 | input[type="search"] {
577 | box-sizing: border-box;
578 | }
579 |
580 | input[type="radio"],
581 | input[type="checkbox"] {
582 | margin: 4px 0 0;
583 | line-height: normal;
584 | }
585 |
586 | .form-control {
587 | display: inline-block;
588 | width: 100%;
589 | min-height: 25px;
590 | padding: 5px 10px;
591 | font-size: 13px;
592 | line-height: 1.6;
593 | background-color: #fff;
594 | border: 1px solid #ddd;
595 | border-radius: 4px;
596 | outline: none;
597 | }
598 | .form-control:focus {
599 | border-color: #6db3fd;
600 | box-shadow: 3px 3px 0 #6db3fd, -3px -3px 0 #6db3fd, -3px 3px 0 #6db3fd, 3px -3px 0 #6db3fd;
601 | }
602 |
603 | textarea {
604 | height: auto;
605 | }
606 |
607 | .form-group {
608 | margin-bottom: 10px;
609 | }
610 |
611 | .radio,
612 | .checkbox {
613 | position: relative;
614 | display: block;
615 | margin-top: 10px;
616 | margin-bottom: 10px;
617 | }
618 | .radio label,
619 | .checkbox label {
620 | padding-left: 20px;
621 | margin-bottom: 0;
622 | font-weight: normal;
623 | }
624 |
625 | .radio input[type="radio"],
626 | .radio-inline input[type="radio"],
627 | .checkbox input[type="checkbox"],
628 | .checkbox-inline input[type="checkbox"] {
629 | position: absolute;
630 | margin-left: -20px;
631 | margin-top: 4px;
632 | }
633 |
634 | .form-actions .btn {
635 | margin-right: 10px;
636 | }
637 | .form-actions .btn:last-child {
638 | margin-right: 0;
639 | }
640 |
641 | .pane-group {
642 | position: absolute;
643 | top: 0;
644 | right: 0;
645 | bottom: 0;
646 | left: 0;
647 | display: flex;
648 | }
649 |
650 | .pane {
651 | position: relative;
652 | overflow-y: auto;
653 | flex: 1;
654 | border-left: 1px solid #ddd;
655 | }
656 | .pane:first-child {
657 | border-left: 0;
658 | }
659 |
660 | .pane-sm {
661 | max-width: 220px;
662 | min-width: 150px;
663 | }
664 |
665 | .pane-mini {
666 | width: 80px;
667 | flex: none;
668 | }
669 |
670 | .pane-one-fourth {
671 | width: 25%;
672 | flex: none;
673 | }
674 |
675 | .pane-one-third {
676 | width: 33.3%;
677 | }
678 |
679 | img {
680 | -webkit-user-drag: text;
681 | }
682 |
683 | .img-circle {
684 | border-radius: 50%;
685 | }
686 |
687 | .img-rounded {
688 | border-radius: 4px;
689 | }
690 |
691 | .list-group {
692 | width: 100%;
693 | list-style: none;
694 | margin: 0;
695 | padding: 0;
696 | }
697 | .list-group * {
698 | margin: 0;
699 | white-space: nowrap;
700 | overflow: hidden;
701 | text-overflow: ellipsis;
702 | }
703 |
704 | .list-group-item {
705 | padding: 10px;
706 | font-size: 12px;
707 | color: #414142;
708 | border-top: 1px solid #ddd;
709 | }
710 | .list-group-item:first-child {
711 | border-top: 0;
712 | }
713 | .list-group-item.active, .list-group-item.selected {
714 | color: #fff;
715 | background-color: #116cd6;
716 | }
717 |
718 | .list-group-header {
719 | padding: 10px;
720 | }
721 |
722 | .media-object {
723 | margin-top: 3px;
724 | }
725 |
726 | .media-object.pull-left {
727 | margin-right: 10px;
728 | }
729 |
730 | .media-object.pull-right {
731 | margin-left: 10px;
732 | }
733 |
734 | .media-body {
735 | overflow: hidden;
736 | }
737 |
738 | .nav-group {
739 | font-size: 14px;
740 | }
741 |
742 | .nav-group-item {
743 | padding: 2px 10px 2px 25px;
744 | display: block;
745 | color: #333;
746 | text-decoration: none;
747 | white-space: nowrap;
748 | overflow: hidden;
749 | text-overflow: ellipsis;
750 | }
751 | .nav-group-item:active, .nav-group-item.active {
752 | background-color: #dcdfe1;
753 | }
754 | .nav-group-item .icon {
755 | width: 19px;
756 | height: 18px;
757 | float: left;
758 | color: #737475;
759 | margin-top: -3px;
760 | margin-right: 7px;
761 | font-size: 18px;
762 | text-align: center;
763 | }
764 |
765 | .nav-group-title {
766 | margin: 0;
767 | padding: 10px 10px 2px;
768 | font-size: 12px;
769 | font-weight: 500;
770 | color: #666666;
771 | }
772 |
773 | @font-face {
774 | font-family: "photon-entypo";
775 | src: url("../fonts/photon-entypo.eot");
776 | src: url("../fonts/photon-entypo.eot?#iefix") format("eot"), url("../fonts/photon-entypo.woff") format("woff"), url("../fonts/photon-entypo.ttf") format("truetype");
777 | font-weight: normal;
778 | font-style: normal;
779 | }
780 | .icon:before {
781 | position: relative;
782 | display: inline-block;
783 | font-family: "photon-entypo";
784 | speak: none;
785 | font-size: 100%;
786 | font-style: normal;
787 | font-weight: normal;
788 | font-variant: normal;
789 | text-transform: none;
790 | line-height: 1;
791 | -webkit-font-smoothing: antialiased;
792 | -moz-osx-font-smoothing: grayscale;
793 | }
794 |
795 | .icon-note:before {
796 | content: '\e800';
797 | }
798 |
799 | /* '' */
800 | .icon-note-beamed:before {
801 | content: '\e801';
802 | }
803 |
804 | /* '' */
805 | .icon-music:before {
806 | content: '\e802';
807 | }
808 |
809 | /* '' */
810 | .icon-search:before {
811 | content: '\e803';
812 | }
813 |
814 | /* '' */
815 | .icon-flashlight:before {
816 | content: '\e804';
817 | }
818 |
819 | /* '' */
820 | .icon-mail:before {
821 | content: '\e805';
822 | }
823 |
824 | /* '' */
825 | .icon-heart:before {
826 | content: '\e806';
827 | }
828 |
829 | /* '' */
830 | .icon-heart-empty:before {
831 | content: '\e807';
832 | }
833 |
834 | /* '' */
835 | .icon-star:before {
836 | content: '\e808';
837 | }
838 |
839 | /* '' */
840 | .icon-star-empty:before {
841 | content: '\e809';
842 | }
843 |
844 | /* '' */
845 | .icon-user:before {
846 | content: '\e80a';
847 | }
848 |
849 | /* '' */
850 | .icon-users:before {
851 | content: '\e80b';
852 | }
853 |
854 | /* '' */
855 | .icon-user-add:before {
856 | content: '\e80c';
857 | }
858 |
859 | /* '' */
860 | .icon-video:before {
861 | content: '\e80d';
862 | }
863 |
864 | /* '' */
865 | .icon-picture:before {
866 | content: '\e80e';
867 | }
868 |
869 | /* '' */
870 | .icon-camera:before {
871 | content: '\e80f';
872 | }
873 |
874 | /* '' */
875 | .icon-layout:before {
876 | content: '\e810';
877 | }
878 |
879 | /* '' */
880 | .icon-menu:before {
881 | content: '\e811';
882 | }
883 |
884 | /* '' */
885 | .icon-check:before {
886 | content: '\e812';
887 | }
888 |
889 | /* '' */
890 | .icon-cancel:before {
891 | content: '\e813';
892 | }
893 |
894 | /* '' */
895 | .icon-cancel-circled:before {
896 | content: '\e814';
897 | }
898 |
899 | /* '' */
900 | .icon-cancel-squared:before {
901 | content: '\e815';
902 | }
903 |
904 | /* '' */
905 | .icon-plus:before {
906 | content: '\e816';
907 | }
908 |
909 | /* '' */
910 | .icon-plus-circled:before {
911 | content: '\e817';
912 | }
913 |
914 | /* '' */
915 | .icon-plus-squared:before {
916 | content: '\e818';
917 | }
918 |
919 | /* '' */
920 | .icon-minus:before {
921 | content: '\e819';
922 | }
923 |
924 | /* '' */
925 | .icon-minus-circled:before {
926 | content: '\e81a';
927 | }
928 |
929 | /* '' */
930 | .icon-minus-squared:before {
931 | content: '\e81b';
932 | }
933 |
934 | /* '' */
935 | .icon-help:before {
936 | content: '\e81c';
937 | }
938 |
939 | /* '' */
940 | .icon-help-circled:before {
941 | content: '\e81d';
942 | }
943 |
944 | /* '' */
945 | .icon-info:before {
946 | content: '\e81e';
947 | }
948 |
949 | /* '' */
950 | .icon-info-circled:before {
951 | content: '\e81f';
952 | }
953 |
954 | /* '' */
955 | .icon-back:before {
956 | content: '\e820';
957 | }
958 |
959 | /* '' */
960 | .icon-home:before {
961 | content: '\e821';
962 | }
963 |
964 | /* '' */
965 | .icon-link:before {
966 | content: '\e822';
967 | }
968 |
969 | /* '' */
970 | .icon-attach:before {
971 | content: '\e823';
972 | }
973 |
974 | /* '' */
975 | .icon-lock:before {
976 | content: '\e824';
977 | }
978 |
979 | /* '' */
980 | .icon-lock-open:before {
981 | content: '\e825';
982 | }
983 |
984 | /* '' */
985 | .icon-eye:before {
986 | content: '\e826';
987 | }
988 |
989 | /* '' */
990 | .icon-tag:before {
991 | content: '\e827';
992 | }
993 |
994 | /* '' */
995 | .icon-bookmark:before {
996 | content: '\e828';
997 | }
998 |
999 | /* '' */
1000 | .icon-bookmarks:before {
1001 | content: '\e829';
1002 | }
1003 |
1004 | /* '' */
1005 | .icon-flag:before {
1006 | content: '\e82a';
1007 | }
1008 |
1009 | /* '' */
1010 | .icon-thumbs-up:before {
1011 | content: '\e82b';
1012 | }
1013 |
1014 | /* '' */
1015 | .icon-thumbs-down:before {
1016 | content: '\e82c';
1017 | }
1018 |
1019 | /* '' */
1020 | .icon-download:before {
1021 | content: '\e82d';
1022 | }
1023 |
1024 | /* '' */
1025 | .icon-upload:before {
1026 | content: '\e82e';
1027 | }
1028 |
1029 | /* '' */
1030 | .icon-upload-cloud:before {
1031 | content: '\e82f';
1032 | }
1033 |
1034 | /* '' */
1035 | .icon-reply:before {
1036 | content: '\e830';
1037 | }
1038 |
1039 | /* '' */
1040 | .icon-reply-all:before {
1041 | content: '\e831';
1042 | }
1043 |
1044 | /* '' */
1045 | .icon-forward:before {
1046 | content: '\e832';
1047 | }
1048 |
1049 | /* '' */
1050 | .icon-quote:before {
1051 | content: '\e833';
1052 | }
1053 |
1054 | /* '' */
1055 | .icon-code:before {
1056 | content: '\e834';
1057 | }
1058 |
1059 | /* '' */
1060 | .icon-export:before {
1061 | content: '\e835';
1062 | }
1063 |
1064 | /* '' */
1065 | .icon-pencil:before {
1066 | content: '\e836';
1067 | }
1068 |
1069 | /* '' */
1070 | .icon-feather:before {
1071 | content: '\e837';
1072 | }
1073 |
1074 | /* '' */
1075 | .icon-print:before {
1076 | content: '\e838';
1077 | }
1078 |
1079 | /* '' */
1080 | .icon-retweet:before {
1081 | content: '\e839';
1082 | }
1083 |
1084 | /* '' */
1085 | .icon-keyboard:before {
1086 | content: '\e83a';
1087 | }
1088 |
1089 | /* '' */
1090 | .icon-comment:before {
1091 | content: '\e83b';
1092 | }
1093 |
1094 | /* '' */
1095 | .icon-chat:before {
1096 | content: '\e83c';
1097 | }
1098 |
1099 | /* '' */
1100 | .icon-bell:before {
1101 | content: '\e83d';
1102 | }
1103 |
1104 | /* '' */
1105 | .icon-attention:before {
1106 | content: '\e83e';
1107 | }
1108 |
1109 | /* '' */
1110 | .icon-alert:before {
1111 | content: '\e83f';
1112 | }
1113 |
1114 | /* '' */
1115 | .icon-vcard:before {
1116 | content: '\e840';
1117 | }
1118 |
1119 | /* '' */
1120 | .icon-address:before {
1121 | content: '\e841';
1122 | }
1123 |
1124 | /* '' */
1125 | .icon-location:before {
1126 | content: '\e842';
1127 | }
1128 |
1129 | /* '' */
1130 | .icon-map:before {
1131 | content: '\e843';
1132 | }
1133 |
1134 | /* '' */
1135 | .icon-direction:before {
1136 | content: '\e844';
1137 | }
1138 |
1139 | /* '' */
1140 | .icon-compass:before {
1141 | content: '\e845';
1142 | }
1143 |
1144 | /* '' */
1145 | .icon-cup:before {
1146 | content: '\e846';
1147 | }
1148 |
1149 | /* '' */
1150 | .icon-trash:before {
1151 | content: '\e847';
1152 | }
1153 |
1154 | /* '' */
1155 | .icon-doc:before {
1156 | content: '\e848';
1157 | }
1158 |
1159 | /* '' */
1160 | .icon-docs:before {
1161 | content: '\e849';
1162 | }
1163 |
1164 | /* '' */
1165 | .icon-doc-landscape:before {
1166 | content: '\e84a';
1167 | }
1168 |
1169 | /* '' */
1170 | .icon-doc-text:before {
1171 | content: '\e84b';
1172 | }
1173 |
1174 | /* '' */
1175 | .icon-doc-text-inv:before {
1176 | content: '\e84c';
1177 | }
1178 |
1179 | /* '' */
1180 | .icon-newspaper:before {
1181 | content: '\e84d';
1182 | }
1183 |
1184 | /* '' */
1185 | .icon-book-open:before {
1186 | content: '\e84e';
1187 | }
1188 |
1189 | /* '' */
1190 | .icon-book:before {
1191 | content: '\e84f';
1192 | }
1193 |
1194 | /* '' */
1195 | .icon-folder:before {
1196 | content: '\e850';
1197 | }
1198 |
1199 | /* '' */
1200 | .icon-archive:before {
1201 | content: '\e851';
1202 | }
1203 |
1204 | /* '' */
1205 | .icon-box:before {
1206 | content: '\e852';
1207 | }
1208 |
1209 | /* '' */
1210 | .icon-rss:before {
1211 | content: '\e853';
1212 | }
1213 |
1214 | /* '' */
1215 | .icon-phone:before {
1216 | content: '\e854';
1217 | }
1218 |
1219 | /* '' */
1220 | .icon-cog:before {
1221 | content: '\e855';
1222 | }
1223 |
1224 | /* '' */
1225 | .icon-tools:before {
1226 | content: '\e856';
1227 | }
1228 |
1229 | /* '' */
1230 | .icon-share:before {
1231 | content: '\e857';
1232 | }
1233 |
1234 | /* '' */
1235 | .icon-shareable:before {
1236 | content: '\e858';
1237 | }
1238 |
1239 | /* '' */
1240 | .icon-basket:before {
1241 | content: '\e859';
1242 | }
1243 |
1244 | /* '' */
1245 | .icon-bag:before {
1246 | content: '\e85a';
1247 | }
1248 |
1249 | /* '' */
1250 | .icon-calendar:before {
1251 | content: '\e85b';
1252 | }
1253 |
1254 | /* '' */
1255 | .icon-login:before {
1256 | content: '\e85c';
1257 | }
1258 |
1259 | /* '' */
1260 | .icon-logout:before {
1261 | content: '\e85d';
1262 | }
1263 |
1264 | /* '' */
1265 | .icon-mic:before {
1266 | content: '\e85e';
1267 | }
1268 |
1269 | /* '' */
1270 | .icon-mute:before {
1271 | content: '\e85f';
1272 | }
1273 |
1274 | /* '' */
1275 | .icon-sound:before {
1276 | content: '\e860';
1277 | }
1278 |
1279 | /* '' */
1280 | .icon-volume:before {
1281 | content: '\e861';
1282 | }
1283 |
1284 | /* '' */
1285 | .icon-clock:before {
1286 | content: '\e862';
1287 | }
1288 |
1289 | /* '' */
1290 | .icon-hourglass:before {
1291 | content: '\e863';
1292 | }
1293 |
1294 | /* '' */
1295 | .icon-lamp:before {
1296 | content: '\e864';
1297 | }
1298 |
1299 | /* '' */
1300 | .icon-light-down:before {
1301 | content: '\e865';
1302 | }
1303 |
1304 | /* '' */
1305 | .icon-light-up:before {
1306 | content: '\e866';
1307 | }
1308 |
1309 | /* '' */
1310 | .icon-adjust:before {
1311 | content: '\e867';
1312 | }
1313 |
1314 | /* '' */
1315 | .icon-block:before {
1316 | content: '\e868';
1317 | }
1318 |
1319 | /* '' */
1320 | .icon-resize-full:before {
1321 | content: '\e869';
1322 | }
1323 |
1324 | /* '' */
1325 | .icon-resize-small:before {
1326 | content: '\e86a';
1327 | }
1328 |
1329 | /* '' */
1330 | .icon-popup:before {
1331 | content: '\e86b';
1332 | }
1333 |
1334 | /* '' */
1335 | .icon-publish:before {
1336 | content: '\e86c';
1337 | }
1338 |
1339 | /* '' */
1340 | .icon-window:before {
1341 | content: '\e86d';
1342 | }
1343 |
1344 | /* '' */
1345 | .icon-arrow-combo:before {
1346 | content: '\e86e';
1347 | }
1348 |
1349 | /* '' */
1350 | .icon-down-circled:before {
1351 | content: '\e86f';
1352 | }
1353 |
1354 | /* '' */
1355 | .icon-left-circled:before {
1356 | content: '\e870';
1357 | }
1358 |
1359 | /* '' */
1360 | .icon-right-circled:before {
1361 | content: '\e871';
1362 | }
1363 |
1364 | /* '' */
1365 | .icon-up-circled:before {
1366 | content: '\e872';
1367 | }
1368 |
1369 | /* '' */
1370 | .icon-down-open:before {
1371 | content: '\e873';
1372 | }
1373 |
1374 | /* '' */
1375 | .icon-left-open:before {
1376 | content: '\e874';
1377 | }
1378 |
1379 | /* '' */
1380 | .icon-right-open:before {
1381 | content: '\e875';
1382 | }
1383 |
1384 | /* '' */
1385 | .icon-up-open:before {
1386 | content: '\e876';
1387 | }
1388 |
1389 | /* '' */
1390 | .icon-down-open-mini:before {
1391 | content: '\e877';
1392 | }
1393 |
1394 | /* '' */
1395 | .icon-left-open-mini:before {
1396 | content: '\e878';
1397 | }
1398 |
1399 | /* '' */
1400 | .icon-right-open-mini:before {
1401 | content: '\e879';
1402 | }
1403 |
1404 | /* '' */
1405 | .icon-up-open-mini:before {
1406 | content: '\e87a';
1407 | }
1408 |
1409 | /* '' */
1410 | .icon-down-open-big:before {
1411 | content: '\e87b';
1412 | }
1413 |
1414 | /* '' */
1415 | .icon-left-open-big:before {
1416 | content: '\e87c';
1417 | }
1418 |
1419 | /* '' */
1420 | .icon-right-open-big:before {
1421 | content: '\e87d';
1422 | }
1423 |
1424 | /* '' */
1425 | .icon-up-open-big:before {
1426 | content: '\e87e';
1427 | }
1428 |
1429 | /* '' */
1430 | .icon-down:before {
1431 | content: '\e87f';
1432 | }
1433 |
1434 | /* '' */
1435 | .icon-left:before {
1436 | content: '\e880';
1437 | }
1438 |
1439 | /* '' */
1440 | .icon-right:before {
1441 | content: '\e881';
1442 | }
1443 |
1444 | /* '' */
1445 | .icon-up:before {
1446 | content: '\e882';
1447 | }
1448 |
1449 | /* '' */
1450 | .icon-down-dir:before {
1451 | content: '\e883';
1452 | }
1453 |
1454 | /* '' */
1455 | .icon-left-dir:before {
1456 | content: '\e884';
1457 | }
1458 |
1459 | /* '' */
1460 | .icon-right-dir:before {
1461 | content: '\e885';
1462 | }
1463 |
1464 | /* '' */
1465 | .icon-up-dir:before {
1466 | content: '\e886';
1467 | }
1468 |
1469 | /* '' */
1470 | .icon-down-bold:before {
1471 | content: '\e887';
1472 | }
1473 |
1474 | /* '' */
1475 | .icon-left-bold:before {
1476 | content: '\e888';
1477 | }
1478 |
1479 | /* '' */
1480 | .icon-right-bold:before {
1481 | content: '\e889';
1482 | }
1483 |
1484 | /* '' */
1485 | .icon-up-bold:before {
1486 | content: '\e88a';
1487 | }
1488 |
1489 | /* '' */
1490 | .icon-down-thin:before {
1491 | content: '\e88b';
1492 | }
1493 |
1494 | /* '' */
1495 | .icon-left-thin:before {
1496 | content: '\e88c';
1497 | }
1498 |
1499 | /* '' */
1500 | .icon-right-thin:before {
1501 | content: '\e88d';
1502 | }
1503 |
1504 | /* '' */
1505 | .icon-up-thin:before {
1506 | content: '\e88e';
1507 | }
1508 |
1509 | /* '' */
1510 | .icon-ccw:before {
1511 | content: '\e88f';
1512 | }
1513 |
1514 | /* '' */
1515 | .icon-cw:before {
1516 | content: '\e890';
1517 | }
1518 |
1519 | /* '' */
1520 | .icon-arrows-ccw:before {
1521 | content: '\e891';
1522 | }
1523 |
1524 | /* '' */
1525 | .icon-level-down:before {
1526 | content: '\e892';
1527 | }
1528 |
1529 | /* '' */
1530 | .icon-level-up:before {
1531 | content: '\e893';
1532 | }
1533 |
1534 | /* '' */
1535 | .icon-shuffle:before {
1536 | content: '\e894';
1537 | }
1538 |
1539 | /* '' */
1540 | .icon-loop:before {
1541 | content: '\e895';
1542 | }
1543 |
1544 | /* '' */
1545 | .icon-switch:before {
1546 | content: '\e896';
1547 | }
1548 |
1549 | /* '' */
1550 | .icon-play:before {
1551 | content: '\e897';
1552 | }
1553 |
1554 | /* '' */
1555 | .icon-stop:before {
1556 | content: '\e898';
1557 | }
1558 |
1559 | /* '' */
1560 | .icon-pause:before {
1561 | content: '\e899';
1562 | }
1563 |
1564 | /* '' */
1565 | .icon-record:before {
1566 | content: '\e89a';
1567 | }
1568 |
1569 | /* '' */
1570 | .icon-to-end:before {
1571 | content: '\e89b';
1572 | }
1573 |
1574 | /* '' */
1575 | .icon-to-start:before {
1576 | content: '\e89c';
1577 | }
1578 |
1579 | /* '' */
1580 | .icon-fast-forward:before {
1581 | content: '\e89d';
1582 | }
1583 |
1584 | /* '' */
1585 | .icon-fast-backward:before {
1586 | content: '\e89e';
1587 | }
1588 |
1589 | /* '' */
1590 | .icon-progress-0:before {
1591 | content: '\e89f';
1592 | }
1593 |
1594 | /* '' */
1595 | .icon-progress-1:before {
1596 | content: '\e8a0';
1597 | }
1598 |
1599 | /* '' */
1600 | .icon-progress-2:before {
1601 | content: '\e8a1';
1602 | }
1603 |
1604 | /* '' */
1605 | .icon-progress-3:before {
1606 | content: '\e8a2';
1607 | }
1608 |
1609 | /* '' */
1610 | .icon-target:before {
1611 | content: '\e8a3';
1612 | }
1613 |
1614 | /* '' */
1615 | .icon-palette:before {
1616 | content: '\e8a4';
1617 | }
1618 |
1619 | /* '' */
1620 | .icon-list:before {
1621 | content: '\e8a5';
1622 | }
1623 |
1624 | /* '' */
1625 | .icon-list-add:before {
1626 | content: '\e8a6';
1627 | }
1628 |
1629 | /* '' */
1630 | .icon-signal:before {
1631 | content: '\e8a7';
1632 | }
1633 |
1634 | /* '' */
1635 | .icon-trophy:before {
1636 | content: '\e8a8';
1637 | }
1638 |
1639 | /* '' */
1640 | .icon-battery:before {
1641 | content: '\e8a9';
1642 | }
1643 |
1644 | /* '' */
1645 | .icon-back-in-time:before {
1646 | content: '\e8aa';
1647 | }
1648 |
1649 | /* '' */
1650 | .icon-monitor:before {
1651 | content: '\e8ab';
1652 | }
1653 |
1654 | /* '' */
1655 | .icon-mobile:before {
1656 | content: '\e8ac';
1657 | }
1658 |
1659 | /* '' */
1660 | .icon-network:before {
1661 | content: '\e8ad';
1662 | }
1663 |
1664 | /* '' */
1665 | .icon-cd:before {
1666 | content: '\e8ae';
1667 | }
1668 |
1669 | /* '' */
1670 | .icon-inbox:before {
1671 | content: '\e8af';
1672 | }
1673 |
1674 | /* '' */
1675 | .icon-install:before {
1676 | content: '\e8b0';
1677 | }
1678 |
1679 | /* '' */
1680 | .icon-globe:before {
1681 | content: '\e8b1';
1682 | }
1683 |
1684 | /* '' */
1685 | .icon-cloud:before {
1686 | content: '\e8b2';
1687 | }
1688 |
1689 | /* '' */
1690 | .icon-cloud-thunder:before {
1691 | content: '\e8b3';
1692 | }
1693 |
1694 | /* '' */
1695 | .icon-flash:before {
1696 | content: '\e8b4';
1697 | }
1698 |
1699 | /* '' */
1700 | .icon-moon:before {
1701 | content: '\e8b5';
1702 | }
1703 |
1704 | /* '' */
1705 | .icon-flight:before {
1706 | content: '\e8b6';
1707 | }
1708 |
1709 | /* '' */
1710 | .icon-paper-plane:before {
1711 | content: '\e8b7';
1712 | }
1713 |
1714 | /* '' */
1715 | .icon-leaf:before {
1716 | content: '\e8b8';
1717 | }
1718 |
1719 | /* '' */
1720 | .icon-lifebuoy:before {
1721 | content: '\e8b9';
1722 | }
1723 |
1724 | /* '' */
1725 | .icon-mouse:before {
1726 | content: '\e8ba';
1727 | }
1728 |
1729 | /* '' */
1730 | .icon-briefcase:before {
1731 | content: '\e8bb';
1732 | }
1733 |
1734 | /* '' */
1735 | .icon-suitcase:before {
1736 | content: '\e8bc';
1737 | }
1738 |
1739 | /* '' */
1740 | .icon-dot:before {
1741 | content: '\e8bd';
1742 | }
1743 |
1744 | /* '' */
1745 | .icon-dot-2:before {
1746 | content: '\e8be';
1747 | }
1748 |
1749 | /* '' */
1750 | .icon-dot-3:before {
1751 | content: '\e8bf';
1752 | }
1753 |
1754 | /* '' */
1755 | .icon-brush:before {
1756 | content: '\e8c0';
1757 | }
1758 |
1759 | /* '' */
1760 | .icon-magnet:before {
1761 | content: '\e8c1';
1762 | }
1763 |
1764 | /* '' */
1765 | .icon-infinity:before {
1766 | content: '\e8c2';
1767 | }
1768 |
1769 | /* '' */
1770 | .icon-erase:before {
1771 | content: '\e8c3';
1772 | }
1773 |
1774 | /* '' */
1775 | .icon-chart-pie:before {
1776 | content: '\e8c4';
1777 | }
1778 |
1779 | /* '' */
1780 | .icon-chart-line:before {
1781 | content: '\e8c5';
1782 | }
1783 |
1784 | /* '' */
1785 | .icon-chart-bar:before {
1786 | content: '\e8c6';
1787 | }
1788 |
1789 | /* '' */
1790 | .icon-chart-area:before {
1791 | content: '\e8c7';
1792 | }
1793 |
1794 | /* '' */
1795 | .icon-tape:before {
1796 | content: '\e8c8';
1797 | }
1798 |
1799 | /* '' */
1800 | .icon-graduation-cap:before {
1801 | content: '\e8c9';
1802 | }
1803 |
1804 | /* '' */
1805 | .icon-language:before {
1806 | content: '\e8ca';
1807 | }
1808 |
1809 | /* '' */
1810 | .icon-ticket:before {
1811 | content: '\e8cb';
1812 | }
1813 |
1814 | /* '' */
1815 | .icon-water:before {
1816 | content: '\e8cc';
1817 | }
1818 |
1819 | /* '' */
1820 | .icon-droplet:before {
1821 | content: '\e8cd';
1822 | }
1823 |
1824 | /* '' */
1825 | .icon-air:before {
1826 | content: '\e8ce';
1827 | }
1828 |
1829 | /* '' */
1830 | .icon-credit-card:before {
1831 | content: '\e8cf';
1832 | }
1833 |
1834 | /* '' */
1835 | .icon-floppy:before {
1836 | content: '\e8d0';
1837 | }
1838 |
1839 | /* '' */
1840 | .icon-clipboard:before {
1841 | content: '\e8d1';
1842 | }
1843 |
1844 | /* '' */
1845 | .icon-megaphone:before {
1846 | content: '\e8d2';
1847 | }
1848 |
1849 | /* '' */
1850 | .icon-database:before {
1851 | content: '\e8d3';
1852 | }
1853 |
1854 | /* '' */
1855 | .icon-drive:before {
1856 | content: '\e8d4';
1857 | }
1858 |
1859 | /* '' */
1860 | .icon-bucket:before {
1861 | content: '\e8d5';
1862 | }
1863 |
1864 | /* '' */
1865 | .icon-thermometer:before {
1866 | content: '\e8d6';
1867 | }
1868 |
1869 | /* '' */
1870 | .icon-key:before {
1871 | content: '\e8d7';
1872 | }
1873 |
1874 | /* '' */
1875 | .icon-flow-cascade:before {
1876 | content: '\e8d8';
1877 | }
1878 |
1879 | /* '' */
1880 | .icon-flow-branch:before {
1881 | content: '\e8d9';
1882 | }
1883 |
1884 | /* '' */
1885 | .icon-flow-tree:before {
1886 | content: '\e8da';
1887 | }
1888 |
1889 | /* '' */
1890 | .icon-flow-line:before {
1891 | content: '\e8db';
1892 | }
1893 |
1894 | /* '' */
1895 | .icon-flow-parallel:before {
1896 | content: '\e8dc';
1897 | }
1898 |
1899 | /* '' */
1900 | .icon-rocket:before {
1901 | content: '\e8dd';
1902 | }
1903 |
1904 | /* '' */
1905 | .icon-gauge:before {
1906 | content: '\e8de';
1907 | }
1908 |
1909 | /* '' */
1910 | .icon-traffic-cone:before {
1911 | content: '\e8df';
1912 | }
1913 |
1914 | /* '' */
1915 | .icon-cc:before {
1916 | content: '\e8e0';
1917 | }
1918 |
1919 | /* '' */
1920 | .icon-cc-by:before {
1921 | content: '\e8e1';
1922 | }
1923 |
1924 | /* '' */
1925 | .icon-cc-nc:before {
1926 | content: '\e8e2';
1927 | }
1928 |
1929 | /* '' */
1930 | .icon-cc-nc-eu:before {
1931 | content: '\e8e3';
1932 | }
1933 |
1934 | /* '' */
1935 | .icon-cc-nc-jp:before {
1936 | content: '\e8e4';
1937 | }
1938 |
1939 | /* '' */
1940 | .icon-cc-sa:before {
1941 | content: '\e8e5';
1942 | }
1943 |
1944 | /* '' */
1945 | .icon-cc-nd:before {
1946 | content: '\e8e6';
1947 | }
1948 |
1949 | /* '' */
1950 | .icon-cc-pd:before {
1951 | content: '\e8e7';
1952 | }
1953 |
1954 | /* '' */
1955 | .icon-cc-zero:before {
1956 | content: '\e8e8';
1957 | }
1958 |
1959 | /* '' */
1960 | .icon-cc-share:before {
1961 | content: '\e8e9';
1962 | }
1963 |
1964 | /* '' */
1965 | .icon-cc-remix:before {
1966 | content: '\e8ea';
1967 | }
1968 |
1969 | /* '' */
1970 | .icon-github:before {
1971 | content: '\e8eb';
1972 | }
1973 |
1974 | /* '' */
1975 | .icon-github-circled:before {
1976 | content: '\e8ec';
1977 | }
1978 |
1979 | /* '' */
1980 | .icon-flickr:before {
1981 | content: '\e8ed';
1982 | }
1983 |
1984 | /* '' */
1985 | .icon-flickr-circled:before {
1986 | content: '\e8ee';
1987 | }
1988 |
1989 | /* '' */
1990 | .icon-vimeo:before {
1991 | content: '\e8ef';
1992 | }
1993 |
1994 | /* '' */
1995 | .icon-vimeo-circled:before {
1996 | content: '\e8f0';
1997 | }
1998 |
1999 | /* '' */
2000 | .icon-twitter:before {
2001 | content: '\e8f1';
2002 | }
2003 |
2004 | /* '' */
2005 | .icon-twitter-circled:before {
2006 | content: '\e8f2';
2007 | }
2008 |
2009 | /* '' */
2010 | .icon-facebook:before {
2011 | content: '\e8f3';
2012 | }
2013 |
2014 | /* '' */
2015 | .icon-facebook-circled:before {
2016 | content: '\e8f4';
2017 | }
2018 |
2019 | /* '' */
2020 | .icon-facebook-squared:before {
2021 | content: '\e8f5';
2022 | }
2023 |
2024 | /* '' */
2025 | .icon-gplus:before {
2026 | content: '\e8f6';
2027 | }
2028 |
2029 | /* '' */
2030 | .icon-gplus-circled:before {
2031 | content: '\e8f7';
2032 | }
2033 |
2034 | /* '' */
2035 | .icon-pinterest:before {
2036 | content: '\e8f8';
2037 | }
2038 |
2039 | /* '' */
2040 | .icon-pinterest-circled:before {
2041 | content: '\e8f9';
2042 | }
2043 |
2044 | /* '' */
2045 | .icon-tumblr:before {
2046 | content: '\e8fa';
2047 | }
2048 |
2049 | /* '' */
2050 | .icon-tumblr-circled:before {
2051 | content: '\e8fb';
2052 | }
2053 |
2054 | /* '' */
2055 | .icon-linkedin:before {
2056 | content: '\e8fc';
2057 | }
2058 |
2059 | /* '' */
2060 | .icon-linkedin-circled:before {
2061 | content: '\e8fd';
2062 | }
2063 |
2064 | /* '' */
2065 | .icon-dribbble:before {
2066 | content: '\e8fe';
2067 | }
2068 |
2069 | /* '' */
2070 | .icon-dribbble-circled:before {
2071 | content: '\e8ff';
2072 | }
2073 |
2074 | /* '' */
2075 | .icon-stumbleupon:before {
2076 | content: '\e900';
2077 | }
2078 |
2079 | /* '' */
2080 | .icon-stumbleupon-circled:before {
2081 | content: '\e901';
2082 | }
2083 |
2084 | /* '' */
2085 | .icon-lastfm:before {
2086 | content: '\e902';
2087 | }
2088 |
2089 | /* '' */
2090 | .icon-lastfm-circled:before {
2091 | content: '\e903';
2092 | }
2093 |
2094 | /* '' */
2095 | .icon-rdio:before {
2096 | content: '\e904';
2097 | }
2098 |
2099 | /* '' */
2100 | .icon-rdio-circled:before {
2101 | content: '\e905';
2102 | }
2103 |
2104 | /* '' */
2105 | .icon-spotify:before {
2106 | content: '\e906';
2107 | }
2108 |
2109 | /* '' */
2110 | .icon-spotify-circled:before {
2111 | content: '\e907';
2112 | }
2113 |
2114 | /* '' */
2115 | .icon-qq:before {
2116 | content: '\e908';
2117 | }
2118 |
2119 | /* '' */
2120 | .icon-instagram:before {
2121 | content: '\e909';
2122 | }
2123 |
2124 | /* '' */
2125 | .icon-dropbox:before {
2126 | content: '\e90a';
2127 | }
2128 |
2129 | /* '' */
2130 | .icon-evernote:before {
2131 | content: '\e90b';
2132 | }
2133 |
2134 | /* '' */
2135 | .icon-flattr:before {
2136 | content: '\e90c';
2137 | }
2138 |
2139 | /* '' */
2140 | .icon-skype:before {
2141 | content: '\e90d';
2142 | }
2143 |
2144 | /* '' */
2145 | .icon-skype-circled:before {
2146 | content: '\e90e';
2147 | }
2148 |
2149 | /* '' */
2150 | .icon-renren:before {
2151 | content: '\e90f';
2152 | }
2153 |
2154 | /* '' */
2155 | .icon-sina-weibo:before {
2156 | content: '\e910';
2157 | }
2158 |
2159 | /* '' */
2160 | .icon-paypal:before {
2161 | content: '\e911';
2162 | }
2163 |
2164 | /* '' */
2165 | .icon-picasa:before {
2166 | content: '\e912';
2167 | }
2168 |
2169 | /* '' */
2170 | .icon-soundcloud:before {
2171 | content: '\e913';
2172 | }
2173 |
2174 | /* '' */
2175 | .icon-mixi:before {
2176 | content: '\e914';
2177 | }
2178 |
2179 | /* '' */
2180 | .icon-behance:before {
2181 | content: '\e915';
2182 | }
2183 |
2184 | /* '' */
2185 | .icon-google-circles:before {
2186 | content: '\e916';
2187 | }
2188 |
2189 | /* '' */
2190 | .icon-vkontakte:before {
2191 | content: '\e917';
2192 | }
2193 |
2194 | /* '' */
2195 | .icon-smashing:before {
2196 | content: '\e918';
2197 | }
2198 |
2199 | /* '' */
2200 | .icon-sweden:before {
2201 | content: '\e919';
2202 | }
2203 |
2204 | /* '' */
2205 | .icon-db-shape:before {
2206 | content: '\e91a';
2207 | }
2208 |
2209 | /* '' */
2210 | .icon-logo-db:before {
2211 | content: '\e91b';
2212 | }
2213 |
2214 | /* '' */
2215 | table {
2216 | width: 100%;
2217 | border: 0;
2218 | border-collapse: separate;
2219 | font-size: 12px;
2220 | text-align: left;
2221 | }
2222 |
2223 | thead {
2224 | background-color: #f5f5f4;
2225 | }
2226 |
2227 | tbody {
2228 | background-color: #fff;
2229 | }
2230 |
2231 | .table-striped tr:nth-child(even) {
2232 | background-color: #f5f5f4;
2233 | }
2234 |
2235 | tr:active,
2236 | .table-striped tr:active:nth-child(even) {
2237 | color: #fff;
2238 | background-color: #116cd6;
2239 | }
2240 |
2241 | thead tr:active {
2242 | color: #333;
2243 | background-color: #f5f5f4;
2244 | }
2245 |
2246 | th {
2247 | font-weight: normal;
2248 | border-right: 1px solid #ddd;
2249 | border-bottom: 1px solid #ddd;
2250 | }
2251 |
2252 | th,
2253 | td {
2254 | padding: 2px 15px;
2255 | white-space: nowrap;
2256 | overflow: hidden;
2257 | text-overflow: ellipsis;
2258 | }
2259 | th:last-child,
2260 | td:last-child {
2261 | border-right: 0;
2262 | }
2263 |
2264 | .tab-group {
2265 | margin-top: -1px;
2266 | display: flex;
2267 | border-top: 1px solid #989698;
2268 | border-bottom: 1px solid #989698;
2269 | }
2270 |
2271 | .tab-item {
2272 | position: relative;
2273 | flex: 1;
2274 | padding: 3px;
2275 | font-size: 12px;
2276 | text-align: center;
2277 | border-left: 1px solid #989698;
2278 | background-color: #b8b6b8;
2279 | background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #b8b6b8), color-stop(100%, #b0aeb0));
2280 | background-image: -webkit-linear-gradient(top, #b8b6b8 0%, #b0aeb0 100%);
2281 | background-image: linear-gradient(to bottom, #b8b6b8 0%, #b0aeb0 100%);
2282 | }
2283 | .tab-item:first-child {
2284 | border-left: 0;
2285 | }
2286 | .tab-item.active {
2287 | background-color: #d4d2d4;
2288 | background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #d4d2d4), color-stop(100%, #cccacc));
2289 | background-image: -webkit-linear-gradient(top, #d4d2d4 0%, #cccacc 100%);
2290 | background-image: linear-gradient(to bottom, #d4d2d4 0%, #cccacc 100%);
2291 | }
2292 | .tab-item .icon-close-tab {
2293 | position: absolute;
2294 | top: 50%;
2295 | left: 5px;
2296 | width: 15px;
2297 | height: 15px;
2298 | font-size: 15px;
2299 | line-height: 15px;
2300 | text-align: center;
2301 | color: #666;
2302 | opacity: 0;
2303 | transition: opacity .1s linear, background-color .1s linear;
2304 | border-radius: 3px;
2305 | transform: translateY(-50%);
2306 | z-index: 10;
2307 | }
2308 | .tab-item:after {
2309 | position: absolute;
2310 | top: 0;
2311 | right: 0;
2312 | bottom: 0;
2313 | left: 0;
2314 | content: "";
2315 | background-color: rgba(0, 0, 0, 0.08);
2316 | opacity: 0;
2317 | transition: opacity .1s linear;
2318 | z-index: 1;
2319 | }
2320 | .tab-item:hover:not(.active):after {
2321 | opacity: 1;
2322 | }
2323 | .tab-item:hover .icon-close-tab {
2324 | opacity: 1;
2325 | }
2326 | .tab-item .icon-close-tab:hover {
2327 | background-color: rgba(0, 0, 0, 0.08);
2328 | }
2329 |
2330 | .tab-item-fixed {
2331 | flex: none;
2332 | padding: 3px 10px;
2333 | }
2334 |
--------------------------------------------------------------------------------