├── static └── .gitkeep ├── .eslintignore ├── favicon.ico ├── docs ├── favicon.ico ├── index.html ├── plugins │ ├── taskList.js │ └── commandList.js └── vue-terminal.min.js ├── .gitattributes ├── .editorconfig ├── .gitignore ├── .postcssrc.js ├── src ├── index.js └── VueTerminal.vue ├── .babelrc ├── LICENSE ├── webpack.config.js ├── package.json ├── README1.x.md ├── README.md ├── .eslintrc.js └── dist └── vue-terminal.min.js /static/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | build/*.js 2 | config/*.js 3 | docs/ 4 | -------------------------------------------------------------------------------- /favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dongsuo/vue-terminal/HEAD/favicon.ico -------------------------------------------------------------------------------- /docs/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dongsuo/vue-terminal/HEAD/docs/favicon.ico -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | *.js text eol=lf 4 | *.vue text eol=lf -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = CRLF 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules/ 3 | npm-debug.log* 4 | yarn-debug.log* 5 | yarn-error.log* 6 | 7 | # Editor directories and files 8 | .idea 9 | .vscode 10 | *.suo 11 | *.ntvs* 12 | *.njsproj 13 | *.sln 14 | *.editorconfig 15 | -------------------------------------------------------------------------------- /.postcssrc.js: -------------------------------------------------------------------------------- 1 | // https://github.com/michael-ciniawsky/postcss-load-config 2 | 3 | module.exports = { 4 | "plugins": { 5 | // to edit target browsers: use "browserslist" field in package.json 6 | "autoprefixer": {} 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import VueTerminal from './VueTerminal.vue' 2 | 3 | // 导出模块 4 | export default VueTerminal 5 | 6 | // global 情况下 自动安装 7 | if (typeof window !== 'undefined' && window.Vue) { 8 | window.Vue.component('vue-terminal', VueTerminal) 9 | } -------------------------------------------------------------------------------- /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | ["env", { 4 | "modules": false, 5 | "targets": { 6 | "browsers": ["> 1%", "last 2 versions", "not ie <= 8"] 7 | } 8 | }], 9 | "stage-2" 10 | ], 11 | "plugins": ["transform-runtime"], 12 | "env": { 13 | "test": { 14 | "presets": ["env", "stage-2"], 15 | "plugins": ["istanbul"] 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /docs/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | VueTerminalEmulator 6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 24 |
25 | 26 | 35 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 dongsuo 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. -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path') 2 | const webpack = require('webpack') 3 | 4 | module.exports = { 5 | entry: './src/index.js', 6 | output: { 7 | path: path.resolve(__dirname, './dist'), 8 | publicPath: '/dist/', 9 | filename: 'vue-terminal.min.js', 10 | library: 'VueTerminal', 11 | libraryTarget: 'umd', 12 | umdNamedDefine: true 13 | 14 | }, 15 | module: { 16 | rules: [ 17 | { 18 | test: /\.vue$/, 19 | loader: 'vue-loader', 20 | options: { 21 | loaders: { 22 | // Since sass-loader (weirdly) has SCSS as its default parse mode, we map 23 | // the "scss" and "sass" values for the lang attribute to the right configs here. 24 | // other preprocessors should work out of the box, no loader config like this necessary. 25 | scss: [ 26 | 'vue-style-loader', 27 | 'css-loader', 28 | 'sass-loader' 29 | ], 30 | sass: [ 31 | 'vue-style-loader', 32 | 'css-loader', 33 | 'sass-loader?indentedSyntax' 34 | ] 35 | } 36 | // other vue-loader options go here 37 | } 38 | }, 39 | { 40 | test: /\.js$/, 41 | loader: 'babel-loader', 42 | exclude: /node_modules/ 43 | }, 44 | { 45 | test: /\.(png|jpg|gif|svg)$/, 46 | loader: 'file-loader', 47 | options: { 48 | name: '[name].[ext]?[hash]' 49 | } 50 | } 51 | ] 52 | }, 53 | resolve: { 54 | alias: { 55 | vue$: 'vue/dist/vue.esm.js' 56 | }, 57 | extensions: ['*', '.js', '.vue', '.json'] 58 | }, 59 | externals: { 60 | vue: { 61 | root: 'Vue', 62 | commonjs: 'vue', 63 | commonjs2: 'vue', 64 | amd: 'vue' 65 | } 66 | }, 67 | devServer: { 68 | historyApiFallback: true, 69 | noInfo: true, 70 | overlay: true 71 | }, 72 | performance: { 73 | hints: false 74 | }, 75 | devtool: '#eval-source-map' 76 | } 77 | 78 | if (process.env.NODE_ENV === 'production') { 79 | module.exports.devtool = '#source-map' 80 | // http://vue-loader.vuejs.org/en/workflow/production.html 81 | module.exports.plugins = (module.exports.plugins || []).concat([ 82 | new webpack.DefinePlugin({ 83 | 'process.env': { 84 | NODE_ENV: '"production"' 85 | } 86 | }), 87 | new webpack.optimize.UglifyJsPlugin({ 88 | sourceMap: true, 89 | compress: { 90 | warnings: false 91 | } 92 | }), 93 | new webpack.LoaderOptionsPlugin({ 94 | minimize: true 95 | }) 96 | ]) 97 | } 98 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vue-terminal", 3 | "version": "1.2.0", 4 | "description": "A terminal emulator in Vue", 5 | "author": "xuxiaofei ", 6 | "main": "dist/vue-terminal.min.js", 7 | "scripts": { 8 | "dev": "cross-env NODE_ENV=development webpack-dev-server --open --hot --content-base='./docs/'", 9 | "build": "cross-env NODE_ENV=production webpack --progress --hide-modules" 10 | }, 11 | "homepage": "https://islasher.com/vue-terminal/", 12 | "repository": { 13 | "type": "git", 14 | "url": "git+https://github.com/dongsuo/vue-terminal.git" 15 | }, 16 | "keywords": [ 17 | "vue", 18 | "terminal" 19 | ], 20 | "license": "MIT", 21 | "devDependencies": { 22 | "autoprefixer": "^7.2.6", 23 | "babel-core": "^6.26.3", 24 | "babel-eslint": "^7.1.1", 25 | "babel-loader": "^7.1.5", 26 | "babel-plugin-transform-runtime": "^6.22.0", 27 | "babel-preset-env": "^1.7.0", 28 | "babel-preset-stage-2": "^6.22.0", 29 | "babel-register": "^6.22.0", 30 | "chalk": "^2.4.1", 31 | "connect-history-api-fallback": "^1.5.0", 32 | "copy-webpack-plugin": "^4.5.4", 33 | "cross-env": "^5.2.0", 34 | "css-loader": "^0.28.11", 35 | "eslint": "^4.18.2", 36 | "eslint-config-airbnb-base": "^11.3.0", 37 | "eslint-friendly-formatter": "^3.0.0", 38 | "eslint-import-resolver-webpack": "^0.8.4", 39 | "eslint-loader": "^1.7.1", 40 | "eslint-plugin-html": "^3.0.0", 41 | "eslint-plugin-import": "^2.14.0", 42 | "eventsource-polyfill": "^0.9.6", 43 | "express": "^4.16.4", 44 | "extract-text-webpack-plugin": "^3.0.0", 45 | "file-loader": "^1.1.11", 46 | "friendly-errors-webpack-plugin": "^1.7.0", 47 | "html-webpack-plugin": "^2.30.1", 48 | "http-proxy-middleware": "^0.17.3", 49 | "node-sass": "^4.9.4", 50 | "opn": "^5.4.0", 51 | "optimize-css-assets-webpack-plugin": "^3.2.0", 52 | "ora": "^1.4.0", 53 | "portfinder": "^1.0.19", 54 | "rimraf": "^2.6.0", 55 | "sass-loader": "^6.0.7", 56 | "semver": "^5.6.0", 57 | "shelljs": "^0.7.6", 58 | "url-loader": "^0.5.8", 59 | "vue-loader": "^13.7.3", 60 | "vue-style-loader": "^3.1.2", 61 | "vue-template-compiler": "^2.5.17", 62 | "webpack": "^3.12.0", 63 | "webpack-bundle-analyzer": "^3.6.1", 64 | "webpack-cli": "^3.1.2", 65 | "webpack-dev-middleware": "^1.12.2", 66 | "webpack-dev-server": "^2.9.1", 67 | "webpack-hot-middleware": "^2.24.3", 68 | "webpack-merge": "^4.1.4" 69 | }, 70 | "engines": { 71 | "node": ">= 4.0.0", 72 | "npm": ">= 3.0.0" 73 | }, 74 | "browserslist": [ 75 | "> 1%", 76 | "last 2 versions", 77 | "not ie <= 8" 78 | ] 79 | } 80 | -------------------------------------------------------------------------------- /docs/plugins/taskList.js: -------------------------------------------------------------------------------- 1 | // const USER_ID = parseInt(Math.random() * 1000) 2 | function generateTime() { 3 | const timeNow = new Date(); 4 | const hours = timeNow.getHours(); 5 | const minutes = timeNow.getMinutes(); 6 | const seconds = timeNow.getSeconds(); 7 | let timeString = '' + hours; 8 | timeString += (minutes < 10 ? ':0' : ':') + minutes; 9 | timeString += (seconds < 10 ? ':0' : ':') + seconds; 10 | return timeString 11 | } 12 | 13 | const mockData = [ 14 | { time: generateTime(), type: 'system', label: 'System', message: 'Welcome to vTerminal, this is an example to show you what this project can do.' }, 15 | { time: generateTime(), type: 'info', label: 'Info', message: 'Terminal Initializing ............' }, 16 | { time: generateTime(), type: 'warning', label: 'warning', message: 'This is a warning message!' }, 17 | { time: generateTime(), type: 'error', label: 'Error', message: 'Oops, something went wrong!' }, 18 | { time: generateTime(), type: 'success', label: 'Success', message: 'Take it easy! everything OK!' } 19 | ] 20 | 21 | const taskList = { 22 | echo: { 23 | description: 'Echoes input', 24 | echo(pushToList, input) { 25 | input = input.split(' ') 26 | input.splice(0, 1) 27 | const p = new Promise(resolve => { 28 | pushToList({ time: generateTime(), label: 'Echo', type: 'success', message: input.join(' ') }); 29 | resolve({ type: 'success', label: '', message: '' }) 30 | }) 31 | return p 32 | } 33 | }, 34 | defaultTask: { 35 | description: 'This is a default task aimed to show you the power of this project.', 36 | defaultTask(pushToList) { 37 | let i = 0; 38 | const p = new Promise(resolve => { 39 | const interval = setInterval(() => { 40 | mockData[i].time = generateTime() 41 | pushToList(mockData[i]); 42 | i++ 43 | if (!mockData[i]) { 44 | clearInterval(interval) 45 | resolve({ type: 'success', label: 'Success', message: 'Example Over!' }) 46 | } 47 | }, 500); 48 | }) 49 | return p 50 | } 51 | }, 52 | open: { 53 | description: 'Open a specified url in a new tab.', 54 | open(pushToList, input) { 55 | const p = new Promise((resolve, reject) => { 56 | let url = input.split(' ')[1] 57 | if (!url) { 58 | reject({ type: 'error', label: 'Error', message: 'a url is required!' }) 59 | return 60 | } 61 | pushToList({ type: 'success', label: 'Success', message: 'Opening' }) 62 | 63 | if (input.split(' ')[1].indexOf('http') === -1) { 64 | url = 'http://' + input.split(' ')[1] 65 | } 66 | window.open(url, '_blank') 67 | resolve({ type: 'success', label: 'Done', message: 'Page Opened!' }) 68 | }) 69 | return p; 70 | } 71 | } 72 | 73 | } 74 | -------------------------------------------------------------------------------- /README1.x.md: -------------------------------------------------------------------------------- 1 | # vue-terminal-emulator 2 | 3 | > A terminal emulator in Vue 4 | 5 | ### message 对象 6 | message 对象对应于命令行中的单条message,其基本结构如下: 7 |   { 8 | time: generateTime(), 9 | type: 'warning', 10 | label: 'warning', 11 | message: 'This is a Waning Message!' 12 | } 13 | 14 | message对象的配置目前支持如上四个字段,其基本含义如下: 15 | - time字段可省略,建议使用提供的 generateTime 方法,也可自己配置; 16 | - type可省略,目前支持5个值:info,warning,success,error,system,分别对应5种颜色,用于label字段的高亮; 17 | - label字段可省略,可随意赋值,但是不建议太长,影响美观; 18 | - message为必须字段就是纯文本内容; 19 | 20 | ### 核心配置文件 21 | 命令行的主要配置文件是 plugins/commadnList.js 和 plugins/taskList.js 这两个文件,这两个文件的基本结构是一致的,都 export一个对象,对象key是任务或者命令名称,值是由 description 和 messages(task) 组成的对象,基本的结构如下所示: 22 | 23 | { 24 | commandOrTask:{ 25 | description:'', 26 | messagesOrTask:[]//(function) 27 | } 28 | } 29 | 30 | VueTerminalEmulator 组件会import这两个文件,根据其中的配置生成帮助项并执行相应的指令,其中description即为'help'指令中各个命令的帮助信息。 31 | 32 | ``` 33 | // VueTerminalEmulator 中引入配置文件 34 | import commandList from './../plugins/commandList' 35 | import taskList from './../plugins/taskList' 36 | ``` 37 | 38 | 其中,commandList 中存放静态的指令,指令执行之后,直接列出所有 message,然后指令结束,无需等待。而taskList 中是异步的任务,指令执行后组件会进入loading状态,任务完成后,通过resolve一个消息来通知VueTerminalEmulator 组件任务结束,解除loading状态(关键词:异步、promise、resolve)。以下是这两种命令的例子: 39 | 异步任务: 40 | 41 | ![](https://user-gold-cdn.xitu.io/2017/11/10/2c49e1275ba4ad1b58528d6968680eee) 42 | 43 | help是典型的静态指令: 44 | 45 | ![](https://user-gold-cdn.xitu.io/2017/11/10/631ebcdca9860e265e21baf7d83c3065) 46 | 47 | #### 静态指令 48 | commandList 中的核心是messages数组,数组内是多个message对象,执行command时,会将command中的message显示在Terminal窗口中,比较简单,不多说,一个示例就解决了: 49 | 50 | contact: { 51 | description: 'How to contact author', 52 | messages: [ 53 | { message: 'Website: http://xiaofeixu.cn' }, 54 | { message: 'Email: xuxiaofei915@gmail.com' }, 55 | { message: 'Github: https://github.com/dongsuo' }, 56 | { message: 'WeChat Offical Account: dongsuo' } 57 | ] } 58 | 就是这么简单,不需要更多的语言。 59 | #### 异步任务 60 | taskList 的核心是名称与任务名一致的函数,该函数接受两个参数:一个函数(pushToList)和命令行(input)的输入值。你可以根据input值来执行具体的任务,然后将message作为参数调用pushToList().当任务结束时,需要返回一个promise,promise要resolve一个message对象通知组件任务结束,如有需要,也可以reject一个message对象通知组件任务出错,示例代码: 61 | 62 | echo: { 63 | description: 'Echoes input, Usage: echo ', 64 | //echo将用户的输入原封不动地返回,显示在terminal窗口中 65 | echo(pushToList, input) { 66 | //解析用户输入 67 | input = input.split(' ') 68 | input.splice(0, 1) 69 | const p = new Promise(resolve => { 70 | // 将message对象作为参数调用pushToList() 71 | pushToList({ time: generateTime(), label: 'Echo', type: 'success', message: input.join(' ') }); 72 | // 通过resolve一个message对象通知组件任务结束 73 | resolve({ type: 'success', label: '', message: '' }) 74 | }) 75 | // 返回 promise 对象 76 | return p 77 | } 78 | } 79 | 80 | ### 部署 81 | 当你已经确认简历做好、没有bug之后,就可以部署了,首先执行`npm run build`命令,然后把你的代码push到Github上,点击settings, 找到Github Pages,将source设置为docs folder,点击save就部署成功了。 82 | -------------------------------------------------------------------------------- /docs/plugins/commandList.js: -------------------------------------------------------------------------------- 1 | const commandList = { 2 | version: { 3 | description: 'Return this project version', 4 | messages: [ 5 | { message: '1.0.0' } 6 | ] 7 | }, 8 | contact: { 9 | description: 'How to contact author', 10 | messages: [ 11 | { message: 'Website: https://islasher.com' }, 12 | { message: 'Email: xuxiaofei915@gmail.com' }, 13 | { message: 'Github: https://github.com/dongsuo' }, 14 | { message: 'WeChat Offical Account: dongsuo' } 15 | ] }, 16 | about: { 17 | description: 'About author', 18 | messages: [ 19 | { message: 'My name is xu xiaofei. I\'m a programmer, You can visit my personal website at https://islasher.com to learn more about me.' } 20 | ] 21 | }, 22 | readme: { 23 | description: 'About this project.', 24 | messages: [ 25 | { message: 'This is a component that emulates a command terminal in browser.' } 26 | ] }, 27 | document: { 28 | description: 'Document of this project.', 29 | messages: [ 30 | { 31 | message: { 32 | text: 'Under Construction', 33 | list: [ 34 | { label: 'hello', type: 'error', message: 'this is a test message' } 35 | ] 36 | } 37 | }] 38 | }, 39 | 'git help': { 40 | description: 'git help', 41 | messages: [ 42 | { 43 | message: `usage: git [--version] [--help] [-C ] [-c =] 44 | [--exec-path[=]] [--html-path] [--man-path] [--info-path] 45 | [-p | --paginate | -P | --no-pager] [--no-replace-objects] [--bare] 46 | [--git-dir=] [--work-tree=] [--namespace=] 47 | [] 48 | 49 | These are common Git commands used in various situations: 50 | 51 | start a working area (see also: git help tutorial) 52 | clone Clone a repository into a new directory 53 | init Create an empty Git repository or reinitialize an existing one 54 | 55 | work on the current change (see also: git help everyday) 56 | add Add file contents to the index 57 | mv Move or rename a file, a directory, or a symlink 58 | reset Reset current HEAD to the specified state 59 | rm Remove files from the working tree and from the index 60 | 61 | examine the history and state (see also: git help revisions) 62 | bisect Use binary search to find the commit that introduced a bug 63 | grep Print lines matching a pattern 64 | log Show commit logs 65 | show Show various types of objects 66 | status Show the working tree status 67 | 68 | grow, mark and tweak your common history 69 | branch List, create, or delete branches 70 | checkout Switch branches or restore working tree files 71 | commit Record changes to the repository 72 | diff Show changes between commits, commit and working tree, etc 73 | merge Join two or more development histories together 74 | rebase Reapply commits on top of another base tip 75 | tag Create, list, delete or verify a tag object signed with GPG 76 | 77 | collaborate (see also: git help workflows) 78 | fetch Download objects and refs from another repository 79 | pull Fetch from and integrate with another repository or a local branch 80 | push Update remote refs along with associated objects 81 | 82 | 'git help -a' and 'git help -g' list available subcommands and some 83 | concept guides. See 'git help ' or 'git help ' 84 | to read about a specific subcommand or concept. 85 | ` 86 | } 87 | ] 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Powered by DartNode](https://dartnode.com/branding/DN-Open-Source-sm.png)](https://dartnode.com "Powered by DartNode - Free VPS for Open Source") 2 | # VUE-TERMINAL 3 | Vue-terminal is a dependency-free, lightweight terminal emulator in Vue.js. Vue-terminal provide flexible api for developer to define task or command that can be executed by users. 4 | ## [Try the demo](https://islasher.com/vue-terminal) 5 | 6 | ### How to use? 7 | ```bash 8 | npm install vue-terminal 9 | 10 | # you can also load vue-terminal.min.js in script tag: 11 | # 12 | ``` 13 | 14 | ### Example 15 | 16 | ```javascript 17 | 20 | 21 | 38 | 39 | ``` 40 | ### About commandList and taskList 41 | 42 | The content of taskList or commandList is defined as json object, the key of the json is command name or task name, here is the structure of command or task: 43 | 44 | ```javascript 45 | { 46 | commandOrTaskName:{ 47 | description: '', 48 | messagesOrTask: [] //(function) 49 | } 50 | } 51 | ``` 52 | 53 | `commandOrTaskName` is the command name you defined. 54 | 55 | `description` is something to describe your task, which will be used by the `help` command. 56 | 57 | `messagesOrTask` is the main part defined to response the command, in `commandList`, the key is `messages`, and in `taskList` the key should be same with task name, here is the detail: 58 | - messages _(array)_ 59 | 60 | messages is an array of `Message`, you can only show message string in terminal instance as a response to a command. 61 | 62 | - task _(function)_ 63 | 64 | you can do more with task, task is a function which use taskName as function name, the first argument is `pushToList`, which is a function allow you to send message to the terminal instance, you can call `pushToList(Message)` to render message in the terminal, the second argument is the string user input, your can parse it and do something interesting. You must return a resolved Promise to tell terminal instance that the task has ended, so that the terminal instance can get ready for more command. 65 | 66 | - Message 67 | 68 | Message is an object, used to define message showed in terminal: 69 | ```javascript 70 | { 71 | time: '', // time to show time before message body 72 | label: '', // label to show a label before message body 73 | type: '', // type to set message's type, will set a class to message's label part, there is 5 builtin types: error, success, info, warning, system 74 | message: '' // message is a string, the main text showed in terminal. 75 | } 76 | ``` 77 | here is an example: 78 | ```javascript 79 | { time: generateTime(), type: 'system', label: 'System', message: 'Welcome to vTerminal, this is an example to show you what this project can do.' }, 80 | ``` 81 | 82 | You can check `/docs/plugins/commandList.js` and `/docs/plugins/taskList.js` to view the detail of task and command config. 83 | 84 | ### Configuration options 85 | 86 | The following options can be passed as props to the `VueTerminal` component to customize its behavior: 87 | 88 | - **title** _(string)_: Sets the title that appears at the top of the terminal window and in front of the prompt. Defaults to `vTerminal`. 89 | 90 | - **showHeader** _(boolean)_: Indicates whether or not to render the window on top of the terminal. Defaults to `true`. 91 | 92 | - **greeting** _(string)_: Sets the greeting that will be shown to the user in the first line of the terminal. Pass `false` to not render a greeting. No defaults value. 93 | 94 | - **defaultTask** _(string)_: The default task runned when initializing the terminal, the task must be defined in `taskList` or `commandList`. 95 | 96 | - **defaultTaskCommandd** _(string)_: the initial command showed when initializing the terminal, default to `init vTerminal`. 97 | 98 | - **prompt** _(string)_: The text to show before the prompt. Defaults to `\{{title}}`. 99 | 100 | - **showHelpMessage** _(boolean)_: Indicates whether a help message should be shown. Defaults to `true`. 101 | 102 | - **unknownCommandMessage** _(object)_: Allows the message that is printed when an unknown command is run to be customized. This object should have a `message` property and can optionally include some additional properties that change how this message is displayed: 103 | ```javascript 104 | { time: '10:53', type: 'error', label: 'Error', message: 'That command is not recognized!' }, 105 | ``` 106 | 107 | If not provided, the default message will be displayed: 108 | 109 | ``` 110 | Unknown Command. 111 | 112 | type "help" to get a supporting command list. 113 | ``` 114 | - **autoFocus** _(boolean)_: Auto focus cursor when initializing the terminal. Defaults to `true`. 115 | 116 | If you want more feature or have problem while using this package, feel free to pull a request or open an issue. 117 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | parser: 'babel-eslint', 4 | parserOptions: { 5 | sourceType: 'module' 6 | }, 7 | env: { 8 | browser: true, 9 | node: true 10 | }, 11 | extends: 'eslint:recommended', 12 | // required to lint *.vue files 13 | plugins: [ 14 | 'html' 15 | ], 16 | // check if imports actually resolve 17 | 'settings': { 18 | 'import/resolver': { 19 | 'webpack': { 20 | 'config': 'build/webpack.base.conf.js' 21 | } 22 | } 23 | }, 24 | // add your custom rules here 25 | 'rules': { 26 | // don't require .vue extension when importing 27 | // 'import/extensions': ['error', 'always', { 28 | // 'js': 'never', 29 | // 'vue': 'never' 30 | // }], 31 | // allow debugger during development 32 | 'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0, 33 | /* 34 | * Possible Errors 35 | */ 36 | 37 | // disallow unnecessary parentheses 38 | 'no-extra-parens': ['error', 'all', {'nestedBinaryExpressions': false}], 39 | 40 | // disallow negating the left operand of relational operators 41 | 'no-unsafe-negation': 'error', 42 | 43 | // enforce valid JSDoc comments 44 | 'valid-jsdoc': 'off', 45 | 46 | /* 47 | * Best Practices 48 | */ 49 | 50 | // enforce return statements in callbacks of array methods 51 | 'array-callback-return': 'error', 52 | 53 | // enforce consistent brace style for all control statements 54 | curly: ['error', 'multi-line'], 55 | 56 | // enforce consistent newlines before and after dots 57 | 'dot-location': ['error', 'property'], 58 | 59 | // enforce dot notation whenever possible 60 | 'dot-notation': 'error', 61 | 62 | // require the use of === and !== 63 | 'eqeqeq': ['error', 'smart'], 64 | 65 | // disallow the use of arguments.caller or arguments.callee 66 | 'no-caller': 'error', 67 | 68 | // disallow empty functions 69 | 'no-empty-function': 'error', 70 | 71 | // disallow unnecessary calls to .bind() 72 | 'no-extra-bind': 'error', 73 | 74 | // disallow unnecessary labels 75 | 'no-extra-label': 'error', 76 | 77 | // disallow leading or trailing decimal points in numeric literals 78 | 'no-floating-decimal': 'error', 79 | 80 | // disallow assignments to native objects or read-only global variables 81 | 'no-global-assign': 'error', 82 | 83 | // disallow the use of eval()-like methods 84 | 'no-implied-eval': 'error', 85 | 86 | // disallow the use of the __iterator__ property 87 | 'no-iterator': 'error', 88 | 89 | // disallow unnecessary nested blocks 90 | 'no-lone-blocks': 'error', 91 | 92 | // disallow multiple spaces 93 | 'no-multi-spaces': 'error', 94 | 95 | // disallow new operators with the String, Number, and Boolean objects 96 | 'no-new-wrappers': 'error', 97 | 98 | // disallow octal escape sequences in string literals 99 | 'no-octal-escape': 'error', 100 | 101 | // disallow the use of the __proto__ property 102 | 'no-proto': 'error', 103 | 104 | // disallow comparisons where both sides are exactly the same 105 | 'no-self-compare': 'error', 106 | 107 | // disallow throwing literals as exceptions 108 | 'no-throw-literal': 'error', 109 | 110 | // disallow unused expressions 111 | 'no-unused-expressions': 'error', 112 | 113 | // disallow unnecessary calls to .call() and .apply() 114 | 'no-useless-call': 'error', 115 | 116 | // disallow unnecessary concatenation of literals or template literals 117 | 'no-useless-concat': 'error', 118 | 119 | // disallow unnecessary escape characters 120 | 'no-useless-escape': 'error', 121 | 122 | // disallow void operators 123 | 'no-void': 'error', 124 | 125 | // require parentheses around immediate function invocations 126 | 'wrap-iife': 'error', 127 | 128 | // require or disallow “Yoda” conditions 129 | yoda: 'error', 130 | 131 | /* 132 | * Variables 133 | */ 134 | 135 | // disallow labels that share a name with a variable 136 | 'no-label-var': 'error', 137 | 138 | // disallow initializing variables to undefined 139 | 'no-undef-init': 'error', 140 | 'no-undef': 'off', 141 | // disallow the use of variables before they are defined 142 | 'no-use-before-define': 'error', 143 | 144 | /* 145 | * Node.js and CommonJS 146 | */ 147 | 148 | // disallow new operators with calls to require 149 | 'no-new-require': 'error', 150 | 151 | /* 152 | * Stylistic Issues 153 | */ 154 | 155 | // enforce consistent spacing inside array brackets 156 | 'array-bracket-spacing': 'error', 157 | 158 | // enforce consistent spacing inside single-line blocks 159 | 'block-spacing': 'error', 160 | 161 | // enforce consistent brace style for blocks 162 | 'brace-style': ['error', '1tbs', {'allowSingleLine': true}], 163 | 164 | // require or disallow trailing commas 165 | 'comma-dangle': 'error', 166 | 167 | // enforce consistent spacing before and after commas 168 | 'comma-spacing': 'error', 169 | 170 | // enforce consistent comma style 171 | 'comma-style': 'error', 172 | 173 | // enforce consistent spacing inside computed property brackets 174 | 'computed-property-spacing': 'error', 175 | 176 | // require or disallow spacing between function identifiers and their invocations 177 | 'func-call-spacing': 'error', 178 | 179 | // enforce consistent indentation 180 | indent: ['error', 2, {SwitchCase: 1}], 181 | 182 | // enforce the consistent use of either double or single quotes in JSX attributes 183 | 'jsx-quotes': 'error', 184 | 185 | // enforce consistent spacing between keys and values in object literal properties 186 | 'key-spacing': 'error', 187 | 188 | // enforce consistent spacing before and after keywords 189 | 'keyword-spacing': 'error', 190 | 191 | // enforce consistent linebreak style 192 | 'linebreak-style': 'off', 193 | 194 | // require or disallow newlines around directives 195 | 'lines-around-directive': 'error', 196 | 197 | // require constructor names to begin with a capital letter 198 | 'new-cap': 'off', 199 | 200 | // require parentheses when invoking a constructor with no arguments 201 | 'new-parens': 'error', 202 | 203 | // disallow Array constructors 204 | 'no-array-constructor': 'error', 205 | 206 | // disallow Object constructors 207 | 'no-new-object': 'error', 208 | 209 | // disallow trailing whitespace at the end of lines 210 | 'no-trailing-spaces': 'error', 211 | 212 | // disallow ternary operators when simpler alternatives exist 213 | 'no-unneeded-ternary': 'error', 214 | 215 | // disallow whitespace before properties 216 | 'no-whitespace-before-property': 'error', 217 | 218 | // enforce consistent spacing inside braces 219 | 'object-curly-spacing': ['error', 'always'], 220 | 221 | // require or disallow padding within blocks 222 | 'padded-blocks': ['error', 'never'], 223 | 224 | // require quotes around object literal property names 225 | 'quote-props': ['error', 'as-needed'], 226 | 227 | // enforce the consistent use of either backticks, double, or single quotes 228 | quotes: ['error', 'single'], 229 | 230 | // enforce consistent spacing before and after semicolons 231 | 'semi-spacing': 'error', 232 | 233 | // require or disallow semicolons instead of ASI 234 | // semi: ['error', 'never'], 235 | 236 | // enforce consistent spacing before blocks 237 | 'space-before-blocks': 'error', 238 | 239 | 'no-console': 'off', 240 | 241 | // enforce consistent spacing before function definition opening parenthesis 242 | 'space-before-function-paren': ['error', 'never'], 243 | 244 | // enforce consistent spacing inside parentheses 245 | 'space-in-parens': 'error', 246 | 247 | // require spacing around infix operators 248 | 'space-infix-ops': 'error', 249 | 250 | // enforce consistent spacing before or after unary operators 251 | 'space-unary-ops': 'error', 252 | 253 | // enforce consistent spacing after the // or /* in a comment 254 | 'spaced-comment': 'error', 255 | 256 | // require or disallow Unicode byte order mark (BOM) 257 | 'unicode-bom': 'error', 258 | 259 | 260 | /* 261 | * ECMAScript 6 262 | */ 263 | 264 | // require braces around arrow function bodies 265 | 'arrow-body-style': 'error', 266 | 267 | // require parentheses around arrow function arguments 268 | 'arrow-parens': ['error', 'as-needed'], 269 | 270 | // enforce consistent spacing before and after the arrow in arrow functions 271 | 'arrow-spacing': 'error', 272 | 273 | // enforce consistent spacing around * operators in generator functions 274 | 'generator-star-spacing': ['error', 'after'], 275 | 276 | // disallow duplicate module imports 277 | 'no-duplicate-imports': 'error', 278 | 279 | // disallow unnecessary computed property keys in object literals 280 | 'no-useless-computed-key': 'error', 281 | 282 | // disallow unnecessary constructors 283 | 'no-useless-constructor': 'error', 284 | 285 | // disallow renaming import, export, and destructured assignments to the same name 286 | 'no-useless-rename': 'error', 287 | 288 | // require let or const instead of var 289 | 'no-var': 'error', 290 | 291 | // require or disallow method and property shorthand syntax for object literals 292 | 'object-shorthand': 'error', 293 | 294 | // require arrow functions as callbacks 295 | 'prefer-arrow-callback': 'error', 296 | 297 | // require const declarations for variables that are never reassigned after declared 298 | 'prefer-const': 'error', 299 | 300 | // disallow parseInt() in favor of binary, octal, and hexadecimal literals 301 | 'prefer-numeric-literals': 'error', 302 | 303 | // require rest parameters instead of arguments 304 | 'prefer-rest-params': 'error', 305 | 306 | // require spread operators instead of .apply() 307 | 'prefer-spread': 'error', 308 | 309 | // enforce spacing between rest and spread operators and their expressions 310 | 'rest-spread-spacing': 'error', 311 | 312 | // require or disallow spacing around embedded expressions of template strings 313 | 'template-curly-spacing': 'error', 314 | 315 | // require or disallow spacing around the * in yield* expressions 316 | 'yield-star-spacing': 'error' 317 | } 318 | } 319 | -------------------------------------------------------------------------------- /src/VueTerminal.vue: -------------------------------------------------------------------------------- 1 | 56 | 241 | 242 | 440 | -------------------------------------------------------------------------------- /dist/vue-terminal.min.js: -------------------------------------------------------------------------------- 1 | !function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define("VueTerminal",[],e):"object"==typeof exports?exports.VueTerminal=e():t.VueTerminal=e()}("undefined"!=typeof self?self:this,function(){return function(t){function e(r){if(n[r])return n[r].exports;var o=n[r]={i:r,l:!1,exports:{}};return t[r].call(o.exports,o,o.exports,e),o.l=!0,o.exports}var n={};return e.m=t,e.c=n,e.d=function(t,n,r){e.o(t,n)||Object.defineProperty(t,n,{configurable:!1,enumerable:!0,get:r})},e.n=function(t){var n=t&&t.__esModule?function(){return t.default}:function(){return t};return e.d(n,"a",n),n},e.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},e.p="/dist/",e(e.s=39)}([function(t,e){var n=t.exports="undefined"!=typeof window&&window.Math==Math?window:"undefined"!=typeof self&&self.Math==Math?self:Function("return this")();"number"==typeof __g&&(__g=n)},function(t,e,n){var r=n(29)("wks"),o=n(30),i=n(0).Symbol,a="function"==typeof i;(t.exports=function(t){return r[t]||(r[t]=a&&i[t]||(a?i:o)("Symbol."+t))}).store=r},function(t,e){var n=t.exports={version:"2.6.11"};"number"==typeof __e&&(__e=n)},function(t,e,n){var r=n(6);t.exports=function(t){if(!r(t))throw TypeError(t+" is not an object!");return t}},function(t,e,n){var r=n(11),o=n(26);t.exports=n(7)?function(t,e,n){return r.f(t,e,o(1,n))}:function(t,e,n){return t[e]=n,t}},function(t,e,n){var r=n(0),o=n(2),i=n(9),a=n(4),s=n(12),u=function(t,e,n){var c,f,l,p=t&u.F,d=t&u.G,h=t&u.S,v=t&u.P,m=t&u.B,y=t&u.W,g=d?o:o[e]||(o[e]={}),x=g.prototype,w=d?r:h?r[e]:(r[e]||{}).prototype;d&&(n=e);for(c in n)(f=!p&&w&&void 0!==w[c])&&s(g,c)||(l=f?w[c]:n[c],g[c]=d&&"function"!=typeof w[c]?n[c]:m&&f?i(l,r):y&&w[c]==l?function(t){var e=function(e,n,r){if(this instanceof t){switch(arguments.length){case 0:return new t;case 1:return new t(e);case 2:return new t(e,n)}return new t(e,n,r)}return t.apply(this,arguments)};return e.prototype=t.prototype,e}(l):v&&"function"==typeof l?i(Function.call,l):l,v&&((g.virtual||(g.virtual={}))[c]=l,t&u.R&&x&&!x[c]&&a(x,c,l)))};u.F=1,u.G=2,u.S=4,u.P=8,u.B=16,u.W=32,u.U=64,u.R=128,t.exports=u},function(t,e){t.exports=function(t){return"object"==typeof t?null!==t:"function"==typeof t}},function(t,e,n){t.exports=!n(17)(function(){return 7!=Object.defineProperty({},"a",{get:function(){return 7}}).a})},function(t,e){t.exports={}},function(t,e,n){var r=n(10);t.exports=function(t,e,n){if(r(t),void 0===e)return t;switch(n){case 1:return function(n){return t.call(e,n)};case 2:return function(n,r){return t.call(e,n,r)};case 3:return function(n,r,o){return t.call(e,n,r,o)}}return function(){return t.apply(e,arguments)}}},function(t,e){t.exports=function(t){if("function"!=typeof t)throw TypeError(t+" is not a function!");return t}},function(t,e,n){var r=n(3),o=n(51),i=n(52),a=Object.defineProperty;e.f=n(7)?Object.defineProperty:function(t,e,n){if(r(t),e=i(e,!0),r(n),o)try{return a(t,e,n)}catch(t){}if("get"in n||"set"in n)throw TypeError("Accessors not supported!");return"value"in n&&(t[e]=n.value),t}},function(t,e){var n={}.hasOwnProperty;t.exports=function(t,e){return n.call(t,e)}},function(t,e){var n={}.toString;t.exports=function(t){return n.call(t).slice(8,-1)}},function(t,e){var n=Math.ceil,r=Math.floor;t.exports=function(t){return isNaN(t=+t)?0:(t>0?r:n)(t)}},function(t,e){t.exports=function(t){if(void 0==t)throw TypeError("Can't call method on "+t);return t}},function(t,e){t.exports=!0},function(t,e){t.exports=function(t){try{return!!t()}catch(t){return!0}}},function(t,e,n){var r=n(6),o=n(0).document,i=r(o)&&r(o.createElement);t.exports=function(t){return i?o.createElement(t):{}}},function(t,e,n){var r=n(58),o=n(15);t.exports=function(t){return r(o(t))}},function(t,e,n){var r=n(29)("keys"),o=n(30);t.exports=function(t){return r[t]||(r[t]=o(t))}},function(t,e,n){var r=n(11).f,o=n(12),i=n(1)("toStringTag");t.exports=function(t,e,n){t&&!o(t=n?t:t.prototype,i)&&r(t,i,{configurable:!0,value:e})}},function(t,e,n){"use strict";function r(t){var e,n;this.promise=new t(function(t,r){if(void 0!==e||void 0!==n)throw TypeError("Bad Promise constructor");e=t,n=r}),this.resolve=o(e),this.reject=o(n)}var o=n(10);t.exports.f=function(t){return new r(t)}},function(t,e,n){"use strict";var r=n(24),o=n.n(r),i=n(80),a=n.n(i),s=n(83),u=n.n(s),c=n(84),f=n.n(c);e.a={name:"VueTerminal",data:function(){return{messageList:[],actionResult:"",lastLineContent:"...",inputCommand:"",supportingCommandList:"",historyIndex:0,commandHistory:[]}},props:{commandList:{required:!1,default:function(){return{}}},taskList:{required:!1,default:function(){return{}}},title:{required:!1,type:String,default:"vTerminal"},showHeader:{required:!1,type:Boolean,default:!0},greeting:{required:!1,type:String,default:void 0},defaultTaskCommandd:{required:!1,type:String,default:"init vTerminal"},defaultTask:{required:!1,type:String,default:void 0},prompt:{required:!1,default:void 0},showHelpMessage:{required:!1,default:!0},unknownCommandMessage:{required:!1,default:void 0}},computed:{lastLineClass:function(){return" "===this.lastLineContent?"cursor":"..."===this.lastLineContent?"loading":void 0}},created:function(){this.supportingCommandList=f()(this.commandList).concat(f()(this.taskList))},mounted:function(){var t=this;return u()(a.a.mark(function e(){return a.a.wrap(function(e){for(;;)switch(e.prev=e.next){case 0:if(!t.defaultTask){e.next=3;break}return e.next=3,t.handleRun(t.defaultTask);case 3:t.showHelpMessage&&t.pushToList({level:"System",message:'Type "help" to get a supporting command list.'}),t.lastLineContent=" ",t.handleFocus();case 6:case"end":return e.stop()}},e,t)}))()},methods:{handleFocus:function(){this.$refs.inputBox.focus()},handleCommand:function(t){var e=this;if(13!==t.keyCode)return void this.handlekeyEvent(t);if(this.commandHistory.push(this.inputCommand),this.historyIndex=this.commandHistory.length,void 0!==this.prompt?this.pushToList({message:this.prompt+" "+this.inputCommand+" "}):this.pushToList({message:"$ \\"+this.title+" "+this.inputCommand+" "}),this.inputCommand){var n=this.inputCommand.split(" ");"help"===n[0]?this.printHelp(n[1]):this.commandList[this.inputCommand]?this.commandList[this.inputCommand].messages.map(function(t){return e.pushToList(t)}):this.taskList[this.inputCommand.split(" ")[0]]?this.handleRun(this.inputCommand.split(" ")[0],this.inputCommand):this.unknownCommandMessage?this.pushToList(this.unknownCommandMessage):(this.pushToList({level:"System",message:"Unknown Command."}),this.pushToList({level:"System",message:'type "help" to get a supporting command list.'})),this.inputCommand="",this.autoScroll()}},handlekeyEvent:function(t){switch(t.keyCode){case 38:this.historyIndex=0===this.historyIndex?0:this.historyIndex-1,this.inputCommand=this.commandHistory[this.historyIndex];break;case 40:this.historyIndex=this.historyIndex===this.commandHistory.length?this.commandHistory.length:this.historyIndex+1,this.inputCommand=this.commandHistory[this.historyIndex]}},handleRun:function(t,e){var n=this;return this.taskList[t]&&this.taskList[t][t]?(this.lastLineContent="...",this.taskList[t][t](this.pushToList,e).then(function(t){n.pushToList(t),n.lastLineContent=" "}).catch(function(t){n.pushToList(t||{type:"error",label:"Error",message:"Something went wrong!"}),n.lastLineContent=" "})):o.a.resolve()},pushToList:function(t){this.messageList.push(t),this.autoScroll()},printHelp:function(t){var e=this;if(t){var n=this.commandList[t]||this.taskList[t];this.pushToList({message:n.description})}else this.pushToList({message:"Here is a list of supporting command."}),this.supportingCommandList.map(function(t){e.commandList[t]?e.pushToList({type:"success",label:t,message:"---\x3e "+e.commandList[t].description}):e.pushToList({type:"success",label:t,message:"---\x3e "+e.taskList[t].description})}),this.pushToList({message:"Enter help to get help for a particular command."});this.autoScroll()},time:function(){return(new Date).toLocaleTimeString().split("").splice(2).join("")},autoScroll:function(){var t=this;this.$nextTick(function(){t.$refs.terminalWindow.scrollTop=t.$refs.terminalLastLine.offsetTop})}}}},function(t,e,n){t.exports={default:n(47),__esModule:!0}},function(t,e,n){"use strict";var r=n(16),o=n(5),i=n(53),a=n(4),s=n(8),u=n(54),c=n(21),f=n(61),l=n(1)("iterator"),p=!([].keys&&"next"in[].keys()),d=function(){return this};t.exports=function(t,e,n,h,v,m,y){u(n,e,h);var g,x,w,_=function(t){if(!p&&t in k)return k[t];switch(t){case"keys":case"values":return function(){return new n(this,t)}}return function(){return new n(this,t)}},b=e+" Iterator",L="values"==v,C=!1,k=t.prototype,T=k[l]||k["@@iterator"]||v&&k[v],S=T||_(v),j=v?L?_("entries"):S:void 0,O="Array"==e?k.entries||T:T;if(O&&(w=f(O.call(new t)))!==Object.prototype&&w.next&&(c(w,b,!0),r||"function"==typeof w[l]||a(w,l,d)),L&&T&&"values"!==T.name&&(C=!0,S=function(){return T.call(this)}),r&&!y||!p&&!C&&k[l]||a(k,l,S),s[e]=S,s[b]=d,v)if(g={values:L?S:_("values"),keys:m?S:_("keys"),entries:j},y)for(x in g)x in k||i(k,x,g[x]);else o(o.P+o.F*(p||C),e,g);return g}},function(t,e){t.exports=function(t,e){return{enumerable:!(1&t),configurable:!(2&t),writable:!(4&t),value:e}}},function(t,e,n){var r=n(57),o=n(31);t.exports=Object.keys||function(t){return r(t,o)}},function(t,e,n){var r=n(14),o=Math.min;t.exports=function(t){return t>0?o(r(t),9007199254740991):0}},function(t,e,n){var r=n(2),o=n(0),i=o["__core-js_shared__"]||(o["__core-js_shared__"]={});(t.exports=function(t,e){return i[t]||(i[t]=void 0!==e?e:{})})("versions",[]).push({version:r.version,mode:n(16)?"pure":"global",copyright:"© 2019 Denis Pushkarev (zloirock.ru)"})},function(t,e){var n=0,r=Math.random();t.exports=function(t){return"Symbol(".concat(void 0===t?"":t,")_",(++n+r).toString(36))}},function(t,e){t.exports="constructor,hasOwnProperty,isPrototypeOf,propertyIsEnumerable,toLocaleString,toString,valueOf".split(",")},function(t,e,n){var r=n(0).document;t.exports=r&&r.documentElement},function(t,e,n){var r=n(15);t.exports=function(t){return Object(r(t))}},function(t,e,n){var r=n(13),o=n(1)("toStringTag"),i="Arguments"==r(function(){return arguments}()),a=function(t,e){try{return t[e]}catch(t){}};t.exports=function(t){var e,n,s;return void 0===t?"Undefined":null===t?"Null":"string"==typeof(n=a(e=Object(t),o))?n:i?r(e):"Object"==(s=r(e))&&"function"==typeof e.callee?"Arguments":s}},function(t,e,n){var r=n(3),o=n(10),i=n(1)("species");t.exports=function(t,e){var n,a=r(t).constructor;return void 0===a||void 0==(n=r(a)[i])?e:o(n)}},function(t,e,n){var r,o,i,a=n(9),s=n(72),u=n(32),c=n(18),f=n(0),l=f.process,p=f.setImmediate,d=f.clearImmediate,h=f.MessageChannel,v=f.Dispatch,m=0,y={},g=function(){var t=+this;if(y.hasOwnProperty(t)){var e=y[t];delete y[t],e()}},x=function(t){g.call(t.data)};p&&d||(p=function(t){for(var e=[],n=1;arguments.length>n;)e.push(arguments[n++]);return y[++m]=function(){s("function"==typeof t?t:Function(t),e)},r(m),m},d=function(t){delete y[t]},"process"==n(13)(l)?r=function(t){l.nextTick(a(g,t,1))}:v&&v.now?r=function(t){v.now(a(g,t,1))}:h?(o=new h,i=o.port2,o.port1.onmessage=x,r=a(i.postMessage,i,1)):f.addEventListener&&"function"==typeof postMessage&&!f.importScripts?(r=function(t){f.postMessage(t+"","*")},f.addEventListener("message",x,!1)):r="onreadystatechange"in c("script")?function(t){u.appendChild(c("script")).onreadystatechange=function(){u.removeChild(this),g.call(t)}}:function(t){setTimeout(a(g,t,1),0)}),t.exports={set:p,clear:d}},function(t,e){t.exports=function(t){try{return{e:!1,v:t()}}catch(t){return{e:!0,v:t}}}},function(t,e,n){var r=n(3),o=n(6),i=n(22);t.exports=function(t,e){if(r(t),o(e)&&e.constructor===t)return e;var n=i.f(t);return(0,n.resolve)(e),n.promise}},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=n(40);e.default=r.a,"undefined"!=typeof window&&window.Vue&&window.Vue.component("vue-terminal",r.a)},function(t,e,n){"use strict";function r(t){n(41)}var o=n(23),i=n(88),a=n(46),s=r,u=a(o.a,i.a,!1,s,"data-v-2e609d0e",null);e.a=u.exports},function(t,e,n){var r=n(42);"string"==typeof r&&(r=[[t.i,r,""]]),r.locals&&(t.exports=r.locals);n(44)("0c1b740f",r,!0,{})},function(t,e,n){e=t.exports=n(43)(!1),e.push([t.i,'.vue-terminal[data-v-2e609d0e]{position:relative;width:100%;border-radius:4px;color:#fff;margin-bottom:10px;max-height:580px}.vue-terminal .terminal-window[data-v-2e609d0e]{position:absolute;top:0;left:0;right:0;overflow:auto;z-index:1;margin-top:30px;max-height:500px;padding-top:50px;background-color:#030924;min-height:140px;padding:20px;font-weight:400;font-family:Monaco,Menlo,Consolas,monospace;color:#fff}.vue-terminal .terminal-window pre[data-v-2e609d0e]{font-family:Monaco,Menlo,Consolas,monospace;white-space:pre-wrap}.vue-terminal .terminal-window p[data-v-2e609d0e]{overflow-wrap:break-word;word-break:break-all;font-size:13px}.vue-terminal .terminal-window p .cmd[data-v-2e609d0e]{line-height:24px}.vue-terminal .terminal-window p .info[data-v-2e609d0e]{padding:2px 3px;background:#2980b9}.vue-terminal .terminal-window p .warning[data-v-2e609d0e]{padding:2px 3px;background:#f39c12}.vue-terminal .terminal-window p .success[data-v-2e609d0e]{padding:2px 3px;background:#27ae60}.vue-terminal .terminal-window p .error[data-v-2e609d0e]{padding:2px 3px;background:#c0392b}.vue-terminal .terminal-window p .system[data-v-2e609d0e]{padding:2px 3px;background:#bdc3c7}.vue-terminal .terminal-window pre[data-v-2e609d0e]{display:inline}.terminal-header ul.shell-dots li[data-v-2e609d0e]{display:inline-block;width:12px;height:12px;border-radius:6px;margin-left:6px}.terminal-header ul .shell-dots-red[data-v-2e609d0e]{background-color:#c83030}.terminal-header ul .shell-dots-yellow[data-v-2e609d0e]{background-color:#f7db60}.terminal-header ul .shell-dots-green[data-v-2e609d0e]{background-color:#2ec971}.terminal-header[data-v-2e609d0e]{position:absolute;z-index:2;top:0;right:0;left:0;background-color:#959598;text-align:center;padding:2px;border-top-left-radius:4px;border-top-right-radius:4px}.terminal-header h4[data-v-2e609d0e]{font-size:14px;margin:5px;letter-spacing:1px}.terminal-header ul.shell-dots[data-v-2e609d0e]{position:absolute;top:5px;left:8px;padding-left:0;margin:0}.vue-terminal .terminal-window .prompt[data-v-2e609d0e]:before{content:"$";margin-right:10px}.vue-terminal .terminal-window .cursor[data-v-2e609d0e]{margin:0;background-color:#fff;animation:blink-data-v-2e609d0e 1s step-end infinite;-webkit-animation:blink-data-v-2e609d0e 1s step-end infinite;margin-left:-5px}@keyframes blink-data-v-2e609d0e{50%{visibility:hidden}}@-webkit-keyframes blink-data-v-2e609d0e{50%{visibility:hidden}}.vue-terminal .terminal-window .loading[data-v-2e609d0e]{display:inline-block;width:0;overflow:hidden;overflow-wrap:normal;animation:load-data-v-2e609d0e 1.2s step-end infinite;-webkit-animation:load-data-v-2e609d0e 1.2s step-end infinite}@keyframes load-data-v-2e609d0e{0%{width:0}20%{width:5px}40%{width:10px}60%{width:15px}80%{width:20px}}@-webkit-keyframes load-data-v-2e609d0e{0%{width:0}20%{width:5px}40%{width:10px}60%{width:15px}80%{width:20px}}.terminal-last-line[data-v-2e609d0e]{font-size:0;word-spacing:0;letter-spacing:0}.input-box[data-v-2e609d0e]{position:relative;background:#030924;border:none;width:1px;opacity:0;cursor:default}.input-box[data-v-2e609d0e]:focus{outline:none;border:none}',""])},function(t,e){function n(t,e){var n=t[1]||"",o=t[3];if(!o)return n;if(e&&"function"==typeof btoa){var i=r(o);return[n].concat(o.sources.map(function(t){return"/*# sourceURL="+o.sourceRoot+t+" */"})).concat([i]).join("\n")}return[n].join("\n")}function r(t){return"/*# sourceMappingURL=data:application/json;charset=utf-8;base64,"+btoa(unescape(encodeURIComponent(JSON.stringify(t))))+" */"}t.exports=function(t){var e=[];return e.toString=function(){return this.map(function(e){var r=n(e,t);return e[2]?"@media "+e[2]+"{"+r+"}":r}).join("")},e.i=function(t,n){"string"==typeof t&&(t=[[null,t,""]]);for(var r={},o=0;on.parts.length&&(r.parts.length=n.parts.length)}else{for(var a=[],o=0;o=e.length?{value:void 0,done:!0}:(t=r(e,n),this._i+=t.length,{value:t,done:!1})})},function(t,e,n){var r=n(14),o=n(15);t.exports=function(t){return function(e,n){var i,a,s=String(o(e)),u=r(n),c=s.length;return u<0||u>=c?t?"":void 0:(i=s.charCodeAt(u),i<55296||i>56319||u+1===c||(a=s.charCodeAt(u+1))<56320||a>57343?t?s.charAt(u):i:t?s.slice(u,u+2):a-56320+(i-55296<<10)+65536)}}},function(t,e,n){t.exports=!n(7)&&!n(17)(function(){return 7!=Object.defineProperty(n(18)("div"),"a",{get:function(){return 7}}).a})},function(t,e,n){var r=n(6);t.exports=function(t,e){if(!r(t))return t;var n,o;if(e&&"function"==typeof(n=t.toString)&&!r(o=n.call(t)))return o;if("function"==typeof(n=t.valueOf)&&!r(o=n.call(t)))return o;if(!e&&"function"==typeof(n=t.toString)&&!r(o=n.call(t)))return o;throw TypeError("Can't convert object to primitive value")}},function(t,e,n){t.exports=n(4)},function(t,e,n){"use strict";var r=n(55),o=n(26),i=n(21),a={};n(4)(a,n(1)("iterator"),function(){return this}),t.exports=function(t,e,n){t.prototype=r(a,{next:o(1,n)}),i(t,e+" Iterator")}},function(t,e,n){var r=n(3),o=n(56),i=n(31),a=n(20)("IE_PROTO"),s=function(){},u=function(){var t,e=n(18)("iframe"),r=i.length;for(e.style.display="none",n(32).appendChild(e),e.src="javascript:",t=e.contentWindow.document,t.open(),t.write("