├── .editorconfig
├── .ember-cli
├── .eslintignore
├── .eslintrc.js
├── .gitignore
├── .npmignore
├── .template-lintrc.js
├── .travis.yml
├── .watchmanconfig
├── README.md
├── app
├── app.js
├── components
│ ├── .gitkeep
│ ├── build-runner.hbs
│ ├── build-runner.js
│ ├── deps-list.hbs
│ ├── deps-list.js
│ ├── destroy-runner.hbs
│ ├── destroy-runner.js
│ ├── generate-runner.hbs
│ ├── generate-runner.js
│ ├── install-runner.hbs
│ ├── install-runner.js
│ ├── lint-runner.hbs
│ ├── lint-runner.js
│ ├── loading-spinner.hbs
│ ├── new-project-runner.hbs
│ ├── new-project-runner.js
│ ├── project-info.hbs
│ ├── project-info.js
│ ├── project-task-runner.hbs
│ ├── project-task-runner.js
│ ├── semver-badge.hbs
│ ├── serve-runner.hbs
│ ├── serve-runner.js
│ ├── speed-data.hbs
│ ├── speed-data.js
│ ├── terminal.hbs
│ ├── terminal.js
│ ├── test-runner.hbs
│ ├── test-runner.js
│ ├── update-runner.hbs
│ └── update-runner.js
├── constants
│ └── blueprints.js
├── controllers
│ ├── .gitkeep
│ └── application.js
├── helpers
│ └── .gitkeep
├── index.html
├── models
│ └── .gitkeep
├── modifiers
│ └── create-xterm.js
├── router.js
├── routes
│ ├── .gitkeep
│ ├── application.js
│ ├── build.js
│ ├── dependencies.js
│ ├── destroy.js
│ ├── generate.js
│ ├── index.js
│ ├── install.js
│ ├── lint.js
│ ├── new-project.js
│ ├── project-tasks.js
│ ├── project-update.js
│ ├── serve.js
│ └── test.js
├── services
│ ├── project.js
│ └── terminal.js
├── styles
│ ├── _typography.css
│ ├── _variables.css
│ └── app.css
└── templates
│ ├── application.hbs
│ ├── build.hbs
│ ├── dependencies.hbs
│ ├── destroy.hbs
│ ├── generate.hbs
│ ├── index.hbs
│ ├── install.hbs
│ ├── lint.hbs
│ ├── new-project.hbs
│ ├── project-tasks.hbs
│ ├── project-update.hbs
│ ├── serve.hbs
│ └── test.hbs
├── bin
└── cli.js
├── config
├── environment.js
├── icons.js
├── optional-features.json
└── targets.js
├── dist
├── assets
│ ├── _typography-26492ca975c5072739cd1f79152e22fb.css
│ ├── _variables-fce0c1ab1a5617d5140d494ca66fd3ed.css
│ ├── ember-cli-ui-45b8d2f6b987b65710d49ba200643149.css
│ ├── ember-cli-ui-9437cc43508a53d4a67fdf52bfde9aa2.js
│ ├── fonts
│ │ └── Roboto
│ │ │ └── Roboto-Regular.ttf
│ ├── images
│ │ ├── favicon-f2d07120d2bb7f0d4a63810011903d75.png
│ │ └── logo-26455e836959ac197f36f57a49b5b61f.png
│ ├── vendor-5f4d6ad9eb42254e21ae58c647cfed2a.js
│ └── vendor-e5446f7e2988be0cf64ea9511b7d7a8e.css
├── index.html
└── robots.txt
├── ember-cli-build.js
├── package-lock.json
├── package.json
├── pnpm-lock.yaml
├── public
├── assets
│ ├── fonts
│ │ └── Roboto
│ │ │ └── Roboto-Regular.ttf
│ └── images
│ │ ├── favicon.png
│ │ └── logo.png
└── robots.txt
├── screenshots
├── build.png
├── destroy.png
├── generate.png
├── home.png
├── install.png
├── lint.png
├── logo.png
├── project-tasks.png
├── serve.png
└── test.png
├── server
├── index.js
└── utils
│ ├── buffer.js
│ ├── bufferUtf8.js
│ ├── downloadTime.js
│ ├── getBuildAssets.js
│ └── speeds.json
├── testem.js
├── tests
├── helpers
│ ├── .gitkeep
│ └── flash-message.js
├── index.html
├── integration
│ ├── .gitkeep
│ ├── components
│ │ ├── build-runner-test.js
│ │ ├── deps-list-test.js
│ │ ├── destroy-runner-test.js
│ │ ├── generate-runner-test.js
│ │ ├── install-runner-test.js
│ │ ├── lint-runner-test.js
│ │ ├── loading-spinner-test.js
│ │ ├── new-project-runner-test.js
│ │ ├── project-info-test.js
│ │ ├── project-task-runner-test.js
│ │ ├── semver-badge-test.js
│ │ ├── serve-runner-test.js
│ │ ├── speed-data-test.js
│ │ ├── terminal-test.js
│ │ ├── test-runner-test.js
│ │ └── update-runner-test.js
│ └── modifiers
│ │ └── create-xterm-test.js
├── test-helper.js
└── unit
│ ├── .gitkeep
│ ├── controllers
│ └── application-test.js
│ ├── routes
│ ├── application-test.js
│ ├── build-test.js
│ ├── dependencies-test.js
│ ├── destroy-test.js
│ ├── generate-test.js
│ ├── index-test.js
│ ├── install-test.js
│ ├── lint-test.js
│ ├── new-project-test.js
│ ├── project-tasks-test.js
│ ├── project-update-test.js
│ ├── serve-test.js
│ └── test-test.js
│ └── services
│ ├── project-test.js
│ └── terminal-test.js
├── vendor
└── .gitkeep
└── yarn.lock
/.editorconfig:
--------------------------------------------------------------------------------
1 | # EditorConfig helps developers define and maintain consistent
2 | # coding styles between different editors and IDEs
3 | # editorconfig.org
4 |
5 | root = true
6 |
7 | [*]
8 | end_of_line = lf
9 | charset = utf-8
10 | trim_trailing_whitespace = true
11 | insert_final_newline = true
12 | indent_style = space
13 | indent_size = 2
14 |
15 | [*.hbs]
16 | insert_final_newline = false
17 |
18 | [*.{diff,md}]
19 | trim_trailing_whitespace = false
20 |
--------------------------------------------------------------------------------
/.ember-cli:
--------------------------------------------------------------------------------
1 | {
2 | /**
3 | Ember CLI sends analytics information by default. The data is completely
4 | anonymous, but there are times when you might want to disable this behavior.
5 |
6 | Setting `disableAnalytics` to true will prevent any data from being sent.
7 | */
8 | "disableAnalytics": false
9 | }
10 |
--------------------------------------------------------------------------------
/.eslintignore:
--------------------------------------------------------------------------------
1 | # unconventional js
2 | /blueprints/*/files/
3 | /vendor/
4 |
5 | # compiled output
6 | /dist/
7 | /tmp/
8 |
9 | # dependencies
10 | /bower_components/
11 | /node_modules/
12 |
13 | # misc
14 | /coverage/
15 | !.*
16 |
17 | # ember-try
18 | /.node_modules.ember-try/
19 | /bower.json.ember-try
20 | /package.json.ember-try
21 |
--------------------------------------------------------------------------------
/.eslintrc.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | module.exports = {
4 | root: true,
5 | parser: 'babel-eslint',
6 | parserOptions: {
7 | ecmaVersion: 2018,
8 | sourceType: 'module',
9 | ecmaFeatures: {
10 | legacyDecorators: true
11 | }
12 | },
13 | plugins: [
14 | 'ember'
15 | ],
16 | extends: [
17 | 'eslint:recommended',
18 | 'plugin:ember/recommended'
19 | ],
20 | env: {
21 | browser: true
22 | },
23 | rules: {},
24 | overrides: [
25 | // node files
26 | {
27 | files: [
28 | '.eslintrc.js',
29 | '.template-lintrc.js',
30 | 'ember-cli-build.js',
31 | 'testem.js',
32 | 'blueprints/*/index.js',
33 | 'config/**/*.js',
34 | 'lib/*/index.js',
35 | 'server/**/*.js'
36 | ],
37 | parserOptions: {
38 | sourceType: 'script'
39 | },
40 | env: {
41 | browser: false,
42 | node: true
43 | },
44 | plugins: ['node'],
45 | extends: ['plugin:node/recommended'],
46 | rules: {
47 | // this can be removed once the following is fixed
48 | // https://github.com/mysticatea/eslint-plugin-node/issues/77
49 | 'node/no-unpublished-require': 'off'
50 | }
51 | }
52 | ]
53 | };
54 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/ignore-files/ for more about ignoring files.
2 |
3 | # compiled output
4 | /tmp/
5 |
6 | # dependencies
7 | /bower_components/
8 | /node_modules/
9 |
10 | # misc
11 | /.env*
12 | /.pnp*
13 | /.sass-cache
14 | /connect.lock
15 | /coverage/
16 | /libpeerconnection.log
17 | /npm-debug.log*
18 | /testem.log
19 | /yarn-error.log
20 |
21 | # ember-try
22 | /.node_modules.ember-try/
23 | /bower.json.ember-try
24 | /package.json.ember-try
25 |
26 | /**/.DS_Store
27 |
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | app/
2 | config/
3 | lib/
4 | public/
5 | tests/
6 | vendor/
7 | pnpm-lock.yaml
8 | .editorconfig
9 | .ember-cli
10 | .eslintrc.js
11 | .template-lintrc.js
12 | .travis.yml
13 | .watchmanconfig
14 | ember-cli-buildjs
15 | testem.js
16 | yarn.lock
17 | screenshots/
18 |
--------------------------------------------------------------------------------
/.template-lintrc.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | module.exports = {
4 | extends: 'octane'
5 | };
6 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | ---
2 | language: node_js
3 | node_js:
4 | - "10"
5 |
6 | dist: xenial
7 |
8 | addons:
9 | chrome: stable
10 |
11 | cache:
12 | directories:
13 | - $HOME/.npm
14 |
15 | env:
16 | global:
17 | # See https://git.io/vdao3 for details.
18 | - JOBS=1
19 |
20 | branches:
21 | only:
22 | - master
23 |
24 | script:
25 | - npm test
26 |
--------------------------------------------------------------------------------
/.watchmanconfig:
--------------------------------------------------------------------------------
1 | {
2 | "ignore_dirs": ["tmp", "dist"]
3 | }
4 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # ember-cli-ui
2 | [](https://npmjs.org/package/ember-cli-ui "View this project on npm")
3 |
4 |
5 | 
6 |
7 | [ember-cli](https://cli.emberjs.com/release/) in the browser to create and manage your
8 | Ember projects using GUI
9 |
10 | See the [demo](https://www.youtube.com/watch?v=AH2S1DVb4tg) video.
11 |
12 | ## Installation
13 |
14 | ```
15 | npm install -g ember-cli-ui
16 | ```
17 |
18 | ## Usage
19 |
20 | ```
21 | ember-cli-ui
22 | ```
23 |
24 | The CLI will automatically open a new browser window and serve a pre-built Ember project from an available port.
25 |
26 | ## Screenshots
27 | ### Home page
28 | 
29 |
30 | ### Install page
31 | 
32 |
33 | ### Serve page
34 | 
35 |
36 | ### Lint page
37 | 
38 |
39 | ### Test page
40 | 
41 |
42 | ### Generate page
43 | 
44 |
45 | ### Destroy page
46 | 
47 |
48 | ### Build page
49 | 
50 |
51 | ### Project tasks page
52 | 
53 |
54 | ## Prerequisites
55 |
56 | You will need the following things properly installed on your computer.
57 |
58 | * [Git](https://git-scm.com/)
59 | * [Node.js](https://nodejs.org/) (with npm)
60 | * [Ember CLI](https://ember-cli.com/)
61 | * [Google Chrome](https://google.com/chrome/)
62 |
63 | ## Further Reading / Useful Links
64 |
65 | * [ember.js](https://emberjs.com/)
66 | * [ember-cli](https://ember-cli.com/)
67 | * Development Browser Extensions
68 | * [ember inspector for chrome](https://chrome.google.com/webstore/detail/ember-inspector/bmdblncegkenkacieihfhpjfppoconhi)
69 | * [ember inspector for firefox](https://addons.mozilla.org/en-US/firefox/addon/ember-inspector/)
70 |
--------------------------------------------------------------------------------
/app/app.js:
--------------------------------------------------------------------------------
1 | import Application from '@ember/application';
2 | import Resolver from 'ember-resolver';
3 | import loadInitializers from 'ember-load-initializers';
4 | import config from './config/environment';
5 |
6 | export default class App extends Application {
7 | modulePrefix = config.modulePrefix;
8 | podModulePrefix = config.podModulePrefix;
9 | Resolver = Resolver;
10 | }
11 |
12 | loadInitializers(App, config.modulePrefix);
13 |
--------------------------------------------------------------------------------
/app/components/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rajasegar/ember-cli-ui/77489c814f0b99b4984f304049ff6da55a5b1d63/app/components/.gitkeep
--------------------------------------------------------------------------------
/app/components/build-runner.hbs:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | {{#if showSpinner}}
7 | Building...
8 |
9 | {{/if}}
10 |
11 | {{#if this.buildReady}}
12 |
13 |
14 | Asset Name |
15 | Size |
16 | gzipped |
17 | Download Time |
18 |
19 |
20 | {{#each this.assets as |i|}}
21 |
22 | {{i.name}} |
23 | {{i.size}} |
24 | {{i.gzipSize}} |
25 |
26 | Show
27 |
28 |
29 |
30 |
31 | |
32 |
33 | {{/each}}
34 |
35 |
36 | {{/if}}
37 |
38 | {{#if this.showLog}}
39 |
40 | {{#each this.logs as |log|}}
41 |
{{log}}
42 | {{/each}}
43 |
44 | {{/if}}
45 |
--------------------------------------------------------------------------------
/app/components/build-runner.js:
--------------------------------------------------------------------------------
1 | import Component from '@glimmer/component';
2 | import { action } from '@ember/object';
3 | import { tracked } from '@glimmer/tracking';
4 | import { htmlSafe } from '@ember/template';
5 |
6 | export default class BuildRunnerComponent extends Component {
7 |
8 | @tracked disabled = false;
9 | @tracked showSpinner = false;
10 | @tracked assets = [];
11 | @tracked showLog = false;
12 | @tracked logs = [];
13 | @tracked buildReady = false;
14 |
15 | @action
16 | runBuild() {
17 | this.showSpinner = true;
18 | this.disabled = true;
19 | fetch('/build')
20 | .then(res => res.json())
21 | .then(response => {
22 | //console.log(response);
23 | this.logs = response.logs.map(l => htmlSafe(l));
24 | this.assets = response.assets;
25 |
26 | this.showSpinner = false;
27 | this.disabled = false;
28 | this.buildReady = true;
29 | });
30 |
31 | }
32 |
33 | @action
34 | toggleLog() {
35 | this.showLog = !this.showLog;
36 | }
37 |
38 | get logBtnLabel() {
39 | return this.showLog ? 'Hide Log' : 'Show Log';
40 | }
41 |
42 | }
43 |
--------------------------------------------------------------------------------
/app/components/deps-list.hbs:
--------------------------------------------------------------------------------
1 | {{#async-await this.items as |items|}}
2 |
3 |
4 | Package Name |
5 | Installed Version |
6 | Latest Version |
7 | Upgrade? |
8 |
9 |
10 | {{#each items as |d|}}
11 |
12 | {{d.name}} |
13 | {{d.version}} |
14 | {{d.latest}} |
15 | |
16 |
17 | {{/each}}
18 |
19 |
20 |
21 | {{else}}
22 |
23 | {{/async-await}}
24 |
--------------------------------------------------------------------------------
/app/components/deps-list.js:
--------------------------------------------------------------------------------
1 | import Component from '@glimmer/component';
2 | import { diff, coerce } from 'semver';
3 |
4 | export default class DepsListComponent extends Component {
5 | get items() {
6 | const url = `/dependencies?type=${this.args.type}`;
7 | return fetch(url)
8 | .then(res => res.json())
9 | .then(deps => {
10 | const { dependencies } = deps;
11 | return dependencies.map(d => {
12 | d.diff = '-';
13 | if(d.latest !== '-') {
14 | d.diff = diff(coerce(d.version), coerce(d.latest));
15 | }
16 | return d;
17 | });
18 | });
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/app/components/destroy-runner.hbs:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/app/components/destroy-runner.js:
--------------------------------------------------------------------------------
1 | import Component from '@glimmer/component';
2 |
3 | import { action } from '@ember/object';
4 | import { tracked } from '@glimmer/tracking';
5 | import blueprints from 'ember-cli-ui/constants/blueprints';
6 |
7 | export default class DestroyRunnerComponent extends Component {
8 |
9 | @tracked blueprint = 'component';
10 | @tracked name;
11 | @tracked command;
12 |
13 | blueprints = Object.keys(blueprints).map(b => {
14 | return { title: b, value: blueprints[b] }
15 | });
16 |
17 | @action
18 | runDestroy() {
19 | if(this.name) {
20 | this.command = `ember d ${this.blueprint} ${this.name}\r\n`;
21 | }
22 | }
23 |
24 | @action
25 | updateBlueprint(event) {
26 | this.blueprint = event.target.value;
27 | }
28 |
29 |
30 | }
31 |
--------------------------------------------------------------------------------
/app/components/generate-runner.hbs:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/app/components/generate-runner.js:
--------------------------------------------------------------------------------
1 | import Component from '@glimmer/component';
2 | import { action } from '@ember/object';
3 | import { tracked } from '@glimmer/tracking';
4 | import blueprints from 'ember-cli-ui/constants/blueprints';
5 |
6 | export default class GenerateRunnerComponent extends Component {
7 |
8 | @tracked blueprint = 'component';
9 | @tracked name;
10 | @tracked command;
11 |
12 | blueprints = Object.keys(blueprints).map(b => {
13 | return { title: b, value: blueprints[b] }
14 | });
15 |
16 | @action
17 | runGenerate() {
18 | if(this.name) {
19 | this.command = `ember g ${this.blueprint} ${this.name}\r\n`;
20 | }
21 | }
22 |
23 | @action
24 | updateBlueprint(event) {
25 | this.blueprint = event.target.value;
26 | }
27 |
28 |
29 | }
30 |
--------------------------------------------------------------------------------
/app/components/install-runner.hbs:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/components/install-runner.js:
--------------------------------------------------------------------------------
1 | import Component from '@glimmer/component';
2 | import { action } from '@ember/object';
3 | import { tracked } from '@glimmer/tracking';
4 |
5 | export default class InstallRunnerComponent extends Component {
6 |
7 | @tracked name;
8 | @tracked command;
9 |
10 | @action
11 | runInstall() {
12 | if(this.name) {
13 | this.command = `ember install ${this.name}\r\n`;
14 | }
15 | }
16 |
17 | }
18 |
--------------------------------------------------------------------------------
/app/components/lint-runner.hbs:
--------------------------------------------------------------------------------
1 |
5 |
9 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/app/components/lint-runner.js:
--------------------------------------------------------------------------------
1 | import Component from '@glimmer/component';
2 | import { action } from '@ember/object';
3 | import { tracked } from '@glimmer/tracking';
4 |
5 | export default class LintRunnerComponent extends Component {
6 |
7 | @tracked command;
8 | @tracked type = 'all';
9 |
10 | @action
11 | runLint() {
12 | if(this.type === 'all') {
13 | this.command = 'npm run lint\r\n';
14 | } else {
15 | this.command = `npm run lint:${this.type}\r\n`;
16 | }
17 | }
18 |
19 | @action
20 | updateType(event) {
21 | this.type = event.target.value;
22 | console.log(this.type);
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/app/components/loading-spinner.hbs:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/components/new-project-runner.hbs:
--------------------------------------------------------------------------------
1 |
2 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
--------------------------------------------------------------------------------
/app/components/new-project-runner.js:
--------------------------------------------------------------------------------
1 | import Component from '@glimmer/component';
2 | import { tracked } from '@glimmer/tracking';
3 | import { action } from '@ember/object';
4 |
5 | export default class NewProjectRunnerComponent extends Component {
6 | dryRun = false
7 | verbose = false
8 | npm = false
9 | git = false
10 | yarn = false
11 | bower = false
12 | appName = 'my-app'
13 | blueprint = ''
14 | dir = ''
15 | noWelcome = false
16 | alias = true
17 |
18 | @tracked name;
19 | @tracked command;
20 |
21 |
22 | @action
23 | createNewProject() {
24 |
25 | const dryRun = this.dryRun ?
26 | this.alias ? '-d' : ' --dry-run' : '';
27 |
28 | const npm = this.npm ? this.alias ? '-sn' : '--skip-npm' : '';
29 | const git = this.git ? this.alias ? '-sg' : '--skip-git' : '';
30 | const bower = this.bower ? this.alias ? '-sb' : '--skip-bower' : '';
31 | const yarn = this.yarn ? '--yarn' : '';
32 | const noWelcome = this.noWelcome ? '--no-welcome' : '';
33 | const verbose = this.verbose ? this.alias ? '-v' : '--verbose' : '';
34 | const blueprint = this.blueprint ? this.alias ? `-b ${this.blueprint}` : `--blueprint ${this.blueprint}` : '';
35 | const dir = this.dir ? this.alias ? `-dir ${this.dir}` : `--directory ${this.dir}` : '';
36 | const _command = `ember new ${this.name} ${dryRun} ${npm} ${git} ${bower} ${yarn} ${verbose} ${blueprint} ${dir} ${noWelcome}\r\n`;
37 | console.log(_command);
38 | this.command = _command;
39 | }
40 |
41 |
42 | @action
43 | toggleDryRun() {
44 | this.dryRun = !this.dryRun;
45 | }
46 |
47 | @action
48 | toggleVerbose() {
49 | this.verbose = !this.verbose;
50 | }
51 |
52 | @action
53 | toggleSkipNpm() {
54 | this.npm = !this.npm;
55 | }
56 |
57 | @action
58 | toggleSkipGit() {
59 | this.git = !this.git;
60 |
61 | }
62 |
63 | @action
64 | toggleYarn() {
65 | this.yarn = !this.yarn;
66 |
67 | }
68 |
69 | @action
70 | toggleSkipBower() {
71 | this.bower = !this.bower;
72 | }
73 |
74 | @action
75 | toggleWelcome() {
76 | this.noWelcome = !this.noWelcome;
77 | }
78 |
79 | @action
80 | updateAppName(event) {
81 | this.appName = event.target.value;
82 | }
83 |
84 | @action
85 | updateBlueprint(event) {
86 | this.blueprint = event.target.value;
87 | }
88 |
89 | @action
90 | updateDirectory(event) {
91 | this.dir = event.target.value;
92 | }
93 | }
94 |
--------------------------------------------------------------------------------
/app/components/project-info.hbs:
--------------------------------------------------------------------------------
1 | {{this.project.name}}
2 | {{this.project.description}}
3 | Version: {{this.project.version}}
4 | ember-cli: {{this.project.cliVersion}}
5 | Dependencies: {{this.project.depsLength}}
6 | Dev Dependencies: {{this.project.devDepsLength}}
7 | private: {{this.project.private}}
8 | LICENSE: {{this.project.license}}
9 | Ember edition: {{this.project.edition}}
10 | Node version: {{this.project.node}}
11 |
--------------------------------------------------------------------------------
/app/components/project-info.js:
--------------------------------------------------------------------------------
1 | import Component from '@glimmer/component';
2 | import { inject as service } from '@ember/service';
3 |
4 | export default class ProjectInfoComponent extends Component {
5 | @service project;
6 | }
7 |
--------------------------------------------------------------------------------
/app/components/project-task-runner.hbs:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 | {{this.taskCommand}}
9 |
10 |
--------------------------------------------------------------------------------
/app/components/project-task-runner.js:
--------------------------------------------------------------------------------
1 | import Component from '@glimmer/component';
2 | import { tracked } from '@glimmer/tracking';
3 | import { action } from '@ember/object';
4 | import { inject as service } from '@ember/service';
5 |
6 | export default class ProjectTaskRunnerComponent extends Component {
7 |
8 | @service project;
9 |
10 | @tracked task;
11 | @tracked command;
12 | @tracked taskCommand;
13 |
14 | @action
15 | runTask() {
16 | this.command = `npm run ${this.task}\r\n`;
17 | }
18 |
19 | @action
20 | updateTask(event) {
21 | this.task = event.target.value;
22 | this.taskCommand = this.project.tasks.find(t => t.name === this.task).task;
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/app/components/semver-badge.hbs:
--------------------------------------------------------------------------------
1 | {{log @type}}
2 | {{#if (eq @type "patch")}}
3 | PATCH
4 | {{else if (eq @type "minor")}}
5 | MINOR
6 | {{else if (eq @type "major")}}
7 | BREAKING
8 | {{else}}
9 | -
10 | {{/if}}
11 |
--------------------------------------------------------------------------------
/app/components/serve-runner.hbs:
--------------------------------------------------------------------------------
1 |
4 |
5 |
--------------------------------------------------------------------------------
/app/components/serve-runner.js:
--------------------------------------------------------------------------------
1 | import Component from '@glimmer/component';
2 | import { tracked } from '@glimmer/tracking';
3 | import { action } from '@ember/object';
4 |
5 | export default class ServeRunnerComponent extends Component {
6 |
7 | @tracked command;
8 | @tracked isBuildRunning = false;
9 | @tracked disabled = false;
10 |
11 | get label() {
12 | return this.isBuildRunning ? "Stop" : "Start";
13 | }
14 |
15 | get icon() {
16 | return this.isBuildRunning ? 'stop' : 'play';
17 | }
18 |
19 | @action
20 | toggleServe() {
21 |
22 | this.command = this.isBuildRunning ? '\x03' : 'npm start\r\n';
23 | this.isBuildRunning = !this.isBuildRunning;
24 | if(this.label === "Start") {
25 | this.disabled = false;
26 | } else {
27 | this.disabled = true;
28 | }
29 | }
30 |
31 | @action
32 | socketCallback(message) {
33 | if(message && message.data) {
34 | if(message.data.includes('Build successful')) {
35 | this.isBuildRunning = true;
36 | this.disabled = false;
37 | }
38 |
39 | if(message.data.includes('ERR')) {
40 | this.isBuildRunning = false;
41 | this.disabled = false;
42 | }
43 | }
44 | }
45 |
46 |
47 | }
48 |
--------------------------------------------------------------------------------
/app/components/speed-data.hbs:
--------------------------------------------------------------------------------
1 | Download Time
2 | {{#each this.items as |i|}}
3 | {{i.name}}: {{i.time}} secs ( {{i.mbps}} mbps )
4 | {{/each}}
5 |
--------------------------------------------------------------------------------
/app/components/speed-data.js:
--------------------------------------------------------------------------------
1 | import Component from '@glimmer/component';
2 |
3 | export default class SpeedDataComponent extends Component {
4 | get items() {
5 | const data = this.args.data;
6 | const keys = Object.keys(this.args.data);
7 | return keys.map(k => {
8 | return {
9 | name: data[k].title,
10 | time: data[k].totalDownloadTime,
11 | mbps: data[k].mbps
12 | }
13 | });
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/app/components/terminal.hbs:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/components/terminal.js:
--------------------------------------------------------------------------------
1 | import Component from '@glimmer/component';
2 |
3 | export default class TerminalComponent extends Component {
4 |
5 | }
6 |
--------------------------------------------------------------------------------
/app/components/test-runner.hbs:
--------------------------------------------------------------------------------
1 |
5 |
9 |
13 |
17 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/app/components/test-runner.js:
--------------------------------------------------------------------------------
1 | import Component from '@glimmer/component';
2 | import { action } from '@ember/object';
3 | import { tracked } from '@glimmer/tracking';
4 |
5 | export default class TestRunnerComponent extends Component {
6 |
7 | @tracked command;
8 | @tracked type = "ALL";
9 | @tracked filter;
10 |
11 | commands = {
12 | ALL: 'npm test',
13 | Unit: 'ember t -f="Unit"',
14 | Integration: 'ember t -f="Integration"',
15 | Acceptance: 'ember t -f="Acceptance"',
16 | 'Custom Filter': '',
17 | };
18 |
19 | @action
20 | runTests() {
21 | if(this.type === 'Custom') {
22 | this.command = `ember t -f="${this.filter}"\r\n`;
23 | } else {
24 | this.command = `${this.commands[this.type]}\r\n`;
25 | }
26 | }
27 |
28 | @action
29 | updateType(event) {
30 | this.type = event.target.value;
31 | }
32 |
33 |
34 |
35 | }
36 |
--------------------------------------------------------------------------------
/app/components/update-runner.hbs:
--------------------------------------------------------------------------------
1 |
2 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
--------------------------------------------------------------------------------
/app/components/update-runner.js:
--------------------------------------------------------------------------------
1 | import Component from '@glimmer/component';
2 | import { action } from '@ember/object';
3 | import { tracked } from '@glimmer/tracking';
4 |
5 | export default class UpdateRunnerComponent extends Component {
6 |
7 | resolveConflicts = false;
8 | runCodemods = false;
9 | reset = false;
10 | compare = false;
11 | stats = false;
12 | listCodemods = false;
13 |
14 | @tracked command;
15 | @tracked toVersion;
16 |
17 | @action
18 | toggleResolveConflicts() {
19 | this.resolveConflicts = !this.resolveConflicts;
20 | }
21 |
22 | @action
23 | toggleRunCodemods() {
24 | this.runCodemods = !this.runCodemods;
25 | }
26 |
27 | @action
28 | toggleReset() {
29 | this.reset = !this.reset;
30 | }
31 |
32 | @action
33 | toggleCompare() {
34 | this.compare = !this.compare;
35 | }
36 |
37 | @action
38 | toggleStats() {
39 | this.stats = !this.stats;
40 | }
41 |
42 | @action
43 | toggleListCodemods() {
44 | this.listCodemods = !this.listCodemods;
45 | }
46 |
47 | @action
48 | runUpdate() {
49 | const {
50 |
51 | resolveConflicts,
52 | runCodemods,
53 | reset,
54 | compare,
55 | stats,
56 | listCodemods,
57 | toVersion
58 | } = this;
59 |
60 | const _resolveConflicts = resolveConflicts ? '--resolve-conflicts' : '';
61 | const _runCodemods = runCodemods ? '--run-codemods' : '';
62 | const _reset = reset ? '--reset' : '';
63 | const _compare = compare ? '--compare-only' : '';
64 | const _stats = stats ? '--stats-only' : '';
65 | const _listCodemods = listCodemods ? '--list-codemods' : '';
66 | const _toVersion = toVersion ? `--to=${toVersion}` : '';
67 |
68 | this.command = `ember-cli-update ${_toVersion} ${_resolveConflicts} ${_runCodemods} ${_reset} ${_compare} ${_stats} ${_listCodemods}\r\n`;
69 | }
70 |
71 | @action
72 | resetProject() {
73 | this.command = `git reset --hard && git clean -f\r\n`;
74 | }
75 |
76 | @action
77 | installEcu() {
78 | this.command = `npm i -g ember-cli-update\r\n`;
79 | }
80 |
81 | }
82 |
--------------------------------------------------------------------------------
/app/constants/blueprints.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | export default {
4 | Component: 'component',
5 | Route: 'route',
6 | Helper: 'helper',
7 | Service: 'service',
8 | Model: 'model',
9 | Util: 'util',
10 | Controller: 'controller',
11 | Mixin: 'mixin',
12 | Adapter: 'adapter',
13 | 'Component-Class': 'component-class',
14 | 'HTTP-Mock': 'http-mock',
15 | 'HTTP-Proxy': 'http-proxy',
16 | 'In-Repo-Addon': 'in-repo-addon',
17 | Lib: 'lib',
18 | Server: 'server',
19 | 'Vendor-Shim': 'vendor-shim',
20 | };
21 |
--------------------------------------------------------------------------------
/app/controllers/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rajasegar/ember-cli-ui/77489c814f0b99b4984f304049ff6da55a5b1d63/app/controllers/.gitkeep
--------------------------------------------------------------------------------
/app/controllers/application.js:
--------------------------------------------------------------------------------
1 | import Controller from '@ember/controller';
2 | import { inject as service } from '@ember/service';
3 |
4 | export default class ApplicationController extends Controller {
5 | @service project;
6 |
7 | datetime = new Date().toLocaleString();
8 |
9 | }
10 |
--------------------------------------------------------------------------------
/app/helpers/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rajasegar/ember-cli-ui/77489c814f0b99b4984f304049ff6da55a5b1d63/app/helpers/.gitkeep
--------------------------------------------------------------------------------
/app/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | ember-cli-ui : Ember CLI on the Browser
7 |
8 |
9 |
10 | {{content-for "head"}}
11 |
12 |
13 |
14 |
15 | {{content-for "head-footer"}}
16 |
17 |
18 | {{content-for "body"}}
19 |
20 |
21 |
22 |
23 | {{content-for "body-footer"}}
24 |
25 |
26 |
--------------------------------------------------------------------------------
/app/models/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rajasegar/ember-cli-ui/77489c814f0b99b4984f304049ff6da55a5b1d63/app/models/.gitkeep
--------------------------------------------------------------------------------
/app/modifiers/create-xterm.js:
--------------------------------------------------------------------------------
1 | import Modifier from 'ember-modifier';
2 | import { Terminal } from 'xterm';
3 | import { AttachAddon } from 'xterm-addon-attach';
4 | import { WebLinksAddon } from 'xterm-addon-web-links';
5 |
6 | export default class CreateXtermModifier extends Modifier {
7 |
8 | socket = null;
9 | term = null;
10 | pid = null;
11 |
12 | didUpdateArguments() {
13 | const command = this.command;
14 | this.socket.send(command);
15 | }
16 |
17 | get command() {
18 | return this.args.named.command;
19 | }
20 |
21 | didInstall() {
22 |
23 | const task = this.args.named.task;
24 | this.term = new Terminal();
25 | this.term.loadAddon(new WebLinksAddon(undefined, undefined, true));
26 | this.term.open(this.element);
27 | this.term.focus();
28 | window.term = this.term;
29 | this.term.onResize((size) => {
30 | if (!this.pid) {
31 | return;
32 | }
33 | const cols = size.cols;
34 | const rows = size.rows;
35 | const url = '/terminals/' + task + '/size?cols=' + cols + '&rows=' + rows;
36 |
37 | fetch(url, {method: 'POST'});
38 | });
39 |
40 | const protocol = (location.protocol === 'https:') ? 'wss://' : 'ws://';
41 | let socketURL = protocol + location.hostname + ((location.port) ? (':' + location.port) : '') + '/terminals/';
42 |
43 | // fit is called within a setTimeout, cols and rows need this.
44 | setTimeout(() => {
45 |
46 |
47 | const url = new URL(`${location.origin}/terminals`);
48 | const params = {
49 | cols: this.term.cols,
50 | rows: this.term.rows,
51 | task: task
52 | };
53 | Object.keys(params).forEach(key => url.searchParams.append(key, params[key]));
54 |
55 | fetch(url, {method: 'POST'}).then((res) => {
56 | res.text().then((processId) => {
57 | this.pid = processId;
58 | socketURL += task;
59 | this.socket = new WebSocket(socketURL);
60 | this.socket.onopen = () => {
61 | this.term.loadAddon(new AttachAddon(this.socket));
62 | this.term._initialized = true;
63 | };
64 | this.socket.onmessage = (event) => {
65 | if(this.args.named.callback) {
66 | this.args.named.callback(event);
67 | }
68 | }
69 | this.socket.onclose = () => {};
70 | this.socket.onerror = () => {};
71 | });
72 | });
73 | }, 0);
74 |
75 |
76 | }
77 |
78 | }
79 |
--------------------------------------------------------------------------------
/app/router.js:
--------------------------------------------------------------------------------
1 | import EmberRouter from '@ember/routing/router';
2 | import config from './config/environment';
3 |
4 | export default class Router extends EmberRouter {
5 | location = config.locationType;
6 | rootURL = config.rootURL;
7 | }
8 |
9 | Router.map(function() {
10 | this.route('serve');
11 | this.route('test');
12 | this.route('lint');
13 | this.route('generate');
14 | this.route('destroy');
15 | this.route('install');
16 | this.route('build');
17 | this.route('project-tasks');
18 | this.route('new-project');
19 | this.route('dependencies');
20 | this.route('project-update');
21 | });
22 |
--------------------------------------------------------------------------------
/app/routes/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rajasegar/ember-cli-ui/77489c814f0b99b4984f304049ff6da55a5b1d63/app/routes/.gitkeep
--------------------------------------------------------------------------------
/app/routes/application.js:
--------------------------------------------------------------------------------
1 | import Route from '@ember/routing/route';
2 | import { inject as service } from '@ember/service';
3 |
4 | export default class ApplicationRoute extends Route {
5 | @service project;
6 | beforeModel() {
7 | return this.project.initialize();
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/app/routes/build.js:
--------------------------------------------------------------------------------
1 | import Route from '@ember/routing/route';
2 |
3 | export default class BuildRoute extends Route {
4 | }
5 |
--------------------------------------------------------------------------------
/app/routes/dependencies.js:
--------------------------------------------------------------------------------
1 | import Route from '@ember/routing/route';
2 |
3 | export default class DependenciesRoute extends Route {
4 |
5 | //async model() {
6 | //const response = await fetch('/dependencies');
7 | //const dependencies = await response.json();
8 |
9 | //return { dependencies };
10 | //}
11 | }
12 |
--------------------------------------------------------------------------------
/app/routes/destroy.js:
--------------------------------------------------------------------------------
1 | import Route from '@ember/routing/route';
2 |
3 | export default class DestroyRoute extends Route {
4 | }
5 |
--------------------------------------------------------------------------------
/app/routes/generate.js:
--------------------------------------------------------------------------------
1 | import Route from '@ember/routing/route';
2 |
3 | export default class GenerateRoute extends Route {
4 | }
5 |
--------------------------------------------------------------------------------
/app/routes/index.js:
--------------------------------------------------------------------------------
1 | import Route from '@ember/routing/route';
2 | import { inject as service } from '@ember/service';
3 |
4 | export default class IndexRoute extends Route {
5 | @service project;
6 |
7 | afterModel() {
8 | // Empty manifest or not an Ember project
9 | if (!this.project.isEmberProject) {
10 | this.transitionTo('new-project');
11 | }
12 |
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/app/routes/install.js:
--------------------------------------------------------------------------------
1 | import Route from '@ember/routing/route';
2 |
3 | export default class InstallRoute extends Route {
4 | }
5 |
--------------------------------------------------------------------------------
/app/routes/lint.js:
--------------------------------------------------------------------------------
1 | import Route from '@ember/routing/route';
2 |
3 | export default class LintRoute extends Route {
4 | }
5 |
--------------------------------------------------------------------------------
/app/routes/new-project.js:
--------------------------------------------------------------------------------
1 | import Route from '@ember/routing/route';
2 |
3 | export default class NewProjectRoute extends Route {
4 | }
5 |
--------------------------------------------------------------------------------
/app/routes/project-tasks.js:
--------------------------------------------------------------------------------
1 | import Route from '@ember/routing/route';
2 |
3 | export default class ProjectTasksRoute extends Route {
4 |
5 | }
6 |
--------------------------------------------------------------------------------
/app/routes/project-update.js:
--------------------------------------------------------------------------------
1 | import Route from '@ember/routing/route';
2 |
3 | export default class ProjectUpdateRoute extends Route {
4 | }
5 |
--------------------------------------------------------------------------------
/app/routes/serve.js:
--------------------------------------------------------------------------------
1 | import Route from '@ember/routing/route';
2 |
3 | export default class ServeRoute extends Route {
4 | }
5 |
--------------------------------------------------------------------------------
/app/routes/test.js:
--------------------------------------------------------------------------------
1 | import Route from '@ember/routing/route';
2 |
3 | export default class TestRoute extends Route {
4 | }
5 |
--------------------------------------------------------------------------------
/app/services/project.js:
--------------------------------------------------------------------------------
1 | import Service from '@ember/service';
2 | import { coerce, valid } from 'semver';
3 |
4 | export default class ProjectService extends Service {
5 | async initialize() {
6 | const response = await fetch('/project');
7 | const project = await response.json();
8 | this.project = project;
9 | return project;
10 | }
11 |
12 | get name() {
13 | return this.project.name;
14 | }
15 |
16 | get description() {
17 | return this.project.description;
18 | }
19 |
20 | get version() {
21 | return this.project.version;
22 | }
23 |
24 | get cliVersion() {
25 | return valid(coerce(this.project.devDependencies['ember-cli']));
26 | }
27 |
28 | get depsLength() {
29 | const { dependencies } = this.project;
30 | const len = dependencies && Object.keys(dependencies).length || 0;
31 | return len;
32 | }
33 |
34 | get devDepsLength() {
35 | const len = Object.keys(this.project.devDependencies).length || 0;
36 | return len;
37 | }
38 |
39 | get license() {
40 | return this.project.license;
41 | }
42 |
43 | get edition() {
44 | return this.project.ember && this.project.ember.edition || '';
45 | }
46 |
47 | get node() {
48 | return this.project.engines.node;
49 | }
50 |
51 | get private() {
52 | return this.project.private;
53 | }
54 |
55 | get tasks() {
56 | const { scripts } = this.project;
57 | return Object.keys(scripts).map(s => {
58 | return { name: s, task: scripts[s] };
59 | });
60 | }
61 |
62 | get isEmberProject() {
63 |
64 | const hasCli = this.project.devDependencies && this.project.devDependencies['ember-cli'];
65 | return Object.keys(this.project) > 0 || hasCli;
66 |
67 | }
68 |
69 | get projectPath() {
70 | return this.project.projectPath;
71 | }
72 |
73 | }
74 |
--------------------------------------------------------------------------------
/app/services/terminal.js:
--------------------------------------------------------------------------------
1 | import Service from '@ember/service';
2 |
3 | export default class TerminalService extends Service {
4 |
5 | getPort() {
6 | return this.port;
7 | }
8 |
9 | setPort() {
10 |
11 | }
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/app/styles/_typography.css:
--------------------------------------------------------------------------------
1 | .text-white {
2 | color: var(--white);
3 | }
4 |
5 | .text-right {
6 | text-align:right;
7 | }
8 |
9 | .text-center {
10 | text-align: center;
11 | }
12 |
13 | .text-ember {
14 | color: var(--ember);
15 | }
16 |
--------------------------------------------------------------------------------
/app/styles/_variables.css:
--------------------------------------------------------------------------------
1 | :root {
2 | --ember: #E04E39;
3 | --linen: #FDF7F6;
4 | --white: #FDFDFD;
5 | --black: #212121;
6 | --burnt-ember: #9B2918;
7 | --gray: #817F7F;
8 | --blue: #1E719B;
9 | --faint-gray: #EFEBEA;
10 | --light-blue: #74B0CE;
11 | --yellow: #FBC840;
12 | }
13 |
--------------------------------------------------------------------------------
/app/styles/app.css:
--------------------------------------------------------------------------------
1 | @import "_variables.css";
2 | @import "_typography.css";
3 |
4 | @font-face {
5 | font-family: 'Roboto';
6 | src: url('/assets/fonts/Roboto/Roboto-Regular.ttf');
7 | }
8 |
9 | body {
10 | font-family: 'Roboto', sans-serif;
11 | background: var(--linen);
12 | margin: 0;
13 | padding: 0;
14 | border: none;
15 | }
16 |
17 | header {
18 | position:fixed;
19 | top: 0;
20 | left: 200px;
21 | width: 100%;
22 | background: var(--white);
23 | color: var(--gray);
24 | }
25 |
26 | .header-wrapper {
27 | margin: 0.5em;
28 | display: flex;
29 | justify-content: space-around;
30 | }
31 |
32 |
33 | header p {
34 | margin: 0.5em;
35 | }
36 |
37 | .logo {
38 | width: 90%;
39 | margin: 0.5em 0;
40 | }
41 | .main {
42 | display: grid;
43 | grid-template-columns: 200px 1fr;
44 | }
45 |
46 | nav {
47 | background: var(--ember);
48 | height: 100vh;
49 | max-height: 100vh;
50 | }
51 |
52 | nav h1, h2, h3 {
53 | padding-left: 0.5em;
54 | }
55 |
56 |
57 | nav ul {
58 | padding: 0;
59 | }
60 | nav ul li {
61 | list-style: none;
62 | display: flex;
63 | }
64 |
65 | nav ul li a {
66 | color: var(--white);
67 | text-decoration: none;
68 | display: block;
69 | width: 100%;
70 | padding: 0.5em;
71 | }
72 |
73 | nav ul li a:hover {
74 | background: var(--burnt-ember);
75 | }
76 | nav ul li a.active {
77 | color: var(--ember);
78 | background: var(--linen);
79 | }
80 |
81 |
82 | h1,h2,h3,h4,h5,h6 {
83 | color: var(--ember);
84 | }
85 |
86 | button {
87 | margin: 1em;
88 | padding: .75em;
89 | color: var(--ember);
90 | background: var(--white);
91 | border:1px solid var(--ember);
92 | border-radius: 4px;
93 | cursor: pointer;
94 | font-size:1em;
95 | }
96 |
97 | button:hover {
98 | background: var(--ember);
99 | color: var(--white);
100 | }
101 |
102 | button[disabled] {
103 | color: var(--gray);
104 | border:1px solid var(--gray);
105 | cursor: not-allowed;
106 | }
107 |
108 | button[disabled]:hover {
109 | background: none;
110 | }
111 |
112 | .right_col {
113 | padding: 1em;
114 | margin: 2em 0 3em 0;
115 | max-height: 100vh;
116 | overflow: auto;
117 | }
118 |
119 |
120 | .terminal {
121 | padding: 1em;
122 | }
123 |
124 | input[type="text"], select {
125 | padding: 0 1em;
126 | margin: 1em;
127 | border: 1px solid var(--gray);
128 | height: 40px;
129 | color: var(--ember);
130 | border-radius: 4px;
131 | font-size: 1em;
132 | }
133 |
134 | .input--big {
135 | width: 400px;
136 | }
137 |
138 | code {
139 | background: var(--faint-gray);
140 | color: var(--blue);
141 | border-radius: 4px;
142 | font-weight: bold;
143 | padding: 1em;
144 | font-size: 1.25em;
145 | margin: 1em 0;
146 | display: block;
147 |
148 | }
149 |
150 | a {
151 | color: var(--ember);
152 | }
153 |
154 | .fas { padding-right: .25em; }
155 |
156 | footer {
157 | position:fixed;
158 | bottom: 0;
159 | left: 200px;
160 | width: 100%;
161 | margin: 0 auto;
162 | text-align:center;
163 | background: var(--white);
164 | }
165 |
166 | footer p {
167 | margin: .5em 0;
168 | }
169 |
170 | .new-project-wrapper {
171 | display: grid;
172 | grid-template-columns: 1fr 3fr;
173 | }
174 |
175 | table, td,th {
176 | border: 1px solid var(--black);
177 | border-collapse: collapse;
178 | }
179 |
180 | table td, table th {
181 | padding: .5em;
182 | }
183 |
184 | .semver-badge {
185 | color: var(--white);
186 | padding: .25em;
187 | border-radius: 2px;
188 | }
189 | .patch {
190 | background: green;
191 | }
192 |
193 | .minor {
194 | background: #ff7700;
195 | }
196 |
197 | .major {
198 | background: var(--ember);
199 | }
200 |
201 | .loader {
202 | border: 8px solid var(--faint-gray);
203 | border-top: 8px solid var(--ember);
204 | border-radius: 50%;
205 | width: 60px;
206 | height: 60px;
207 | animation: spin 2s linear infinite;
208 | margin-left: 50vh;
209 | }
210 |
211 | @keyframes spin {
212 | 0% { transform: rotate(0deg); }
213 | 100% { transform: rotate(360deg); }
214 | }
215 |
216 | .ember-tooltip {
217 | min-width: 250px !important;
218 | }
219 |
220 | .build-log {
221 | margin-top: 1em;
222 | background: var(--faint-gray);
223 | border: solid 1px var(--gray);
224 | border-radius: 4px;
225 | padding: 1em;
226 | min-height:50px;
227 | }
228 |
229 | .date-time-wrapper {
230 | margin-right: 1em;
231 | }
232 |
--------------------------------------------------------------------------------
/app/templates/application.hbs:
--------------------------------------------------------------------------------
1 |
2 |
41 |
42 |
57 | {{outlet}}
58 |
63 |
64 |
65 |
--------------------------------------------------------------------------------
/app/templates/build.hbs:
--------------------------------------------------------------------------------
1 | Build your Ember project
2 | Run ember build -prod in your project
3 |
4 |
--------------------------------------------------------------------------------
/app/templates/dependencies.hbs:
--------------------------------------------------------------------------------
1 | Project Dependencies
2 | Your project's dependencies and dev dependencies are listed here.
3 | Dependencies
4 |
5 | Dev Dependencies
6 |
7 |
--------------------------------------------------------------------------------
/app/templates/destroy.hbs:
--------------------------------------------------------------------------------
1 | Destroy Blueprints
2 | Run ember destroy command.
3 |
4 |
--------------------------------------------------------------------------------
/app/templates/generate.hbs:
--------------------------------------------------------------------------------
1 | Generate Blueprints
2 | Run ember generate command.
3 |
4 |
--------------------------------------------------------------------------------
/app/templates/index.hbs:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/templates/install.hbs:
--------------------------------------------------------------------------------
1 | Install Ember Addons
2 |
3 |
--------------------------------------------------------------------------------
/app/templates/lint.hbs:
--------------------------------------------------------------------------------
1 | Lint
2 |
3 |
--------------------------------------------------------------------------------
/app/templates/new-project.hbs:
--------------------------------------------------------------------------------
1 | New Project
2 | Create a new Ember.js app
3 |
4 |
--------------------------------------------------------------------------------
/app/templates/project-tasks.hbs:
--------------------------------------------------------------------------------
1 | Project Tasks
2 | Run your project's npm scripts
3 |
4 |
--------------------------------------------------------------------------------
/app/templates/project-update.hbs:
--------------------------------------------------------------------------------
1 | Update Project
2 | Run ember-cli-update to update your Ember project.
3 |
4 |
--------------------------------------------------------------------------------
/app/templates/serve.hbs:
--------------------------------------------------------------------------------
1 | Serve
2 | Run ember serve command
3 |
4 |
--------------------------------------------------------------------------------
/app/templates/test.hbs:
--------------------------------------------------------------------------------
1 | Test
2 | Run your project's test suite. You can filter by category and create custom filters for your tests.
3 |
4 |
--------------------------------------------------------------------------------
/bin/cli.js:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 |
3 | /* globals require process */
4 |
5 | 'use strict';
6 |
7 | process.title = 'ember-cli-ui';
8 | console.log('Ember cli UI');
9 | const startServer = require('../server');
10 | startServer(process.cwd());
11 |
--------------------------------------------------------------------------------
/config/environment.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | module.exports = function(environment) {
4 | let ENV = {
5 | modulePrefix: 'ember-cli-ui',
6 | environment,
7 | rootURL: '/',
8 | locationType: 'auto',
9 | EmberENV: {
10 | FEATURES: {
11 | // Here you can enable experimental features on an ember canary build
12 | // e.g. EMBER_NATIVE_DECORATOR_SUPPORT: true
13 | },
14 | EXTEND_PROTOTYPES: {
15 | // Prevent Ember Data from overriding Date.parse.
16 | Date: false
17 | }
18 | },
19 |
20 | APP: {
21 | // Here you can pass flags/options to your application instance
22 | // when it is created
23 | }
24 | };
25 |
26 | if (environment === 'development') {
27 | // ENV.APP.LOG_RESOLVER = true;
28 | // ENV.APP.LOG_ACTIVE_GENERATION = true;
29 | // ENV.APP.LOG_TRANSITIONS = true;
30 | // ENV.APP.LOG_TRANSITIONS_INTERNAL = true;
31 | // ENV.APP.LOG_VIEW_LOOKUPS = true;
32 | ENV.locationType = 'hash';
33 | }
34 |
35 | if (environment === 'test') {
36 | // Testem prefers this...
37 | ENV.locationType = 'none';
38 |
39 | // keep test console output quieter
40 | ENV.APP.LOG_ACTIVE_GENERATION = false;
41 | ENV.APP.LOG_VIEW_LOOKUPS = false;
42 |
43 | ENV.APP.rootElement = '#ember-testing';
44 | ENV.APP.autoboot = false;
45 | }
46 |
47 | if (environment === 'production') {
48 | // here you can enable a production-specific feature
49 | ENV.locationType = 'hash';
50 | }
51 |
52 | return ENV;
53 | };
54 |
--------------------------------------------------------------------------------
/config/icons.js:
--------------------------------------------------------------------------------
1 | module.exports = function() {
2 | return {
3 | 'free-solid-svg-icons': [
4 | 'home',
5 | 'server',
6 | 'vial',
7 | 'broom',
8 | 'plus-square',
9 | 'trash-alt',
10 | 'download',
11 | 'file-archive',
12 | 'tasks',
13 | 'folder-plus',
14 | 'cubes',
15 | 'wrench',
16 | 'play',
17 | 'stop',
18 | 'undo',
19 | 'suitcase',
20 | 'folder',
21 | 'bug',
22 | 'list'
23 | ]
24 | };
25 | };
26 |
--------------------------------------------------------------------------------
/config/optional-features.json:
--------------------------------------------------------------------------------
1 | {
2 | "application-template-wrapper": false,
3 | "default-async-observers": true,
4 | "jquery-integration": false,
5 | "template-only-glimmer-components": true
6 | }
7 |
--------------------------------------------------------------------------------
/config/targets.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const browsers = [
4 | 'last 1 Chrome versions',
5 | 'last 1 Firefox versions',
6 | 'last 1 Safari versions'
7 | ];
8 |
9 | const isCI = !!process.env.CI;
10 | const isProduction = process.env.EMBER_ENV === 'production';
11 |
12 | if (isCI || isProduction) {
13 | browsers.push('ie 11');
14 | }
15 |
16 | module.exports = {
17 | browsers
18 | };
19 |
--------------------------------------------------------------------------------
/dist/assets/_typography-26492ca975c5072739cd1f79152e22fb.css:
--------------------------------------------------------------------------------
1 | .text-white{color:var(--white)}.text-right{text-align:right}.text-center{text-align:center}.text-ember{color:var(--ember)}
--------------------------------------------------------------------------------
/dist/assets/_variables-fce0c1ab1a5617d5140d494ca66fd3ed.css:
--------------------------------------------------------------------------------
1 | :root{--ember:#E04E39;--linen:#FDF7F6;--white:#FDFDFD;--black:#212121;--burnt-ember:#9B2918;--gray:#817F7F;--blue:#1E719B;--faint-gray:#EFEBEA;--light-blue:#74B0CE;--yellow:#FBC840}
--------------------------------------------------------------------------------
/dist/assets/ember-cli-ui-45b8d2f6b987b65710d49ba200643149.css:
--------------------------------------------------------------------------------
1 | @import "_variables-fce0c1ab1a5617d5140d494ca66fd3ed.css";@import "_typography-26492ca975c5072739cd1f79152e22fb.css";body,nav ul{padding:0}.right_col,nav{max-height:100vh}.right_col,.terminal,code{padding:1em}footer,header{position:fixed;left:200px}@font-face{font-family:Roboto;src:url(/assets/fonts/Roboto/Roboto-Regular.ttf)}body{font-family:Roboto,sans-serif;background:var(--linen);margin:0;border:none}header{top:0;width:100%;background:var(--white);color:var(--gray)}.header-wrapper{margin:.5em;display:flex;justify-content:space-around}header p{margin:.5em}.logo{width:90%;margin:.5em 0}.main{display:grid;grid-template-columns:200px 1fr}nav{background:var(--ember);height:100vh}h2,h3,nav h1{padding-left:.5em}nav ul li{list-style:none;display:flex}nav ul li a{color:var(--white);text-decoration:none;display:block;width:100%;padding:.5em}nav ul li a:hover{background:var(--burnt-ember)}nav ul li a.active{color:var(--ember);background:var(--linen)}button,footer{background:var(--white)}h1,h2,h3,h4,h5,h6{color:var(--ember)}button{margin:1em;padding:.75em;color:var(--ember);border:1px solid var(--ember);border-radius:4px;cursor:pointer;font-size:1em}button:hover{background:var(--ember);color:var(--white)}button[disabled]{color:var(--gray);border:1px solid var(--gray);cursor:not-allowed}button[disabled]:hover{background:0 0}.right_col{margin:2em 0 3em;overflow:auto}input[type=text],select{padding:0 1em;margin:1em;border:1px solid var(--gray);height:40px;color:var(--ember);border-radius:4px;font-size:1em}.input--big{width:400px}code{background:var(--faint-gray);color:var(--blue);border-radius:4px;font-weight:700;font-size:1.25em;margin:1em 0;display:block}a{color:var(--ember)}.fas{padding-right:.25em}footer{bottom:0;width:100%;margin:0 auto;text-align:center}footer p{margin:.5em 0}.new-project-wrapper{display:grid;grid-template-columns:1fr 3fr}table,td,th{border:1px solid var(--black);border-collapse:collapse}table td,table th{padding:.5em}.semver-badge{color:var(--white);padding:.25em;border-radius:2px}.patch{background:green}.minor{background:#f70}.major{background:var(--ember)}.loader{border:8px solid var(--faint-gray);border-top:8px solid var(--ember);border-radius:50%;width:60px;height:60px;animation:spin 2s linear infinite;margin-left:50vh}@keyframes spin{0%{transform:rotate(0)}100%{transform:rotate(360deg)}}.ember-tooltip{min-width:250px!important}.build-log{margin-top:1em;background:var(--faint-gray);border:1px solid var(--gray);border-radius:4px;padding:1em;min-height:50px}.date-time-wrapper{margin-right:1em}
--------------------------------------------------------------------------------
/dist/assets/fonts/Roboto/Roboto-Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rajasegar/ember-cli-ui/77489c814f0b99b4984f304049ff6da55a5b1d63/dist/assets/fonts/Roboto/Roboto-Regular.ttf
--------------------------------------------------------------------------------
/dist/assets/images/favicon-f2d07120d2bb7f0d4a63810011903d75.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rajasegar/ember-cli-ui/77489c814f0b99b4984f304049ff6da55a5b1d63/dist/assets/images/favicon-f2d07120d2bb7f0d4a63810011903d75.png
--------------------------------------------------------------------------------
/dist/assets/images/logo-26455e836959ac197f36f57a49b5b61f.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rajasegar/ember-cli-ui/77489c814f0b99b4984f304049ff6da55a5b1d63/dist/assets/images/logo-26455e836959ac197f36f57a49b5b61f.png
--------------------------------------------------------------------------------
/dist/assets/vendor-e5446f7e2988be0cf64ea9511b7d7a8e.css:
--------------------------------------------------------------------------------
1 | .fa-layers,.svg-inline--fa{height:1em;display:inline-block}.svg-inline--fa,svg:not(:root).svg-inline--fa{overflow:visible}.fa-inverse,.fa-layers-counter,.fad.fa-inverse{color:#fff}.svg-inline--fa{font-size:inherit;vertical-align:-.125em}.svg-inline--fa.fa-lg{vertical-align:-.225em}.svg-inline--fa.fa-w-1{width:.0625em}.svg-inline--fa.fa-w-2{width:.125em}.svg-inline--fa.fa-w-3{width:.1875em}.svg-inline--fa.fa-w-4{width:.25em}.svg-inline--fa.fa-w-5{width:.3125em}.svg-inline--fa.fa-w-6{width:.375em}.svg-inline--fa.fa-w-7{width:.4375em}.svg-inline--fa.fa-w-8{width:.5em}.svg-inline--fa.fa-w-9{width:.5625em}.svg-inline--fa.fa-w-10{width:.625em}.svg-inline--fa.fa-w-11{width:.6875em}.svg-inline--fa.fa-w-12{width:.75em}.svg-inline--fa.fa-w-13{width:.8125em}.svg-inline--fa.fa-w-14{width:.875em}.svg-inline--fa.fa-w-15{width:.9375em}.svg-inline--fa.fa-w-16{width:1em}.svg-inline--fa.fa-w-17{width:1.0625em}.svg-inline--fa.fa-w-18{width:1.125em}.svg-inline--fa.fa-w-19{width:1.1875em}.svg-inline--fa.fa-w-20{width:1.25em}.svg-inline--fa.fa-pull-left{margin-right:.3em;width:auto}.svg-inline--fa.fa-pull-right{margin-left:.3em;width:auto}.svg-inline--fa.fa-border{height:1.5em}.svg-inline--fa.fa-li{width:2em}.fa-fw,.svg-inline--fa.fa-fw{width:1.25em}.fa-layers svg.svg-inline--fa{bottom:0;left:0;margin:auto;position:absolute;right:0;top:0;-webkit-transform-origin:center center;transform-origin:center center}.fa-layers,.fa-stack,.fa-ul>li{position:relative}.fa-layers{text-align:center;vertical-align:-.125em;width:1em}.fa-layers-counter,.fa-layers-text{display:inline-block;position:absolute;text-align:center}.fa-layers-text{left:50%;top:50%;-webkit-transform:translate(-50%,-50%);transform:translate(-50%,-50%);-webkit-transform-origin:center center;transform-origin:center center}.fa-layers-counter{background-color:#ff253a;border-radius:1em;-webkit-box-sizing:border-box;box-sizing:border-box;height:1.5em;line-height:1;max-width:5em;min-width:1.5em;overflow:hidden;padding:.25em;right:0;text-overflow:ellipsis;top:0;-webkit-transform:scale(.25);transform:scale(.25);-webkit-transform-origin:top right;transform-origin:top right}.fa-layers-bottom-right{bottom:0;right:0;top:auto;-webkit-transform:scale(.25);transform:scale(.25);-webkit-transform-origin:bottom right;transform-origin:bottom right}.fa-layers-bottom-left{bottom:0;left:0;right:auto;top:auto;-webkit-transform:scale(.25);transform:scale(.25);-webkit-transform-origin:bottom left;transform-origin:bottom left}.fa-layers-top-right{right:0;top:0;-webkit-transform:scale(.25);transform:scale(.25);-webkit-transform-origin:top right;transform-origin:top right}.fa-layers-top-left{left:0;right:auto;top:0;-webkit-transform:scale(.25);transform:scale(.25);-webkit-transform-origin:top left;transform-origin:top left}.fa-lg{font-size:1.3333333333em;line-height:.75em;vertical-align:-.0667em}.fa-xs{font-size:.75em}.fa-sm{font-size:.875em}.fa-1x{font-size:1em}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-6x{font-size:6em}.fa-7x{font-size:7em}.fa-8x{font-size:8em}.fa-9x{font-size:9em}.fa-10x{font-size:10em}.fa-fw{text-align:center}.fa-ul{list-style-type:none;margin-left:2.5em;padding-left:0}.fa-li{left:-2em;position:absolute;text-align:center;width:2em;line-height:inherit}.fa-border{border:.08em solid #eee;border-radius:.1em;padding:.2em .25em .15em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa.fa-pull-left,.fab.fa-pull-left,.fal.fa-pull-left,.far.fa-pull-left,.fas.fa-pull-left{margin-right:.3em}.fa.fa-pull-right,.fab.fa-pull-right,.fal.fa-pull-right,.far.fa-pull-right,.fas.fa-pull-right{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s infinite linear;animation:fa-spin 2s infinite linear}.fa-pulse{-webkit-animation:fa-spin 1s infinite steps(8);animation:fa-spin 1s infinite steps(8)}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";-webkit-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";-webkit-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";-webkit-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";-webkit-transform:scale(-1,1);transform:scale(-1,1)}.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";-webkit-transform:scale(1,-1);transform:scale(1,-1)}.fa-flip-both,.fa-flip-horizontal.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";-webkit-transform:scale(-1,-1);transform:scale(-1,-1)}:root .fa-flip-both,:root .fa-flip-horizontal,:root .fa-flip-vertical,:root .fa-rotate-180,:root .fa-rotate-270,:root .fa-rotate-90{-webkit-filter:none;filter:none}.fa-stack{display:inline-block;height:2em;width:2.5em}.fa-stack-1x,.fa-stack-2x{bottom:0;left:0;margin:auto;position:absolute;right:0;top:0}.svg-inline--fa.fa-stack-1x{height:1em;width:1.25em}.svg-inline--fa.fa-stack-2x{height:2em;width:2.5em}.sr-only{border:0;clip:rect(0,0,0,0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.sr-only-focusable:active,.sr-only-focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.svg-inline--fa .fa-primary{fill:var(--fa-primary-color,currentColor);opacity:1;opacity:var(--fa-primary-opacity,1)}.svg-inline--fa .fa-secondary{fill:var(--fa-secondary-color,currentColor);opacity:.4;opacity:var(--fa-secondary-opacity,.4)}.svg-inline--fa.fa-swap-opacity .fa-primary{opacity:.4;opacity:var(--fa-secondary-opacity,.4)}.svg-inline--fa.fa-swap-opacity .fa-secondary{opacity:1;opacity:var(--fa-primary-opacity,1)}.svg-inline--fa mask .fa-primary,.svg-inline--fa mask .fa-secondary{fill:#000}.xterm{font-feature-settings:"liga" 0;position:relative;user-select:none;-ms-user-select:none;-webkit-user-select:none}.xterm.focus,.xterm:focus{outline:0}.xterm .xterm-helpers{position:absolute;top:0;z-index:5}.xterm .xterm-helper-textarea{padding:0;border:0;margin:0;position:absolute;opacity:0;left:-9999em;top:0;width:0;height:0;z-index:-5;white-space:nowrap;overflow:hidden;resize:none}.xterm .composition-view{background:#000;color:#FFF;display:none;position:absolute;white-space:nowrap;z-index:1}.xterm .composition-view.active{display:block}.xterm .xterm-viewport{background-color:#000;overflow-y:scroll;cursor:default;position:absolute;right:0;left:0;top:0;bottom:0}.xterm .xterm-screen{position:relative}.xterm .xterm-screen canvas{position:absolute;left:0;top:0}.xterm .xterm-scroll-area{visibility:hidden}.xterm-char-measure-element{display:inline-block;visibility:hidden;position:absolute;top:0;left:-9999em;line-height:normal}.xterm{cursor:text}.xterm.enable-mouse-events{cursor:default}.xterm.xterm-cursor-pointer{cursor:pointer}.xterm.column-select.focus{cursor:crosshair}.xterm .xterm-accessibility,.xterm .xterm-message{position:absolute;left:0;top:0;bottom:0;right:0;z-index:10;color:transparent}.xterm .live-region{position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden}.xterm-dim{opacity:.5}.xterm-underline{text-decoration:underline}.ember-tooltip-base{display:none;height:0;width:0;position:absolute}.ember-popover,.ember-tooltip{margin-bottom:10px;-webkit-touch-callout:none;-webkit-user-select:none;user-select:none;pointer-events:none;position:absolute;z-index:2;font-size:14px;font-family:inherit;border-radius:3px;opacity:0;-webkit-transition:opacity ease-out,margin ease-out;transition:opacity ease-out,margin ease-out;transition-duration:.2s}.ember-tooltip{max-width:200px;padding:6px 10px;color:#fff;background:#3a3c47;text-shadow:-1px -1px 0 rgba(0,0,0,.2);white-space:normal;white-space:initial}.ember-popover{color:#000;background-color:#fff;padding:10px 20px;border:1px solid #ccc}.ember-popover[aria-hidden=false]{pointer-events:auto;cursor:initial;-webkit-touch-callout:auto;-webkit-user-select:auto;user-select:auto}.ember-popover-arrow,.ember-tooltip-arrow{width:0;height:0;position:absolute;margin:5px;border:5px solid transparent}.ember-popover.ember-tooltip-effect-none,.ember-popover.ember-tooltip-show,.ember-tooltip.ember-tooltip-effect-none,.ember-tooltip.ember-tooltip-show{opacity:1}.ember-popover[x-placement^=top] .ember-popover-arrow,.ember-tooltip[x-placement^=top] .ember-tooltip-arrow{border-bottom-width:0;bottom:-5px;left:calc(50% - 5px);margin-top:0;margin-bottom:0}.ember-tooltip[x-placement^=top] .ember-tooltip-arrow{border-top-color:#3a3c47}.ember-popover[x-placement^=top] .ember-popover-arrow{border-top-color:#ccc}.ember-popover[x-placement^=right] .ember-popover-arrow,.ember-tooltip[x-placement^=right] .ember-tooltip-arrow{border-left-width:0;left:-5px;top:calc(50% - 5px);margin-right:0;margin-left:0}.ember-tooltip[x-placement^=right] .ember-tooltip-arrow{border-right-color:#3a3c47}.ember-popover[x-placement^=right] .ember-popover-arrow{border-right-color:#ccc}.ember-popover[x-placement^=bottom] .ember-popover-arrow,.ember-tooltip[x-placement^=bottom] .ember-tooltip-arrow{border-top-width:0;top:-5px;left:calc(50% - 5px);margin-bottom:0;margin-top:0}.ember-tooltip[x-placement^=bottom] .ember-tooltip-arrow{border-bottom-color:#3a3c47}.ember-popover[x-placement^=bottom] .ember-popover-arrow{border-bottom-color:#ccc}.ember-popover[x-placement^=left] .ember-popover-arrow,.ember-tooltip[x-placement^=left] .ember-tooltip-arrow{border-right-width:0;right:-5px;top:calc(50% - 5px);margin-left:0;margin-right:0}.ember-tooltip[x-placement^=left] .ember-tooltip-arrow{border-left-color:#3a3c47}.ember-popover[x-placement^=left] .ember-popover-arrow{border-left-color:#ccc}
--------------------------------------------------------------------------------
/dist/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | ember-cli-ui : Ember CLI on the Browser
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/dist/robots.txt:
--------------------------------------------------------------------------------
1 | # http://www.robotstxt.org
2 | User-agent: *
3 | Disallow:
4 |
--------------------------------------------------------------------------------
/ember-cli-build.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const EmberApp = require('ember-cli/lib/broccoli/ember-app');
4 |
5 | module.exports = function(defaults) {
6 | let app = new EmberApp(defaults, {
7 | });
8 |
9 |
10 | app.import('node_modules/xterm/css/xterm.css');
11 | // Use `app.import` to add additional libraries to the generated
12 | // output files.
13 | //
14 | // If you need to use different assets in different
15 | // environments, specify an object as the first parameter. That
16 | // object's keys should be the environment name and the values
17 | // should be the asset to use in that environment.
18 | //
19 | // If the library that you are including contains AMD or ES6
20 | // modules that you would like to import into your application
21 | // please specify an object with the list of modules as keys
22 | // along with the exports of each module as its value.
23 |
24 | return app.toTree();
25 | };
26 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "ember-cli-ui",
3 | "version": "0.14.0",
4 | "description": "ember-cli in the browser",
5 | "repository": "https://github.com/rajasegar/ember-cli-ui",
6 | "license": "MIT",
7 | "author": "Rajasegar Chandran ",
8 | "directories": {
9 | "doc": "doc",
10 | "test": "tests"
11 | },
12 | "bin": {
13 | "ember-cli-ui": "bin/cli.js"
14 | },
15 | "scripts": {
16 | "build": "ember build --environment=production",
17 | "lint": "npm-run-all --aggregate-output --continue-on-error --parallel lint:*",
18 | "lint:hbs": "ember-template-lint .",
19 | "lint:js": "eslint .",
20 | "start:cli": "./bin/cli.js",
21 | "build:watch": "ember build --watch",
22 | "start": "npm-run-all --aggregate-output --parallel start:cli build:watch",
23 | "test": "npm-run-all lint:* test:*",
24 | "test:ember": "ember test",
25 | "deploy": " git push && git push --tags && npm publish"
26 | },
27 | "devDependencies": {
28 | "@ember/optional-features": "^1.3.0",
29 | "@fortawesome/ember-fontawesome": "^0.2.1",
30 | "@fortawesome/free-solid-svg-icons": "^5.14.0",
31 | "@glimmer/component": "^1.0.0",
32 | "@glimmer/tracking": "^1.0.0",
33 | "babel-eslint": "^10.1.0",
34 | "broccoli-asset-rev": "^3.0.0",
35 | "ember-async-await-helper": "^0.2.0",
36 | "ember-auto-import": "^1.5.3",
37 | "ember-cli": "~3.19.0",
38 | "ember-cli-app-version": "^3.2.0",
39 | "ember-cli-babel": "^7.20.5",
40 | "ember-cli-dependency-checker": "^3.2.0",
41 | "ember-cli-htmlbars": "^5.1.2",
42 | "ember-cli-inject-live-reload": "^2.0.2",
43 | "ember-cli-sri": "^2.1.1",
44 | "ember-cli-uglify": "^3.0.0",
45 | "ember-data": "~3.19.0",
46 | "ember-export-application-global": "^2.0.1",
47 | "ember-fetch": "^8.0.1",
48 | "ember-load-initializers": "^2.1.1",
49 | "ember-maybe-import-regenerator": "^0.1.6",
50 | "ember-modifier": "^2.1.0",
51 | "ember-qunit": "^4.6.0",
52 | "ember-resolver": "^8.0.0",
53 | "ember-source": "~3.19.0",
54 | "ember-svg-jar": "^2.2.3",
55 | "ember-template-lint": "^2.8.0",
56 | "ember-tooltips": "^3.4.5",
57 | "ember-truth-helpers": "^2.1.0",
58 | "eslint": "^7.1.0",
59 | "eslint-plugin-ember": "^8.6.0",
60 | "eslint-plugin-node": "^11.1.0",
61 | "loader.js": "^4.7.0",
62 | "npm-run-all": "^4.1.5",
63 | "qunit-dom": "^1.2.0"
64 | },
65 | "engines": {
66 | "node": "10.* || >= 12"
67 | },
68 | "ember": {
69 | "edition": "octane"
70 | },
71 | "dependencies": {
72 | "ansi_up": "^4.0.4",
73 | "express": "^4.10.7",
74 | "express-ws": "^4.0.0",
75 | "filesize": "^6.1.0",
76 | "get-port": "^5.1.1",
77 | "node-pty": "^0.9.0",
78 | "npm-check-updates": "^7.1.1",
79 | "resolve": "^1.17.0",
80 | "semver": "^7.3.2",
81 | "walk-sync": "^2.2.0",
82 | "xterm": "^4.8.1",
83 | "xterm-addon-attach": "^0.6.0",
84 | "xterm-addon-fit": "^0.4.0",
85 | "xterm-addon-web-links": "^0.4.0"
86 | },
87 | "ember-addon": {}
88 | }
89 |
--------------------------------------------------------------------------------
/public/assets/fonts/Roboto/Roboto-Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rajasegar/ember-cli-ui/77489c814f0b99b4984f304049ff6da55a5b1d63/public/assets/fonts/Roboto/Roboto-Regular.ttf
--------------------------------------------------------------------------------
/public/assets/images/favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rajasegar/ember-cli-ui/77489c814f0b99b4984f304049ff6da55a5b1d63/public/assets/images/favicon.png
--------------------------------------------------------------------------------
/public/assets/images/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rajasegar/ember-cli-ui/77489c814f0b99b4984f304049ff6da55a5b1d63/public/assets/images/logo.png
--------------------------------------------------------------------------------
/public/robots.txt:
--------------------------------------------------------------------------------
1 | # http://www.robotstxt.org
2 | User-agent: *
3 | Disallow:
4 |
--------------------------------------------------------------------------------
/screenshots/build.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rajasegar/ember-cli-ui/77489c814f0b99b4984f304049ff6da55a5b1d63/screenshots/build.png
--------------------------------------------------------------------------------
/screenshots/destroy.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rajasegar/ember-cli-ui/77489c814f0b99b4984f304049ff6da55a5b1d63/screenshots/destroy.png
--------------------------------------------------------------------------------
/screenshots/generate.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rajasegar/ember-cli-ui/77489c814f0b99b4984f304049ff6da55a5b1d63/screenshots/generate.png
--------------------------------------------------------------------------------
/screenshots/home.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rajasegar/ember-cli-ui/77489c814f0b99b4984f304049ff6da55a5b1d63/screenshots/home.png
--------------------------------------------------------------------------------
/screenshots/install.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rajasegar/ember-cli-ui/77489c814f0b99b4984f304049ff6da55a5b1d63/screenshots/install.png
--------------------------------------------------------------------------------
/screenshots/lint.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rajasegar/ember-cli-ui/77489c814f0b99b4984f304049ff6da55a5b1d63/screenshots/lint.png
--------------------------------------------------------------------------------
/screenshots/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rajasegar/ember-cli-ui/77489c814f0b99b4984f304049ff6da55a5b1d63/screenshots/logo.png
--------------------------------------------------------------------------------
/screenshots/project-tasks.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rajasegar/ember-cli-ui/77489c814f0b99b4984f304049ff6da55a5b1d63/screenshots/project-tasks.png
--------------------------------------------------------------------------------
/screenshots/serve.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rajasegar/ember-cli-ui/77489c814f0b99b4984f304049ff6da55a5b1d63/screenshots/serve.png
--------------------------------------------------------------------------------
/screenshots/test.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rajasegar/ember-cli-ui/77489c814f0b99b4984f304049ff6da55a5b1d63/screenshots/test.png
--------------------------------------------------------------------------------
/server/index.js:
--------------------------------------------------------------------------------
1 | const express = require('express');
2 | const expressWs = require('express-ws');
3 | const os = require('os');
4 | const pty = require('node-pty');
5 | const path = require('path');
6 | const getPort = require('get-port');
7 | const { exec } = require('child_process');
8 | const fs = require('fs');
9 | const ncu = require('npm-check-updates');
10 | const buffer = require('./utils/buffer');
11 | const getBuildAssets = require('./utils/getBuildAssets');
12 | const { Writable } = require('stream');
13 | const AU = require('ansi_up');
14 | const ansi_up = new AU.default;
15 | const resolve = require('resolve');
16 |
17 | function startServer(projectPath) {
18 | //projectPath = '/Users/rajasegarchandran/www/super-rentals';
19 |
20 | const app = express();
21 | expressWs(app);
22 |
23 | const terminals = {};
24 | const logs = {};
25 |
26 | app.get('/', (req, res) => {
27 | const indexFile = path.join(__dirname, '..', 'dist/index.html');
28 | res.sendFile(indexFile);
29 | });
30 |
31 | app.use('/assets', express.static(path.join(__dirname, '..', 'dist/assets')));
32 |
33 | app.get('/project', (req,res) => {
34 | const manifestPath =`${projectPath}/package.json`;
35 | if(fs.existsSync(manifestPath)) {
36 | const manifest = require(manifestPath);
37 | manifest.projectPath = projectPath;
38 | res.json(manifest);
39 | } else {
40 | res.json({});
41 | }
42 | });
43 |
44 | app.get('/assets', (req, res) => {
45 |
46 | const files = getBuildAssets(projectPath);
47 |
48 | res.json(files);
49 | });
50 |
51 | app.get('/build', async (req, res) => {
52 | const buildLogs = [];
53 | const errLogs = [];
54 | const logStream = new Writable({
55 | objectMode: true,
56 | write: (data, _, done) => {
57 | console.log('<-', data.toString());
58 | buildLogs.push(ansi_up.ansi_to_html(data.toString()));
59 | done();
60 | }
61 | });
62 |
63 | const errStream = new Writable({
64 | objectMode: true,
65 | write: (data, _, done) => {
66 | console.log('<-', data.toString());
67 | errLogs.push(ansi_up.ansi_to_html(data.toString()));
68 | done();
69 | }
70 | });
71 |
72 | let projectLocalCli;
73 | try {
74 | projectLocalCli = resolve.sync('ember-cli', {
75 | basedir: projectPath
76 | });
77 | } catch(ignored) {} // eslint-disable-line
78 |
79 | console.log('Resolved "ember-cli" to %j', projectLocalCli);
80 |
81 | // Load `ember-cli` either from the project-local path, or if it could not
82 | // be resolved use the global version
83 | var cli = require(projectLocalCli || 'ember-cli/lib/cli');
84 |
85 |
86 | const result = await cli({
87 | cliArgs: ['build', '-prod'],
88 | inputStream: process.stdin,
89 | outputStream: logStream,
90 | errorStream: errStream
91 | })
92 |
93 | const assets = getBuildAssets(projectPath);
94 |
95 | res.json({ result, logs: buildLogs, assets, errLogs });
96 |
97 | });
98 |
99 | app.get('/dependencies', async (req, res) => {
100 | const upgraded = await ncu.run();
101 | const manifestPath =`${projectPath}/package.json`;
102 | const manifest = require(manifestPath);
103 | const { devDependencies, dependencies } = manifest;
104 | let deps;
105 | if(req.query.type === 'dev') {
106 | deps = devDependencies;
107 | } else {
108 | deps = dependencies || {};
109 | }
110 |
111 | const _deps = Object.keys(deps).map(k => {
112 | const obj = {
113 | name: k,
114 | version: deps[k],
115 | latest: '-'
116 | };
117 | if(upgraded[k]) {
118 | obj.latest = upgraded[k];
119 | }
120 | return obj;
121 | });
122 |
123 | return res.json({ dependencies: _deps});
124 | });
125 |
126 |
127 | app.post('/terminals', (req, res) => {
128 | const env = Object.assign({}, process.env);
129 | env['COLORTERM'] = 'truecolor';
130 | const cols = parseInt(req.query.cols);
131 | const rows = parseInt(req.query.rows);
132 | const task = req.query.task;
133 | let term;
134 |
135 | // Connect if term is already there
136 | // instead of creating a new one
137 | if(terminals[task]) {
138 | term = terminals[task];
139 | } else {
140 | term = pty.spawn(process.platform === 'win32' ? 'cmd.exe' : 'bash', [], {
141 | name: 'xterm-256color',
142 | cols: cols || 80,
143 | rows: rows || 24,
144 | cwd: projectPath,
145 | env: env,
146 | // encoding: USE_BINARY ? null : 'utf8'
147 | encoding: 'utf8'
148 | });
149 |
150 | term.write('clear\r');
151 | term.write('pwd\r');
152 |
153 | console.log('Created terminal with PID: ' + term.pid);
154 |
155 | // terminals use task name as the key eg. build, serve
156 | terminals[task] = term;
157 |
158 | // logs still use pid as the key
159 | logs[term.pid] = '';
160 | }
161 |
162 | term.on('data', function(data) {
163 | logs[term.pid] += data;
164 | });
165 | res.send(term.pid.toString());
166 | res.end();
167 | });
168 |
169 | // TODO: Change pid reference to task
170 | app.post('/terminals/:pid/size', (req, res) => {
171 | const pid = parseInt(req.params.pid);
172 | const cols = parseInt(req.query.cols);
173 | const rows = parseInt(req.query.rows);
174 | const term = terminals[pid];
175 |
176 | term.resize(cols, rows);
177 | console.log('Resized terminal ' + pid + ' to ' + cols + ' cols and ' + rows + ' rows.');
178 | res.end();
179 | });
180 |
181 | app.ws('/terminals/:termid', function (ws, req) {
182 | const termId = req.params.termid;
183 | const term = terminals[termId];
184 | console.log('Connected to terminal ' + term.pid);
185 | ws.send(logs[term.pid]);
186 |
187 | // const send = USE_BINARY ? bufferUtf8(ws, 5) : buffer(ws, 5);
188 | const send = buffer(ws, 5);
189 |
190 | term.on('data', function(data) {
191 | try {
192 | send(data);
193 | } catch (ex) {
194 | // The WebSocket is not open, ignore
195 | }
196 | });
197 | ws.on('message', function(msg) {
198 | term.write(msg);
199 | // Change the project to new path
200 | if(msg.includes('ember new')) {
201 | const [,,newPath] = msg.split(' ');
202 | projectPath += "/" + newPath;
203 | }
204 | });
205 | ws.on('close', function () {
206 | term.kill();
207 | console.log('Closed terminal ' + term.pid);
208 | // Clean things up
209 | delete terminals[termId];
210 | delete logs[term.pid];
211 | });
212 | });
213 |
214 | (async () => {
215 | const port = await getPort();
216 |
217 | const host = os.platform() === 'win32' ? '127.0.0.1' : '0.0.0.0';
218 |
219 | console.log('Xterm listening to http://localhost:' + port);
220 |
221 | let openCommand = 'open';
222 | if (os.platform() === 'win32') openCommand = 'start';
223 | if (os.platform() === 'linux') openCommand = 'xdg-open';
224 |
225 | exec(`${openCommand} http://localhost:${port}`, () => {});
226 |
227 | app.listen(port, host);
228 | })();
229 |
230 | }
231 |
232 | module.exports = startServer;
233 |
--------------------------------------------------------------------------------
/server/utils/buffer.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | // string message buffering
4 | module.exports = function (socket, timeout) {
5 | let s = '';
6 | let sender = null;
7 | return (data) => {
8 | s += data;
9 | if (!sender) {
10 | sender = setTimeout(() => {
11 | socket.send(s);
12 | s = '';
13 | sender = null;
14 | }, timeout);
15 | }
16 | };
17 | };
18 |
--------------------------------------------------------------------------------
/server/utils/bufferUtf8.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | // binary message buffering
4 | module.exports = function (socket, timeout) {
5 | let buffer = [];
6 | let sender = null;
7 | let length = 0;
8 | return (data) => {
9 | buffer.push(data);
10 | length += data.length;
11 | if (!sender) {
12 | sender = setTimeout(() => {
13 | socket.send(Buffer.concat(buffer, length));
14 | buffer = [];
15 | sender = null;
16 | length = 0;
17 | }, timeout);
18 | }
19 | };
20 | };
21 |
--------------------------------------------------------------------------------
/server/utils/downloadTime.js:
--------------------------------------------------------------------------------
1 | // Copied from
2 | // https://raw.githubusercontent.com/vuejs/vue-cli/dev/packages/%40vue/cli-ui-addon-webpack/src/util/assets.js
3 | const speedsData = require('./speeds.json');
4 |
5 | const DOWNLOAD_TIME_THRESHOLD_SECONDS = 5
6 |
7 | function getSpeedData (datapoint, size) {
8 | const assetsSizeInMB = size / 1024 / 1024
9 | const bandwidthInMbps = datapoint.mbps
10 | const bandwidthInMBps = bandwidthInMbps / 8
11 | const rttInSeconds = datapoint.rtt / 1000
12 |
13 | const totalDownloadTime = assetsSizeInMB / bandwidthInMBps + rttInSeconds
14 |
15 | const isDownloadTimeOverThreshold =
16 | totalDownloadTime > DOWNLOAD_TIME_THRESHOLD_SECONDS
17 | const timeDifferenceToThreshold =
18 | (isDownloadTimeOverThreshold ? '+' : '-') +
19 | Math.abs(totalDownloadTime - DOWNLOAD_TIME_THRESHOLD_SECONDS).toFixed(2) +
20 | 's'
21 |
22 | return {
23 | totalDownloadTime: Number(totalDownloadTime).toFixed(2),
24 | isDownloadTimeOverThreshold,
25 | timeDifferenceToThreshold
26 | }
27 | }
28 |
29 | function getSpeeds (size) {
30 | return Object.keys(speedsData).reduce((obj, key) => {
31 | obj[key] = {
32 | ...getSpeedData(speedsData[key], size),
33 | ...speedsData[key]
34 | }
35 | return obj
36 | }, {})
37 | }
38 |
39 | function buildSortedAssets (assets, sizeField) {
40 | let list = assets.slice()
41 | if (list.length) {
42 | const max = list[0].size
43 | list = list.map(asset => {
44 | const size = asset.size[sizeField]
45 | return {
46 | name: asset.name,
47 | size,
48 | big: size > 250000,
49 | ratio: size / max,
50 | secondary: /\.map$/.test(asset.name),
51 | speeds: getSpeeds(size)
52 | }
53 | })
54 | list.sort((a, b) => {
55 | if (a.secondary === b.secondary) {
56 | return b.size - a.size
57 | } else if (a.secondary && !b.secondary) {
58 | return 1
59 | } else {
60 | return -1
61 | }
62 | })
63 | }
64 | return list
65 | }
66 |
67 | module.exports = {
68 | buildSortedAssets,
69 | getSpeedData,
70 | getSpeeds
71 | }
72 |
73 |
--------------------------------------------------------------------------------
/server/utils/getBuildAssets.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const fs = require('fs');
4 | const zlib = require('zlib');
5 | const walkSync = require('walk-sync');
6 | const filesize = require('filesize');
7 | const { getSpeeds } = require('./downloadTime');
8 |
9 | module.exports = function(projectPath) {
10 |
11 | return walkSync(`${projectPath}/dist`, { globs: ['**/*.js','**/*.css'] })
12 | .map(file => {
13 |
14 | const filePath = `${projectPath}/dist/${file}`;
15 | let contentsBuffer = fs.readFileSync(filePath);
16 | let output = {
17 | name: file,
18 | size: filesize(contentsBuffer.length),
19 | };
20 |
21 | const gzipSize = contentsBuffer.length > 0 ? zlib.gzipSync(contentsBuffer).length : 0;
22 | output.gzipSize = filesize(gzipSize);
23 | output.speeds = getSpeeds(gzipSize);
24 |
25 | return output;
26 | });
27 | }
28 |
--------------------------------------------------------------------------------
/server/utils/speeds.json:
--------------------------------------------------------------------------------
1 | {
2 | "global": { "title": "Global Average", "mbps": 7, "rtt": 30 },
3 | "edge": { "title": "Mobile Edge", "mbps": 0.24, "rtt": 840 },
4 | "2g": { "title": "2G", "mbps": 0.28, "rtt": 800 },
5 | "3gs": { "title": "3G Slow", "mbps": 0.4, "rtt": 400 },
6 | "3gb": { "title": "3G Basic", "mbps": 1.6, "rtt": 300 },
7 | "3gf": { "title": "3G Fast", "mbps": 1.6, "rtt": 150 },
8 | "4g": { "title": "4G", "mbps": 9, "rtt": 170 },
9 | "lte": { "title": "LTE", "mbps": 12, "rtt": 70 },
10 | "dup": { "title": "Dial Up", "mbps": 0.05, "rtt": 120 },
11 | "dsl": { "title": "DSL", "mbps": 1.5, "rtt": 50 },
12 | "cable": { "title": "Cable", "mbps": 5, "rtt": 28 },
13 | "fios": { "title": "FIOS", "mbps": 20, "rtt": 4 }
14 | }
15 |
--------------------------------------------------------------------------------
/testem.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | module.exports = {
4 | test_page: 'tests/index.html?hidepassed',
5 | disable_watching: true,
6 | launch_in_ci: [
7 | 'Chrome'
8 | ],
9 | launch_in_dev: [
10 | 'Chrome'
11 | ],
12 | browser_start_timeout: 120,
13 | browser_args: {
14 | Chrome: {
15 | ci: [
16 | // --no-sandbox is needed when running Chrome inside a container
17 | process.env.CI ? '--no-sandbox' : null,
18 | '--headless',
19 | '--disable-dev-shm-usage',
20 | '--disable-software-rasterizer',
21 | '--mute-audio',
22 | '--remote-debugging-port=0',
23 | '--window-size=1440,900'
24 | ].filter(Boolean)
25 | }
26 | }
27 | };
28 |
--------------------------------------------------------------------------------
/tests/helpers/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rajasegar/ember-cli-ui/77489c814f0b99b4984f304049ff6da55a5b1d63/tests/helpers/.gitkeep
--------------------------------------------------------------------------------
/tests/helpers/flash-message.js:
--------------------------------------------------------------------------------
1 | import FlashObject from 'ember-cli-flash/flash/object';
2 |
3 | FlashObject.reopen({ init() {} });
4 |
--------------------------------------------------------------------------------
/tests/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | EmberCliUi Tests
7 |
8 |
9 |
10 | {{content-for "head"}}
11 | {{content-for "test-head"}}
12 |
13 |
14 |
15 |
16 |
17 | {{content-for "head-footer"}}
18 | {{content-for "test-head-footer"}}
19 |
20 |
21 | {{content-for "body"}}
22 | {{content-for "test-body"}}
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 | {{content-for "body-footer"}}
31 | {{content-for "test-body-footer"}}
32 |
33 |
34 |
--------------------------------------------------------------------------------
/tests/integration/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rajasegar/ember-cli-ui/77489c814f0b99b4984f304049ff6da55a5b1d63/tests/integration/.gitkeep
--------------------------------------------------------------------------------
/tests/integration/components/build-runner-test.js:
--------------------------------------------------------------------------------
1 | import { module, test } from 'qunit';
2 | import { setupRenderingTest } from 'ember-qunit';
3 | import { render } from '@ember/test-helpers';
4 | import { hbs } from 'ember-cli-htmlbars';
5 |
6 | module('Integration | Component | build-runner', function(hooks) {
7 | setupRenderingTest(hooks);
8 |
9 | test('it renders', async function(assert) {
10 | // Set any properties with this.set('myProperty', 'value');
11 | // Handle any actions with this.set('myAction', function(val) { ... });
12 |
13 | await render(hbs``);
14 |
15 | assert.equal(this.element.textContent.trim(), '');
16 |
17 | // Template block usage:
18 | await render(hbs`
19 |
20 | template block text
21 |
22 | `);
23 |
24 | assert.equal(this.element.textContent.trim(), 'template block text');
25 | });
26 | });
27 |
--------------------------------------------------------------------------------
/tests/integration/components/deps-list-test.js:
--------------------------------------------------------------------------------
1 | import { module, test } from 'qunit';
2 | import { setupRenderingTest } from 'ember-qunit';
3 | import { render } from '@ember/test-helpers';
4 | import { hbs } from 'ember-cli-htmlbars';
5 |
6 | module('Integration | Component | deps-list', function(hooks) {
7 | setupRenderingTest(hooks);
8 |
9 | test('it renders', async function(assert) {
10 | // Set any properties with this.set('myProperty', 'value');
11 | // Handle any actions with this.set('myAction', function(val) { ... });
12 |
13 | await render(hbs``);
14 |
15 | assert.equal(this.element.textContent.trim(), '');
16 |
17 | // Template block usage:
18 | await render(hbs`
19 |
20 | template block text
21 |
22 | `);
23 |
24 | assert.equal(this.element.textContent.trim(), 'template block text');
25 | });
26 | });
27 |
--------------------------------------------------------------------------------
/tests/integration/components/destroy-runner-test.js:
--------------------------------------------------------------------------------
1 | import { module, test } from 'qunit';
2 | import { setupRenderingTest } from 'ember-qunit';
3 | import { render } from '@ember/test-helpers';
4 | import { hbs } from 'ember-cli-htmlbars';
5 |
6 | module('Integration | Component | destroy-runner', function(hooks) {
7 | setupRenderingTest(hooks);
8 |
9 | test('it renders', async function(assert) {
10 | // Set any properties with this.set('myProperty', 'value');
11 | // Handle any actions with this.set('myAction', function(val) { ... });
12 |
13 | await render(hbs``);
14 |
15 | assert.equal(this.element.textContent.trim(), '');
16 |
17 | // Template block usage:
18 | await render(hbs`
19 |
20 | template block text
21 |
22 | `);
23 |
24 | assert.equal(this.element.textContent.trim(), 'template block text');
25 | });
26 | });
27 |
--------------------------------------------------------------------------------
/tests/integration/components/generate-runner-test.js:
--------------------------------------------------------------------------------
1 | import { module, test } from 'qunit';
2 | import { setupRenderingTest } from 'ember-qunit';
3 | import { render } from '@ember/test-helpers';
4 | import { hbs } from 'ember-cli-htmlbars';
5 |
6 | module('Integration | Component | generate-runner', function(hooks) {
7 | setupRenderingTest(hooks);
8 |
9 | test('it renders', async function(assert) {
10 | // Set any properties with this.set('myProperty', 'value');
11 | // Handle any actions with this.set('myAction', function(val) { ... });
12 |
13 | await render(hbs``);
14 |
15 | assert.equal(this.element.textContent.trim(), '');
16 |
17 | // Template block usage:
18 | await render(hbs`
19 |
20 | template block text
21 |
22 | `);
23 |
24 | assert.equal(this.element.textContent.trim(), 'template block text');
25 | });
26 | });
27 |
--------------------------------------------------------------------------------
/tests/integration/components/install-runner-test.js:
--------------------------------------------------------------------------------
1 | import { module, test } from 'qunit';
2 | import { setupRenderingTest } from 'ember-qunit';
3 | import { render } from '@ember/test-helpers';
4 | import { hbs } from 'ember-cli-htmlbars';
5 |
6 | module('Integration | Component | install-runner', function(hooks) {
7 | setupRenderingTest(hooks);
8 |
9 | test('it renders', async function(assert) {
10 | // Set any properties with this.set('myProperty', 'value');
11 | // Handle any actions with this.set('myAction', function(val) { ... });
12 |
13 | await render(hbs``);
14 |
15 | assert.equal(this.element.textContent.trim(), '');
16 |
17 | // Template block usage:
18 | await render(hbs`
19 |
20 | template block text
21 |
22 | `);
23 |
24 | assert.equal(this.element.textContent.trim(), 'template block text');
25 | });
26 | });
27 |
--------------------------------------------------------------------------------
/tests/integration/components/lint-runner-test.js:
--------------------------------------------------------------------------------
1 | import { module, test } from 'qunit';
2 | import { setupRenderingTest } from 'ember-qunit';
3 | import { render } from '@ember/test-helpers';
4 | import { hbs } from 'ember-cli-htmlbars';
5 |
6 | module('Integration | Component | lint-runner', function(hooks) {
7 | setupRenderingTest(hooks);
8 |
9 | test('it renders', async function(assert) {
10 | // Set any properties with this.set('myProperty', 'value');
11 | // Handle any actions with this.set('myAction', function(val) { ... });
12 |
13 | await render(hbs``);
14 |
15 | assert.equal(this.element.textContent.trim(), '');
16 |
17 | // Template block usage:
18 | await render(hbs`
19 |
20 | template block text
21 |
22 | `);
23 |
24 | assert.equal(this.element.textContent.trim(), 'template block text');
25 | });
26 | });
27 |
--------------------------------------------------------------------------------
/tests/integration/components/loading-spinner-test.js:
--------------------------------------------------------------------------------
1 | import { module, test } from 'qunit';
2 | import { setupRenderingTest } from 'ember-qunit';
3 | import { render } from '@ember/test-helpers';
4 | import { hbs } from 'ember-cli-htmlbars';
5 |
6 | module('Integration | Component | loading-spinner', function(hooks) {
7 | setupRenderingTest(hooks);
8 |
9 | test('it renders', async function(assert) {
10 | // Set any properties with this.set('myProperty', 'value');
11 | // Handle any actions with this.set('myAction', function(val) { ... });
12 |
13 | await render(hbs``);
14 |
15 | assert.equal(this.element.textContent.trim(), '');
16 |
17 | // Template block usage:
18 | await render(hbs`
19 |
20 | template block text
21 |
22 | `);
23 |
24 | assert.equal(this.element.textContent.trim(), 'template block text');
25 | });
26 | });
27 |
--------------------------------------------------------------------------------
/tests/integration/components/new-project-runner-test.js:
--------------------------------------------------------------------------------
1 | import { module, test } from 'qunit';
2 | import { setupRenderingTest } from 'ember-qunit';
3 | import { render } from '@ember/test-helpers';
4 | import { hbs } from 'ember-cli-htmlbars';
5 |
6 | module('Integration | Component | new-project-runner', function(hooks) {
7 | setupRenderingTest(hooks);
8 |
9 | test('it renders', async function(assert) {
10 | // Set any properties with this.set('myProperty', 'value');
11 | // Handle any actions with this.set('myAction', function(val) { ... });
12 |
13 | await render(hbs``);
14 |
15 | assert.equal(this.element.textContent.trim(), '');
16 |
17 | // Template block usage:
18 | await render(hbs`
19 |
20 | template block text
21 |
22 | `);
23 |
24 | assert.equal(this.element.textContent.trim(), 'template block text');
25 | });
26 | });
27 |
--------------------------------------------------------------------------------
/tests/integration/components/project-info-test.js:
--------------------------------------------------------------------------------
1 | import { module, test } from 'qunit';
2 | import { setupRenderingTest } from 'ember-qunit';
3 | import { render } from '@ember/test-helpers';
4 | import { hbs } from 'ember-cli-htmlbars';
5 |
6 | module('Integration | Component | project-info', function(hooks) {
7 | setupRenderingTest(hooks);
8 |
9 | test('it renders', async function(assert) {
10 | // Set any properties with this.set('myProperty', 'value');
11 | // Handle any actions with this.set('myAction', function(val) { ... });
12 |
13 | await render(hbs``);
14 |
15 | assert.equal(this.element.textContent.trim(), '');
16 |
17 | // Template block usage:
18 | await render(hbs`
19 |
20 | template block text
21 |
22 | `);
23 |
24 | assert.equal(this.element.textContent.trim(), 'template block text');
25 | });
26 | });
27 |
--------------------------------------------------------------------------------
/tests/integration/components/project-task-runner-test.js:
--------------------------------------------------------------------------------
1 | import { module, test } from 'qunit';
2 | import { setupRenderingTest } from 'ember-qunit';
3 | import { render } from '@ember/test-helpers';
4 | import { hbs } from 'ember-cli-htmlbars';
5 |
6 | module('Integration | Component | project-task-runner', function(hooks) {
7 | setupRenderingTest(hooks);
8 |
9 | test('it renders', async function(assert) {
10 | // Set any properties with this.set('myProperty', 'value');
11 | // Handle any actions with this.set('myAction', function(val) { ... });
12 |
13 | await render(hbs``);
14 |
15 | assert.equal(this.element.textContent.trim(), '');
16 |
17 | // Template block usage:
18 | await render(hbs`
19 |
20 | template block text
21 |
22 | `);
23 |
24 | assert.equal(this.element.textContent.trim(), 'template block text');
25 | });
26 | });
27 |
--------------------------------------------------------------------------------
/tests/integration/components/semver-badge-test.js:
--------------------------------------------------------------------------------
1 | import { module, test } from 'qunit';
2 | import { setupRenderingTest } from 'ember-qunit';
3 | import { render } from '@ember/test-helpers';
4 | import { hbs } from 'ember-cli-htmlbars';
5 |
6 | module('Integration | Component | semver-badge', function(hooks) {
7 | setupRenderingTest(hooks);
8 |
9 | test('it renders', async function(assert) {
10 | // Set any properties with this.set('myProperty', 'value');
11 | // Handle any actions with this.set('myAction', function(val) { ... });
12 |
13 | await render(hbs``);
14 |
15 | assert.equal(this.element.textContent.trim(), '');
16 |
17 | // Template block usage:
18 | await render(hbs`
19 |
20 | template block text
21 |
22 | `);
23 |
24 | assert.equal(this.element.textContent.trim(), 'template block text');
25 | });
26 | });
27 |
--------------------------------------------------------------------------------
/tests/integration/components/serve-runner-test.js:
--------------------------------------------------------------------------------
1 | import { module, test } from 'qunit';
2 | import { setupRenderingTest } from 'ember-qunit';
3 | import { render } from '@ember/test-helpers';
4 | import { hbs } from 'ember-cli-htmlbars';
5 |
6 | module('Integration | Component | serve-runner', function(hooks) {
7 | setupRenderingTest(hooks);
8 |
9 | test('it renders', async function(assert) {
10 | // Set any properties with this.set('myProperty', 'value');
11 | // Handle any actions with this.set('myAction', function(val) { ... });
12 |
13 | await render(hbs``);
14 |
15 | assert.equal(this.element.textContent.trim(), '');
16 |
17 | // Template block usage:
18 | await render(hbs`
19 |
20 | template block text
21 |
22 | `);
23 |
24 | assert.equal(this.element.textContent.trim(), 'template block text');
25 | });
26 | });
27 |
--------------------------------------------------------------------------------
/tests/integration/components/speed-data-test.js:
--------------------------------------------------------------------------------
1 | import { module, test } from 'qunit';
2 | import { setupRenderingTest } from 'ember-qunit';
3 | import { render } from '@ember/test-helpers';
4 | import { hbs } from 'ember-cli-htmlbars';
5 |
6 | module('Integration | Component | speed-data', function(hooks) {
7 | setupRenderingTest(hooks);
8 |
9 | test('it renders', async function(assert) {
10 | // Set any properties with this.set('myProperty', 'value');
11 | // Handle any actions with this.set('myAction', function(val) { ... });
12 |
13 | await render(hbs``);
14 |
15 | assert.equal(this.element.textContent.trim(), '');
16 |
17 | // Template block usage:
18 | await render(hbs`
19 |
20 | template block text
21 |
22 | `);
23 |
24 | assert.equal(this.element.textContent.trim(), 'template block text');
25 | });
26 | });
27 |
--------------------------------------------------------------------------------
/tests/integration/components/terminal-test.js:
--------------------------------------------------------------------------------
1 | import { module, test } from 'qunit';
2 | import { setupRenderingTest } from 'ember-qunit';
3 | import { render } from '@ember/test-helpers';
4 | import { hbs } from 'ember-cli-htmlbars';
5 |
6 | module('Integration | Component | terminal', function(hooks) {
7 | setupRenderingTest(hooks);
8 |
9 | test('it renders', async function(assert) {
10 | // Set any properties with this.set('myProperty', 'value');
11 | // Handle any actions with this.set('myAction', function(val) { ... });
12 |
13 | await render(hbs``);
14 |
15 | assert.equal(this.element.textContent.trim(), '');
16 |
17 | // Template block usage:
18 | await render(hbs`
19 |
20 | template block text
21 |
22 | `);
23 |
24 | assert.equal(this.element.textContent.trim(), 'template block text');
25 | });
26 | });
27 |
--------------------------------------------------------------------------------
/tests/integration/components/test-runner-test.js:
--------------------------------------------------------------------------------
1 | import { module, test } from 'qunit';
2 | import { setupRenderingTest } from 'ember-qunit';
3 | import { render } from '@ember/test-helpers';
4 | import { hbs } from 'ember-cli-htmlbars';
5 |
6 | module('Integration | Component | test-runner', function(hooks) {
7 | setupRenderingTest(hooks);
8 |
9 | test('it renders', async function(assert) {
10 | // Set any properties with this.set('myProperty', 'value');
11 | // Handle any actions with this.set('myAction', function(val) { ... });
12 |
13 | await render(hbs``);
14 |
15 | assert.equal(this.element.textContent.trim(), '');
16 |
17 | // Template block usage:
18 | await render(hbs`
19 |
20 | template block text
21 |
22 | `);
23 |
24 | assert.equal(this.element.textContent.trim(), 'template block text');
25 | });
26 | });
27 |
--------------------------------------------------------------------------------
/tests/integration/components/update-runner-test.js:
--------------------------------------------------------------------------------
1 | import { module, test } from 'qunit';
2 | import { setupRenderingTest } from 'ember-qunit';
3 | import { render } from '@ember/test-helpers';
4 | import { hbs } from 'ember-cli-htmlbars';
5 |
6 | module('Integration | Component | update-runner', function(hooks) {
7 | setupRenderingTest(hooks);
8 |
9 | test('it renders', async function(assert) {
10 | // Set any properties with this.set('myProperty', 'value');
11 | // Handle any actions with this.set('myAction', function(val) { ... });
12 |
13 | await render(hbs``);
14 |
15 | assert.equal(this.element.textContent.trim(), '');
16 |
17 | // Template block usage:
18 | await render(hbs`
19 |
20 | template block text
21 |
22 | `);
23 |
24 | assert.equal(this.element.textContent.trim(), 'template block text');
25 | });
26 | });
27 |
--------------------------------------------------------------------------------
/tests/integration/modifiers/create-xterm-test.js:
--------------------------------------------------------------------------------
1 | import { module, test } from 'qunit';
2 | import { setupRenderingTest } from 'ember-qunit';
3 | import { render } from '@ember/test-helpers';
4 | import { hbs } from 'ember-cli-htmlbars';
5 |
6 | module('Integration | Modifier | create-xterm', function(hooks) {
7 | setupRenderingTest(hooks);
8 |
9 | // Replace this with your real tests.
10 | test('it renders', async function(assert) {
11 | await render(hbs``);
12 |
13 | assert.ok(true);
14 | });
15 | });
16 |
--------------------------------------------------------------------------------
/tests/test-helper.js:
--------------------------------------------------------------------------------
1 | import Application from '../app';
2 | import config from '../config/environment';
3 | import { setApplication } from '@ember/test-helpers';
4 | import { start } from 'ember-qunit';
5 | import './helpers/flash-message';
6 |
7 |
8 | setApplication(Application.create(config.APP));
9 |
10 | start();
11 |
--------------------------------------------------------------------------------
/tests/unit/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rajasegar/ember-cli-ui/77489c814f0b99b4984f304049ff6da55a5b1d63/tests/unit/.gitkeep
--------------------------------------------------------------------------------
/tests/unit/controllers/application-test.js:
--------------------------------------------------------------------------------
1 | import { module, test } from 'qunit';
2 | import { setupTest } from 'ember-qunit';
3 |
4 | module('Unit | Controller | application', function(hooks) {
5 | setupTest(hooks);
6 |
7 | // TODO: Replace this with your real tests.
8 | test('it exists', function(assert) {
9 | let controller = this.owner.lookup('controller:application');
10 | assert.ok(controller);
11 | });
12 | });
13 |
--------------------------------------------------------------------------------
/tests/unit/routes/application-test.js:
--------------------------------------------------------------------------------
1 | import { module, test } from 'qunit';
2 | import { setupTest } from 'ember-qunit';
3 |
4 | module('Unit | Route | application', function(hooks) {
5 | setupTest(hooks);
6 |
7 | test('it exists', function(assert) {
8 | let route = this.owner.lookup('route:application');
9 | assert.ok(route);
10 | });
11 | });
12 |
--------------------------------------------------------------------------------
/tests/unit/routes/build-test.js:
--------------------------------------------------------------------------------
1 | import { module, test } from 'qunit';
2 | import { setupTest } from 'ember-qunit';
3 |
4 | module('Unit | Route | build', function(hooks) {
5 | setupTest(hooks);
6 |
7 | test('it exists', function(assert) {
8 | let route = this.owner.lookup('route:build');
9 | assert.ok(route);
10 | });
11 | });
12 |
--------------------------------------------------------------------------------
/tests/unit/routes/dependencies-test.js:
--------------------------------------------------------------------------------
1 | import { module, test } from 'qunit';
2 | import { setupTest } from 'ember-qunit';
3 |
4 | module('Unit | Route | dependencies', function(hooks) {
5 | setupTest(hooks);
6 |
7 | test('it exists', function(assert) {
8 | let route = this.owner.lookup('route:dependencies');
9 | assert.ok(route);
10 | });
11 | });
12 |
--------------------------------------------------------------------------------
/tests/unit/routes/destroy-test.js:
--------------------------------------------------------------------------------
1 | import { module, test } from 'qunit';
2 | import { setupTest } from 'ember-qunit';
3 |
4 | module('Unit | Route | destroy', function(hooks) {
5 | setupTest(hooks);
6 |
7 | test('it exists', function(assert) {
8 | let route = this.owner.lookup('route:destroy');
9 | assert.ok(route);
10 | });
11 | });
12 |
--------------------------------------------------------------------------------
/tests/unit/routes/generate-test.js:
--------------------------------------------------------------------------------
1 | import { module, test } from 'qunit';
2 | import { setupTest } from 'ember-qunit';
3 |
4 | module('Unit | Route | generate', function(hooks) {
5 | setupTest(hooks);
6 |
7 | test('it exists', function(assert) {
8 | let route = this.owner.lookup('route:generate');
9 | assert.ok(route);
10 | });
11 | });
12 |
--------------------------------------------------------------------------------
/tests/unit/routes/index-test.js:
--------------------------------------------------------------------------------
1 | import { module, test } from 'qunit';
2 | import { setupTest } from 'ember-qunit';
3 |
4 | module('Unit | Route | index', function(hooks) {
5 | setupTest(hooks);
6 |
7 | test('it exists', function(assert) {
8 | let route = this.owner.lookup('route:index');
9 | assert.ok(route);
10 | });
11 | });
12 |
--------------------------------------------------------------------------------
/tests/unit/routes/install-test.js:
--------------------------------------------------------------------------------
1 | import { module, test } from 'qunit';
2 | import { setupTest } from 'ember-qunit';
3 |
4 | module('Unit | Route | install', function(hooks) {
5 | setupTest(hooks);
6 |
7 | test('it exists', function(assert) {
8 | let route = this.owner.lookup('route:install');
9 | assert.ok(route);
10 | });
11 | });
12 |
--------------------------------------------------------------------------------
/tests/unit/routes/lint-test.js:
--------------------------------------------------------------------------------
1 | import { module, test } from 'qunit';
2 | import { setupTest } from 'ember-qunit';
3 |
4 | module('Unit | Route | lint', function(hooks) {
5 | setupTest(hooks);
6 |
7 | test('it exists', function(assert) {
8 | let route = this.owner.lookup('route:lint');
9 | assert.ok(route);
10 | });
11 | });
12 |
--------------------------------------------------------------------------------
/tests/unit/routes/new-project-test.js:
--------------------------------------------------------------------------------
1 | import { module, test } from 'qunit';
2 | import { setupTest } from 'ember-qunit';
3 |
4 | module('Unit | Route | new-project', function(hooks) {
5 | setupTest(hooks);
6 |
7 | test('it exists', function(assert) {
8 | let route = this.owner.lookup('route:new-project');
9 | assert.ok(route);
10 | });
11 | });
12 |
--------------------------------------------------------------------------------
/tests/unit/routes/project-tasks-test.js:
--------------------------------------------------------------------------------
1 | import { module, test } from 'qunit';
2 | import { setupTest } from 'ember-qunit';
3 |
4 | module('Unit | Route | project-tasks', function(hooks) {
5 | setupTest(hooks);
6 |
7 | test('it exists', function(assert) {
8 | let route = this.owner.lookup('route:project-tasks');
9 | assert.ok(route);
10 | });
11 | });
12 |
--------------------------------------------------------------------------------
/tests/unit/routes/project-update-test.js:
--------------------------------------------------------------------------------
1 | import { module, test } from 'qunit';
2 | import { setupTest } from 'ember-qunit';
3 |
4 | module('Unit | Route | project-update', function(hooks) {
5 | setupTest(hooks);
6 |
7 | test('it exists', function(assert) {
8 | let route = this.owner.lookup('route:project-update');
9 | assert.ok(route);
10 | });
11 | });
12 |
--------------------------------------------------------------------------------
/tests/unit/routes/serve-test.js:
--------------------------------------------------------------------------------
1 | import { module, test } from 'qunit';
2 | import { setupTest } from 'ember-qunit';
3 |
4 | module('Unit | Route | serve', function(hooks) {
5 | setupTest(hooks);
6 |
7 | test('it exists', function(assert) {
8 | let route = this.owner.lookup('route:serve');
9 | assert.ok(route);
10 | });
11 | });
12 |
--------------------------------------------------------------------------------
/tests/unit/routes/test-test.js:
--------------------------------------------------------------------------------
1 | import { module, test } from 'qunit';
2 | import { setupTest } from 'ember-qunit';
3 |
4 | module('Unit | Route | test', function(hooks) {
5 | setupTest(hooks);
6 |
7 | test('it exists', function(assert) {
8 | let route = this.owner.lookup('route:test');
9 | assert.ok(route);
10 | });
11 | });
12 |
--------------------------------------------------------------------------------
/tests/unit/services/project-test.js:
--------------------------------------------------------------------------------
1 | import { module, test } from 'qunit';
2 | import { setupTest } from 'ember-qunit';
3 |
4 | module('Unit | Service | project', function(hooks) {
5 | setupTest(hooks);
6 |
7 | // TODO: Replace this with your real tests.
8 | test('it exists', function(assert) {
9 | let service = this.owner.lookup('service:project');
10 | assert.ok(service);
11 | });
12 | });
13 |
--------------------------------------------------------------------------------
/tests/unit/services/terminal-test.js:
--------------------------------------------------------------------------------
1 | import { module, test } from 'qunit';
2 | import { setupTest } from 'ember-qunit';
3 |
4 | module('Unit | Service | terminal', function(hooks) {
5 | setupTest(hooks);
6 |
7 | // TODO: Replace this with your real tests.
8 | test('it exists', function(assert) {
9 | let service = this.owner.lookup('service:terminal');
10 | assert.ok(service);
11 | });
12 | });
13 |
--------------------------------------------------------------------------------
/vendor/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rajasegar/ember-cli-ui/77489c814f0b99b4984f304049ff6da55a5b1d63/vendor/.gitkeep
--------------------------------------------------------------------------------