diff --git a/.bowerrc b/.bowerrc
new file mode 100644
index 00000000..0c16bd5a
--- /dev/null
+++ b/.bowerrc
@@ -0,0 +1,3 @@
+{
+ "directory": "browser/vendor/"
+}
diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 00000000..548af57f
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,3 @@
+[submodule "browser/ace"]
+ path = browser/ace
+ url = https://github.com/ajaxorg/ace-builds.git
diff --git a/Gulpfile.js b/Gulpfile.js
deleted file mode 100644
index 405da03b..00000000
--- a/Gulpfile.js
+++ /dev/null
@@ -1,129 +0,0 @@
-var gulp = require('gulp')
-var styl = require('gulp-stylus')
-var autoprefixer = require('gulp-autoprefixer')
-var del = require('del')
-var runSequence = require('run-sequence')
-var plumber = require('gulp-plumber')
-var notify = require('gulp-notify')
-var rename = require('gulp-rename')
-var livereload = require('gulp-livereload')
-var inject = require('gulp-inject')
-
-// for Dist
-var rev = require('gulp-rev')
-var ngAnnotate = require('gulp-ng-annotate')
-var templateCache = require('gulp-angular-templatecache')
-var uglify = require('gulp-uglify')
-var minifyCss = require('gulp-minify-css')
-var merge = require('merge-stream')
-var concat = require('gulp-concat')
-var minifyHtml = require('gulp-minify-html')
-
-var config = require('./build.config.js')
-
-gulp.task('build', function () {
- var tpls = gulp.src(['src/browser/main/**/*.html','!src/browser/main/index.html','!src/browser/main/index.inject.html'])
- .pipe(templateCache({}))
- .pipe(concat('tpls.js'))
- .pipe(ngAnnotate())
- .pipe(uglify())
- .pipe(gulp.dest('build'))
- var js = gulp.src(['src/browser/main/**/*.js', 'src/browser/shared/**/*.js'])
- .pipe(concat('app.js'))
- .pipe(ngAnnotate())
- .pipe(uglify())
- .pipe(gulp.dest('build'))
- var css = gulp.src(['src/browser/main/**/*.css', 'src/browser/shared/**/*.css'])
- .pipe(concat('all.css'))
- .pipe(minifyCss())
- .pipe(gulp.dest('build'))
- return merge(tpls, js, css)
-})
-
-gulp.task('vendor', function () {
- var vendors = config.vendors
-
- var vendorFiles = vendors.map(function (vendor) {
- return vendor.src
- })
-
- vendorFiles.push('node_modules/font-awesome/**/font-awesome.css')
- vendorFiles.push('node_modules/font-awesome/**/fontawesome-webfont.*')
- vendorFiles.push('node_modules/font-awesome/**/FontAwesome.*')
-
- return gulp.src(vendorFiles)
- .pipe(gulp.dest('src/browser/vendor'))
-})
-
-gulp.task('styl', function () {
- return gulp.src('src/browser/main/styles/app.styl')
- .pipe(plumber({errorHandler: notify.onError('Error: <%= error.message %>')}))
- .pipe(styl())
- .pipe(autoprefixer())
- .pipe(gulp.dest('src/browser/main/styles/'))
- .pipe(livereload())
- .pipe(notify('Stylus!!'))
-})
-
-gulp.task('styl-popup', function () {
- return gulp.src('src/browser/popup/styles/app.styl')
- .pipe(plumber({errorHandler: notify.onError('Error: <%= error.message %>')}))
- .pipe(styl())
- .pipe(autoprefixer())
- .pipe(gulp.dest('src/browser/popup/styles/'))
- .pipe(livereload())
- .pipe(notify('Stylus!! @POPUP'))
-})
-
-gulp.task('bs', function () {
- return gulp.src('src/browser/shared/styles/bootstrap.styl')
- .pipe(plumber({errorHandler: notify.onError('Error: <%= error.message %>')}))
- .pipe(styl())
- .pipe(autoprefixer())
- .pipe(gulp.dest('src/browser/shared/styles'))
- .pipe(notify('Bootstrap compiled!!'))
- .pipe(livereload())
-})
-
-gulp.task('inject', function (cb) {
- runSequence(['inject-main', 'inject-popup'], cb)
-})
-
-gulp.task('inject-main', function () {
- return gulp.src('src/browser/main/index.inject.html')
- .pipe(inject(gulp.src(['src/browser/main/**/*.js', 'src/browser/main/**/*.css', 'src/browser/shared/**/*.js', 'src/browser/shared/**/*.css'], {read: false}), {
- relative: true
- }))
- .pipe(rename(function (path) {
- path.basename = 'index'
- }))
- .pipe(gulp.dest('src/browser/main/'))
-})
-
-gulp.task('watch-main', function () {
- gulp.watch(
- ['src/browser/main/index.inject.html', 'src/browser/main/**/*.js', 'src/browser/main/**/*.css', 'src/browser/shared/**/*.js', 'src/browser/shared/**/*.css'], ['inject-main'])
-
- gulp.watch('src/browser/main/styles/**/*.styl', ['styl'])
- gulp.watch('src/browser/popup/styles/**/*.styl', ['styl-popup'])
- gulp.watch('src/browser/shared/styles/**/*.styl', ['bs'])
- livereload.listen()
-})
-gulp.task('inject-popup', function () {
- return gulp.src('src/browser/popup/index.inject.html')
- .pipe(inject(gulp.src(['src/browser/popup/**/*.js', 'src/browser/popup/**/*.css', 'src/browser/shared/**/*.js', 'src/browser/shared/**/*.css'], {read: false}), {
- relative: true
- }))
- .pipe(rename(function (path) {
- path.basename = 'index'
- }))
- .pipe(gulp.dest('src/browser/popup/'))
-})
-
-gulp.task('del', function (cb) {
- del(['build/**/*'], cb)
-})
-
-gulp.task('default', function (cb) {
- runSequence('del', 'build', 'watch', cb)
-})
diff --git a/bower.json b/bower.json
new file mode 100644
index 00000000..85708203
--- /dev/null
+++ b/bower.json
@@ -0,0 +1,11 @@
+{
+ "name": "codexen-app",
+ "dependencies": {
+ "react": "~0.13.3",
+ "fontawesome": "~4.3.0",
+ "react-router": "~0.13.3",
+ "reflux": "~0.2.8",
+ "moment": "~2.10.3",
+ "markdown-it": "~4.3.1"
+ }
+}
diff --git a/browser/finder/Components/FinderDetail.jsx b/browser/finder/Components/FinderDetail.jsx
new file mode 100644
index 00000000..0f610d6c
--- /dev/null
+++ b/browser/finder/Components/FinderDetail.jsx
@@ -0,0 +1,43 @@
+var React = require('react/addons')
+
+var CodeViewer = require('../../main/Components/CodeViewer')
+
+var Markdown = require('../../main/Mixins/Markdown')
+
+module.exports = React.createClass({
+ mixins: [Markdown],
+ propTypes: {
+ currentArticle: React.PropTypes.object
+ },
+ render: function () {
+ var article = this.props.currentArticle
+
+ if (article != null) {
+ if (article.type === 'code') {
+ return (
+
+
{article.description}
+
+
+
+
+ )
+ } else if (article.type === 'note') {
+
+ return (
+
+ )
+ }
+ }
+ return (
+
+ )
+ }
+})
diff --git a/browser/finder/Components/FinderInput.jsx b/browser/finder/Components/FinderInput.jsx
new file mode 100644
index 00000000..467d5a40
--- /dev/null
+++ b/browser/finder/Components/FinderInput.jsx
@@ -0,0 +1,15 @@
+var React = require('react/addons')
+
+module.exports = React.createClass({
+ propTypes: {
+ onChange: React.PropTypes.func,
+ search: React.PropTypes.string
+ },
+ render: function () {
+ return (
+
+
+
+ )
+ }
+})
diff --git a/browser/finder/Components/FinderList.jsx b/browser/finder/Components/FinderList.jsx
new file mode 100644
index 00000000..5b3898f3
--- /dev/null
+++ b/browser/finder/Components/FinderList.jsx
@@ -0,0 +1,79 @@
+var React = require('react/addons')
+
+module.exports = React.createClass({
+ propTypes: {
+ articles: React.PropTypes.arrayOf,
+ currentArticle: React.PropTypes.shape({
+ id: React.PropTypes.number,
+ type: React.PropTypes.string
+ }),
+ selectArticle: React.PropTypes.func
+ },
+ componentDidUpdate: function () {
+ var index = this.props.articles.indexOf(this.props.currentArticle)
+ var el = React.findDOMNode(this)
+ var li = el.querySelectorAll('li')[index]
+
+ if (li == null) {
+ return
+ }
+
+ var overflowBelow = el.clientHeight + el.scrollTop < li.offsetTop + li.clientHeight
+ if (overflowBelow) {
+ el.scrollTop = li.offsetTop + li.clientHeight - el.clientHeight
+ }
+ var overflowAbove = el.scrollTop > li.offsetTop
+ if (overflowAbove) {
+ el.scrollTop = li.offsetTop
+ }
+ },
+ handleArticleClick: function (article) {
+ return function () {
+ this.props.selectArticle(article)
+ }.bind(this)
+ },
+ render: function () {
+ var list = this.props.articles.map(function (article) {
+ if (article == null) {
+ return (
+
+ Undefined
+
+
+ )
+ }
+
+ var isActive = this.props.currentArticle != null && (article.type === this.props.currentArticle.type && article.id === this.props.currentArticle.id)
+ if (article.type === 'code') {
+ return (
+
+ {article.description}
+
+
+ )
+ }
+ if (article.type === 'note') {
+ return (
+
+ {article.title}
+
+
+ )
+ }
+ return (
+
+ Undefined
+
+
+ )
+ }.bind(this))
+
+ return (
+
+ )
+ }
+})
diff --git a/browser/finder/favicon.ico b/browser/finder/favicon.ico
new file mode 100644
index 00000000..ad6a19a4
Binary files /dev/null and b/browser/finder/favicon.ico differ
diff --git a/browser/finder/index.electron.html b/browser/finder/index.electron.html
new file mode 100644
index 00000000..b0602b39
--- /dev/null
+++ b/browser/finder/index.electron.html
@@ -0,0 +1,62 @@
+
+
+
+
+ CodeXen Popup
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/browser/finder/index.html b/browser/finder/index.html
new file mode 100644
index 00000000..e69de29b
diff --git a/browser/finder/index.jsx b/browser/finder/index.jsx
new file mode 100644
index 00000000..9cde1c0d
--- /dev/null
+++ b/browser/finder/index.jsx
@@ -0,0 +1,134 @@
+/* global localStorage */
+var remote = require('remote')
+var hideFinder = remote.getGlobal('hideFinder')
+var clipboard = require('clipboard')
+
+var React = require('react/addons')
+
+var ArticleFilter = require('../main/Mixins/ArticleFilter')
+
+var FinderInput = require('./Components/FinderInput')
+var FinderList = require('./Components/FinderList')
+var FinderDetail = require('./Components/FinderDetail')
+
+// Filter end
+
+function fetchArticles () {
+ var user = JSON.parse(localStorage.getItem('currentUser'))
+ if (user == null) {
+ console.log('need to login')
+ return []
+ }
+
+ var articles = []
+ user.Planets.forEach(function (planet) {
+ var _planet = JSON.parse(localStorage.getItem('planet-' + planet.id))
+ articles = articles.concat(_planet.Codes, _planet.Notes)
+ })
+ user.Teams.forEach(function (team) {
+ team.Planets.forEach(function (planet) {
+ var _planet = JSON.parse(localStorage.getItem('planet-' + planet.id))
+ articles = articles.concat(_planet.Codes, _planet.Notes)
+ })
+ })
+
+ return articles
+}
+
+var Finder = React.createClass({
+ mixins: [ArticleFilter],
+ getInitialState: function () {
+ var articles = fetchArticles()
+ return {
+ articles: articles,
+ currentArticle: articles[0],
+ search: ''
+ }
+ },
+ componentDidMount: function () {
+ document.addEventListener('keydown', this.handleKeyDown)
+ document.addEventListener('click', this.handleClick)
+ window.addEventListener('focus', this.handleFinderFocus)
+ },
+ componentWillUnmount: function () {
+ document.removeEventListener('keydown', this.handleKeyDown)
+ document.removeEventListener('click', this.handleClick)
+ window.removeEventListener('focus', this.handleFinderFocus)
+ },
+ handleFinderFocus: function () {
+ console.log('focusseeddddd')
+ this.focusInput()
+ var articles = fetchArticles()
+ this.setState({
+ articles: articles,
+ search: ''
+ }, function () {
+ var firstArticle = this.refs.finderList.props.articles[0]
+ if (firstArticle) {
+ this.setState({
+ currentArticle: firstArticle
+ })
+ }
+ })
+ },
+ handleKeyDown: function (e) {
+ if (e.keyCode === 38) {
+ this.selectPrevious()
+ e.preventDefault()
+ }
+
+ if (e.keyCode === 40) {
+ this.selectNext()
+ e.preventDefault()
+ }
+
+ if (e.keyCode === 13) {
+ var article = this.state.currentArticle
+ clipboard.writeText(article.content)
+ hideFinder()
+ e.preventDefault()
+ }
+ if (e.keyCode === 27) {
+ hideFinder()
+ e.preventDefault()
+ }
+ },
+ focusInput: function () {
+ React.findDOMNode(this.refs.finderInput).querySelector('input').focus()
+ },
+ handleClick: function () {
+ this.focusInput()
+ },
+ selectPrevious: function () {
+ var index = this.refs.finderList.props.articles.indexOf(this.state.currentArticle)
+ if (index > 0) {
+ this.setState({currentArticle: this.refs.finderList.props.articles[index - 1]})
+ }
+ },
+ selectNext: function () {
+ var index = this.refs.finderList.props.articles.indexOf(this.state.currentArticle)
+ if (index > -1 && index < this.refs.finderList.props.articles.length - 1) {
+ this.setState({currentArticle: this.refs.finderList.props.articles[index + 1]})
+ }
+ },
+ selectArticle: function (article) {
+ this.setState({currentArticle: article})
+ },
+ handleChange: function (e) {
+ this.setState({search: e.target.value}, function () {
+ this.setState({currentArticle: this.refs.finderList.props.articles[0]})
+ })
+ },
+ render: function () {
+ var articles = this.searchArticle(this.state.search, this.state.articles)
+ return (
+
+
+
+
+
+ )
+ }
+})
+
+React.render(, document.getElementById('content'))
diff --git a/browser/index.html b/browser/index.html
new file mode 100644
index 00000000..cbb53cad
--- /dev/null
+++ b/browser/index.html
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+ Go Main
+ Go Popup
+
+
diff --git a/browser/main/Components/AboutModal.jsx b/browser/main/Components/AboutModal.jsx
new file mode 100644
index 00000000..53ffc253
--- /dev/null
+++ b/browser/main/Components/AboutModal.jsx
@@ -0,0 +1,32 @@
+var remote = require('remote')
+var version = remote.getGlobal('version')
+
+var React = require('react/addons')
+
+var ExternalLink = require('../Mixins/ExternalLink')
+
+module.exports = React.createClass({
+ mixins: [ExternalLink],
+ propTypes: {
+ close: React.PropTypes.func
+ },
+ render: function () {
+ return (
+
+
+

+
Boost {version == null || version.length === 0 ? 'DEV version' : 'v' + version}
+
+
+
+
+ )
+ }
+})
diff --git a/browser/main/Components/AddMemberModal.jsx b/browser/main/Components/AddMemberModal.jsx
new file mode 100644
index 00000000..e96f2b47
--- /dev/null
+++ b/browser/main/Components/AddMemberModal.jsx
@@ -0,0 +1,83 @@
+var React = require('react/addons')
+var Select = require('react-select')
+
+var LinkedState = require('../Mixins/LinkedState')
+
+var Hq = require('../Services/Hq')
+
+var UserStore = require('../Stores/UserStore')
+
+var getOptions = function (input, callback) {
+ Hq.searchUser(input)
+ .then(function (res) {
+ callback(null, {
+ options: res.body.map(function (user) {
+ return {
+ label: user.name,
+ value: user.name
+ }
+ }),
+ complete: false
+ })
+ })
+ .catch(function (err) {
+ console.error(err)
+ })
+}
+
+module.exports = React.createClass({
+ mixins: [LinkedState],
+ propTypes: {
+ team: React.PropTypes.object,
+ close: React.PropTypes.func
+ },
+ getInitialState: function () {
+ return {
+ userName: '',
+ role: 'member'
+ }
+ },
+ handleSubmit: function () {
+ Hq
+ .addMember(this.props.team.name, {
+ userName: this.state.userName,
+ role: this.state.role
+ })
+ .then(function (res) {
+ console.log(res.body)
+ UserStore.Actions.addMember(res.body)
+ this.props.close()
+ }.bind(this))
+ .catch(function (err) {
+ console.error(err)
+ })
+ },
+ handleChange: function (value) {
+ this.setState({userName: value})
+ },
+ render: function () {
+ return (
+
+
+
+
+ Add member as
+
+ role
+
+
+
+
+ )
+ }
+})
diff --git a/browser/main/Components/CodeDeleteModal.jsx b/browser/main/Components/CodeDeleteModal.jsx
new file mode 100644
index 00000000..dd9503bf
--- /dev/null
+++ b/browser/main/Components/CodeDeleteModal.jsx
@@ -0,0 +1,48 @@
+var React = require('react')
+
+var Hq = require('../Services/Hq')
+
+var PlanetStore = require('../Stores/PlanetStore')
+
+module.exports = React.createClass({
+ propTypes: {
+ planet: React.PropTypes.object,
+ code: React.PropTypes.object,
+ close: React.PropTypes.func
+ },
+ componentDidMount: function () {
+ React.findDOMNode(this).focus()
+ },
+ stopPropagation: function (e) {
+ e.stopPropagation()
+ },
+ submit: function () {
+ var planet = this.props.planet
+ Hq.destroyCode(planet.userName, planet.name, this.props.code.localId)
+ .then(function (res) {
+ PlanetStore.Actions.destroyCode(res.body)
+ this.props.close()
+ }.bind(this))
+ .catch(function (err) {
+ console.error(err)
+ })
+ },
+ render: function () {
+ return (
+
+
+
Delete Code
+
+
+
Are you sure to delete it?
+
+
+
+ )
+ }
+})
diff --git a/browser/main/Components/CodeEditModal.jsx b/browser/main/Components/CodeEditModal.jsx
new file mode 100644
index 00000000..8877cafa
--- /dev/null
+++ b/browser/main/Components/CodeEditModal.jsx
@@ -0,0 +1,20 @@
+var React = require('react')
+var CodeForm = require('./CodeForm')
+
+module.exports = React.createClass({
+ propTypes: {
+ close: React.PropTypes.func,
+ code: React.PropTypes.object,
+ planet: React.PropTypes.object
+ },
+ render: function () {
+ return (
+
+ )
+ }
+})
diff --git a/browser/main/Components/CodeEditor.jsx b/browser/main/Components/CodeEditor.jsx
new file mode 100644
index 00000000..6cf3a4a7
--- /dev/null
+++ b/browser/main/Components/CodeEditor.jsx
@@ -0,0 +1,58 @@
+var React = require('react/addons')
+
+var ace = window.ace
+
+module.exports = React.createClass({
+ propTypes: {
+ code: React.PropTypes.string,
+ mode: React.PropTypes.string,
+ onChange: React.PropTypes.func
+ },
+ componentDidMount: function () {
+ var el = React.findDOMNode(this.refs.target)
+ var editor = ace.edit(el)
+ editor.$blockScrolling = Infinity
+ editor.setValue(this.props.code)
+ editor.renderer.setShowGutter(true)
+ editor.setTheme('ace/theme/xcode')
+ editor.clearSelection()
+
+ var session = editor.getSession()
+ if (this.props.mode != null && this.props.mode.length > 0) {
+ session.setMode('ace/mode/' + this.props.mode)
+ } else {
+ session.setMode('ace/mode/text')
+ }
+ session.setUseSoftTabs(true)
+ session.setOption('useWorker', false)
+ session.setUseWrapMode(true)
+
+ session.on('change', function (e) {
+ if (this.props.onChange != null) {
+ var value = editor.getValue()
+ this.props.onChange(e, value)
+ }
+ }.bind(this))
+
+ this.setState({editor: editor})
+ },
+ componentDidUpdate: function (prevProps) {
+ if (this.state.editor.getValue() !== this.props.code) {
+ this.state.editor.setValue(this.props.code)
+ this.state.editor.clearSelection()
+ }
+ if (prevProps.mode !== this.props.mode) {
+ var session = this.state.editor.getSession()
+ if (this.props.mode != null && this.props.mode.length > 0) {
+ session.setMode('ace/mode/' + this.props.mode)
+ } else {
+ session.setMode('ace/mode/text')
+ }
+ }
+ },
+ render: function () {
+ return (
+
+ )
+ }
+})
diff --git a/browser/main/Components/CodeForm.jsx b/browser/main/Components/CodeForm.jsx
new file mode 100644
index 00000000..e80dc6af
--- /dev/null
+++ b/browser/main/Components/CodeForm.jsx
@@ -0,0 +1,151 @@
+var React = require('react/addons')
+var CodeEditor = require('./CodeEditor')
+var Select = require('react-select')
+
+var Hq = require('../Services/Hq')
+
+var LinkedState = require('../Mixins/LinkedState')
+
+var PlanetStore = require('../Stores/PlanetStore')
+
+var aceModes = require('../../../modules/ace-modes')
+
+var getOptions = function (input, callback) {
+ Hq.searchTag(input)
+ .then(function (res) {
+ callback(null, {
+ options: res.body.map(function (tag) {
+ return {
+ label: tag.name,
+ value: tag.name
+ }
+ }),
+ complete: false
+ })
+ })
+ .catch(function (err) {
+ console.log(err)
+ })
+}
+
+module.exports = React.createClass({
+ mixins: [LinkedState],
+ propTypes: {
+ planet: React.PropTypes.object,
+ close: React.PropTypes.func,
+ transitionTo: React.PropTypes.func,
+ code: React.PropTypes.object
+ },
+ getInitialState: function () {
+ var code = Object.assign({
+ description: '',
+ mode: '',
+ content: '',
+ Tags: []
+ }, this.props.code)
+
+ code.Tags = code.Tags.map(function (tag) {
+ return {
+ label: tag.name,
+ value: tag.name
+ }
+ })
+
+ return {
+ code: code
+ }
+ },
+ handleModeChange: function (selected) {
+ var code = this.state.code
+ code.mode = selected
+ this.setState({code: code})
+ },
+ handleTagsChange: function (selected, all) {
+ var code = this.state.code
+ code.Tags = all
+ this.setState({code: code})
+ },
+ handleContentChange: function (e, value) {
+ var code = this.state.code
+ code.content = value
+ this.setState({code: code})
+ },
+ submit: function () {
+ var planet = this.props.planet
+ var code = this.state.code
+ code.Tags = code.Tags.map(function (tag) {
+ return tag.value
+ })
+ if (this.props.code == null) {
+ Hq.createCode(planet.userName, planet.name, this.state.code)
+ .then(function (res) {
+ var code = res.body
+ PlanetStore.Actions.updateCode(code)
+ this.props.close()
+ this.props.transitionTo('codes', {userName: planet.userName, planetName: planet.name, localId: code.localId})
+ }.bind(this))
+ .catch(function (err) {
+ console.error(err)
+ })
+ } else {
+ Hq.updateCode(planet.userName, planet.name, this.props.code.localId, this.state.code)
+ .then(function (res) {
+ var code = res.body
+ PlanetStore.Actions.updateCode(code)
+ this.props.close()
+ }.bind(this))
+ }
+ },
+ handleKeyDown: function (e) {
+ if (e.keyCode === 13 && e.metaKey) {
+ this.submit()
+ e.stopPropagation()
+ }
+ },
+ render: function () {
+ var modeOptions = aceModes.map(function (mode) {
+ return {
+ label: mode,
+ value: mode
+ }
+ })
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ )
+ }
+})
diff --git a/browser/main/Components/CodeViewer.jsx b/browser/main/Components/CodeViewer.jsx
new file mode 100644
index 00000000..bd20fe2f
--- /dev/null
+++ b/browser/main/Components/CodeViewer.jsx
@@ -0,0 +1,52 @@
+var React = require('react/addons')
+
+var ace = window.ace
+
+module.exports = React.createClass({
+ propTypes: {
+ code: React.PropTypes.string,
+ mode: React.PropTypes.string
+ },
+ componentDidMount: function () {
+ var el = React.findDOMNode(this.refs.target)
+ var editor = ace.edit(el)
+ editor.$blockScrolling = Infinity
+ editor.setValue(this.props.code)
+ editor.renderer.setShowGutter(false)
+ editor.setReadOnly(true)
+ editor.setTheme('ace/theme/xcode')
+ editor.setHighlightActiveLine(false)
+ editor.clearSelection()
+
+ var session = editor.getSession()
+ if (this.props.mode != null && this.props.mode.length > 0) {
+ session.setMode('ace/mode/' + this.props.mode)
+ } else {
+ session.setMode('ace/mode/text')
+ }
+ session.setUseSoftTabs(true)
+ session.setOption('useWorker', false)
+ session.setUseWrapMode(true)
+
+ this.setState({editor: editor})
+ },
+ componentDidUpdate: function (prevProps) {
+ if (this.state.editor.getValue() !== this.props.code) {
+ this.state.editor.setValue(this.props.code)
+ this.state.editor.clearSelection()
+ }
+ if (prevProps.mode !== this.props.mode) {
+ var session = this.state.editor.getSession()
+ if (this.props.mode != null && this.props.mode.length > 0) {
+ session.setMode('ace/mode/' + this.props.mode)
+ } else {
+ session.setMode('ace/mode/text')
+ }
+ }
+ },
+ render: function () {
+ return (
+
+ )
+ }
+})
diff --git a/browser/main/Components/ContactModal.jsx b/browser/main/Components/ContactModal.jsx
new file mode 100644
index 00000000..5fc7cc84
--- /dev/null
+++ b/browser/main/Components/ContactModal.jsx
@@ -0,0 +1,62 @@
+var React = require('react')
+
+var LinkedState = require('../Mixins/LinkedState')
+
+var Hq = require('../Services/Hq')
+
+module.exports = React.createClass({
+ mixins: [LinkedState],
+ propTypes: {
+ close: React.PropTypes.func
+ },
+ getInitialState: function () {
+ return {
+ isSent: false,
+ mail: {
+ title: '',
+ content: ''
+ }
+ }
+ },
+ sendEmail: function () {
+ Hq.sendEmail(this.state.mail)
+ .then(function (res) {
+ this.setState({isSent: !this.state.isSent})
+ }.bind(this))
+ .catch(function (err) {
+ console.error(err)
+ })
+ },
+ render: function () {
+ return (
+
+
Contact form
+
+ {!this.state.isSent ? (
+
+ ) : (
+
+
Thanks for sharing your opinion!
+
+
+ )}
+
+ )
+ }
+})
diff --git a/browser/main/Components/EditProfileModal.jsx b/browser/main/Components/EditProfileModal.jsx
new file mode 100644
index 00000000..cf9e8c86
--- /dev/null
+++ b/browser/main/Components/EditProfileModal.jsx
@@ -0,0 +1,162 @@
+/* global localStorage */
+
+var React = require('react/addons')
+
+var Hq = require('../Services/Hq')
+
+var LinkedState = require('../Mixins/LinkedState')
+
+var UserStore = require('../Stores/UserStore')
+
+module.exports = React.createClass({
+ mixins: [LinkedState],
+ propTypes: {
+ user: React.PropTypes.shape({
+ name: React.PropTypes.string,
+ profileName: React.PropTypes.string,
+ email: React.PropTypes.string
+ })
+ },
+ getInitialState: function () {
+ var user = this.props.user
+ return {
+ currentTab: 'userInfo',
+ user: {
+ profileName: user.profileName,
+ email: user.email
+ },
+ userSubmitStatus: null,
+ password: {
+ currentPassword: '',
+ newPassword: '',
+ passwordConfirmation: ''
+ },
+ passwordSubmitStatus: null
+ }
+ },
+ selectTab: function (tabName) {
+ return function () {
+ this.setState({currentTab: tabName})
+ }.bind(this)
+ },
+ saveUserInfo: function () {
+ this.setState({
+ userSubmitStatus: 'sending'
+ }, function () {
+ Hq.updateUser(this.props.user.name, this.state.user)
+ .then(function (res) {
+ this.setState({userSubmitStatus: 'done'}, function () {
+ localStorage.setItem('currentUser', JSON.stringify(res.body))
+ UserStore.Actions.update(res.body)
+ })
+ }.bind(this))
+ .catch(function (err) {
+ console.error(err)
+ this.setState({userSubmitStatus: 'error'})
+ }.bind(this))
+ })
+ },
+ savePassword: function () {
+ this.setState({
+ passwordSubmitStatus: 'sending'
+ }, function () {
+ console.log(this.state.password)
+ Hq.changePassword(this.state.password)
+ .then(function (res) {
+ this.setState({
+ passwordSubmitStatus: 'done',
+ currentPassword: '',
+ newPassword: '',
+ passwordConfirmation: ''
+ })
+ }.bind(this))
+ .catch(function (err) {
+ console.error(err)
+ this.setState({
+ passwordSubmitStatus: 'error',
+ currentPassword: '',
+ newPassword: '',
+ passwordConfirmation: ''
+ })
+ }.bind(this))
+ })
+ },
+ render: function () {
+ var content
+
+ switch (this.state.currentTab) {
+ case 'userInfo':
+ content = this.renderUserInfoTab()
+ break
+ case 'password':
+ content = this.renderPasswordTab()
+ break
+ }
+
+ return (
+
+
+
Edit profile
+
+
+
+
+
+
+ {content}
+
+
+ )
+ },
+ renderUserInfoTab: function () {
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
on Sending...
+
+
Connection failed.. Try again.
+
+
Successfully done!!
+
+
+ )
+ },
+ renderPasswordTab: function () {
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
on Sending...
+
+
Connection failed.. Try again.
+
+
Successfully done!!
+
+
+ )
+ }
+})
diff --git a/browser/main/Components/HomeNavigator.jsx b/browser/main/Components/HomeNavigator.jsx
new file mode 100644
index 00000000..462853ed
--- /dev/null
+++ b/browser/main/Components/HomeNavigator.jsx
@@ -0,0 +1,188 @@
+/* global localStorage */
+
+var React = require('react/addons')
+var ReactRouter = require('react-router')
+var Navigation = ReactRouter.Navigation
+var State = ReactRouter.State
+var Link = ReactRouter.Link
+var Reflux = require('reflux')
+
+var Modal = require('../Mixins/Modal')
+
+var UserStore = require('../Stores/UserStore')
+
+var AboutModal = require('./AboutModal')
+var PlanetCreateModal = require('./PlanetCreateModal')
+var TeamCreateModal = require('./TeamCreateModal')
+var LogoutModal = require('./LogoutModal')
+var ProfileImage = require('./ProfileImage')
+
+module.exports = React.createClass({
+ mixins: [Navigation, State, Reflux.listenTo(UserStore, 'onUserChange'), Modal],
+ getInitialState: function () {
+ return {
+ isPlanetCreateModalOpen: false,
+ currentUser: JSON.parse(localStorage.getItem('currentUser'))
+ }
+ },
+ onUserChange: function (res) {
+ switch (res.status) {
+ case 'userUpdated':
+ var user = res.data
+ var currentUser = this.state.currentUser
+ if (currentUser.id === user.id) {
+ this.setState({currentUser: user})
+ return
+ }
+
+ if (user.userType === 'team') {
+ var isMyTeam = user.Members.some(function (member) {
+ if (currentUser.id === member.id) {
+ return true
+ }
+ return false
+ })
+
+ if (isMyTeam) {
+ var isNew = !currentUser.Teams.some(function (team, index) {
+ if (user.id === team.id) {
+ currentUser.Teams.splice(index, 1, user)
+ return true
+ }
+ return false
+ })
+
+ if (isNew) {
+ currentUser.Teams.push(user)
+ }
+
+ this.setState({currentUser: currentUser})
+ }
+ }
+ break
+ }
+ },
+ openTeamCreateModal: function () {
+ this.openModal(TeamCreateModal, {user: this.state.currentUser, transitionTo: this.transitionTo})
+ },
+ openAboutModal: function () {
+ this.openModal(AboutModal)
+ },
+ openPlanetCreateModal: function () {
+ this.openModal(PlanetCreateModal, {transitionTo: this.transitionTo})
+ },
+ handleKeyDown: function (e) {
+ if (this.state.currentUser == null) return
+ if (e.metaKey && e.keyCode > 48 && e.keyCode < 58) {
+ var planet = this.state.currentUser.Planets[e.keyCode - 49]
+ if (planet != null) {
+ this.transitionTo('planet', {userName: planet.userName, planetName: planet.name})
+ }
+ e.preventDefault()
+ }
+ },
+ toggleProfilePopup: function () {
+ this.openProfilePopup()
+ },
+ openProfilePopup: function () {
+ this.setState({isProfilePopupOpen: true}, function () {
+ document.addEventListener('click', this.closeProfilePopup)
+ })
+ },
+ closeProfilePopup: function () {
+ document.removeEventListener('click', this.closeProfilePopup)
+ this.setState({isProfilePopupOpen: false})
+ },
+ handleLogoutClick: function () {
+ this.openModal(LogoutModal, {transitionTo: this.transitionTo})
+ },
+ render: function () {
+ var params = this.getParams()
+
+ if (this.state.currentUser == null) {
+ return (
+
+
+ )
+ }
+
+ var planets = (this.state.currentUser.Planets.concat(this.state.currentUser.Teams.reduce(function (planets, team) {
+ return team.Planets == null ? planets : planets.concat(team.Planets)
+ }, []))).map(function (planet, index) {
+ return (
+
+
+ {planet.name[0]}
+ {planet.userName}/{planet.name}
+
+ ⌘{index + 1}
+
+ )
+ })
+
+ var popup = this.renderPopup()
+
+ return (
+
+
+ {popup}
+
+
+
+ )
+ },
+ renderPopup: function () {
+ var teams = this.state.currentUser.Teams == null ? [] : this.state.currentUser.Teams.map(function (team) {
+ return (
+
+ {team.profileName} ({team.name})
+
+
+ )
+ })
+
+ return (
+
+
+
+ You
+
+
+ -
+ Profile ({this.state.currentUser.name})
+
+
+
+
+
+
+
+ Team
+
+
+ {teams}
+ -
+
+
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+ )
+ }
+})
diff --git a/browser/main/Components/LaunchModal.jsx b/browser/main/Components/LaunchModal.jsx
new file mode 100644
index 00000000..649404db
--- /dev/null
+++ b/browser/main/Components/LaunchModal.jsx
@@ -0,0 +1,60 @@
+var React = require('react/addons')
+
+var CodeForm = require('./CodeForm')
+var NoteForm = require('./NoteForm')
+
+module.exports = React.createClass({
+ propTypes: {
+ planet: React.PropTypes.object,
+ transitionTo: React.PropTypes.func,
+ close: React.PropTypes.func
+ },
+ getInitialState: function () {
+ return {
+ currentTab: 'code'
+ }
+ },
+ componentDidMount: function () {
+
+ },
+ stopPropagation: function (e) {
+ e.stopPropagation()
+ },
+ selectCodeTab: function () {
+ this.setState({currentTab: 'code'})
+ },
+ selectNoteTab: function () {
+ this.setState({currentTab: 'note'})
+ },
+ handleKeyDown: function (e) {
+ if (e.keyCode === 37 && e.metaKey) {
+ this.selectCodeTab()
+ }
+ if (e.keyCode === 39 && e.metaKey) {
+ this.selectNoteTab()
+ }
+ },
+ render: function () {
+ var modalBody
+ if (this.state.currentTab === 'code') {
+ modalBody = (
+
+ )
+ } else {
+ modalBody = (
+
+ )
+ }
+
+ return (
+
+ )
+ }
+})
diff --git a/browser/main/Components/LogoutModal.jsx b/browser/main/Components/LogoutModal.jsx
new file mode 100644
index 00000000..9a6e542d
--- /dev/null
+++ b/browser/main/Components/LogoutModal.jsx
@@ -0,0 +1,27 @@
+/* global localStorage */
+
+var React = require('react')
+
+module.exports = React.createClass({
+ propTypes: {
+ transitionTo: React.PropTypes.func,
+ close: React.PropTypes.func
+ },
+ logout: function () {
+ localStorage.removeItem('currentUser')
+ localStorage.removeItem('token')
+ this.props.transitionTo('login')
+ this.props.close()
+ },
+ render: function () {
+ return (
+
+
Are you sure to log out?
+
+
+
+
+
+ )
+ }
+})
diff --git a/browser/main/Components/MarkdownPreview.jsx b/browser/main/Components/MarkdownPreview.jsx
new file mode 100644
index 00000000..80df45c5
--- /dev/null
+++ b/browser/main/Components/MarkdownPreview.jsx
@@ -0,0 +1,43 @@
+var React = require('react')
+
+var Markdown = require('../Mixins/Markdown')
+var ExternalLink = require('../Mixins/ExternalLink')
+
+module.exports = React.createClass({
+ mixins: [Markdown, ExternalLink],
+ propTypes: {
+ className: React.PropTypes.string,
+ content: React.PropTypes.string
+ },
+ componentDidMount: function () {
+ this.addListener()
+ },
+ componentDidUpdate: function () {
+ this.addListener()
+ },
+ componentWillUnmount: function () {
+ this.removeListener()
+ },
+ componentWillUpdate: function () {
+ this.removeListener()
+ },
+ addListener: function () {
+ var anchors = React.findDOMNode(this).querySelectorAll('a')
+
+ for (var i = 0; i < anchors.length; i++) {
+ anchors[i].addEventListener('click', this.openExternal)
+ }
+ },
+ removeListener: function () {
+ var anchors = React.findDOMNode(this).querySelectorAll('a')
+
+ for (var i = 0; i < anchors.length; i++) {
+ anchors[i].removeEventListener('click', this.openExternal)
+ }
+ },
+ render: function () {
+ return (
+
+ )
+ }
+})
diff --git a/browser/main/Components/NoteDeleteModal.jsx b/browser/main/Components/NoteDeleteModal.jsx
new file mode 100644
index 00000000..841b5291
--- /dev/null
+++ b/browser/main/Components/NoteDeleteModal.jsx
@@ -0,0 +1,45 @@
+var React = require('react')
+
+var Hq = require('../Services/Hq')
+
+var PlanetStore = require('../Stores/PlanetStore')
+
+module.exports = React.createClass({
+ propTypes: {
+ planet: React.PropTypes.object,
+ note: React.PropTypes.object,
+ close: React.PropTypes.func
+ },
+ componentDidMount: function () {
+ React.findDOMNode(this).focus()
+ },
+ submit: function () {
+ var planet = this.props.planet
+ Hq.destroyNote(planet.userName, planet.name, this.props.note.localId)
+ .then(function (res) {
+ PlanetStore.Actions.destroyNote(res.body)
+ this.props.close()
+ }.bind(this))
+ .catch(function (err) {
+ console.error(err)
+ })
+ },
+ render: function () {
+ return (
+
+
+
Delete Note
+
+
+
Are you sure to delete it?
+
+
+
+ )
+ }
+})
diff --git a/browser/main/Components/NoteEditModal.jsx b/browser/main/Components/NoteEditModal.jsx
new file mode 100644
index 00000000..458b57ea
--- /dev/null
+++ b/browser/main/Components/NoteEditModal.jsx
@@ -0,0 +1,21 @@
+var React = require('react')
+
+var NoteForm = require('./NoteForm')
+
+module.exports = React.createClass({
+ propTypes: {
+ close: React.PropTypes.func,
+ note: React.PropTypes.object,
+ planet: React.PropTypes.object
+ },
+ render: function () {
+ return (
+
+ )
+ }
+})
diff --git a/browser/main/Components/NoteForm.jsx b/browser/main/Components/NoteForm.jsx
new file mode 100644
index 00000000..0f805dbb
--- /dev/null
+++ b/browser/main/Components/NoteForm.jsx
@@ -0,0 +1,146 @@
+var React = require('react/addons')
+var ReactRouter = require('react-router')
+var Select = require('react-select')
+
+var Hq = require('../Services/Hq')
+
+var LinkedState = require('../Mixins/LinkedState')
+var Markdown = require('../Mixins/Markdown')
+
+var PlanetStore = require('../Stores/PlanetStore')
+
+var CodeEditor = require('./CodeEditor')
+var MarkdownPreview = require('./MarkdownPreview')
+
+var getOptions = function (input, callback) {
+ Hq.searchTag(input)
+ .then(function (res) {
+ callback(null, {
+ options: res.body.map(function (tag) {
+ return {
+ label: tag.name,
+ value: tag.name
+ }
+ }),
+ complete: false
+ })
+ })
+ .catch(function (err) {
+ console.log(err)
+ })
+}
+
+var EDIT_MODE = 0
+var PREVIEW_MODE = 1
+
+module.exports = React.createClass({
+ mixins: [LinkedState, Markdown],
+ propTypes: {
+ planet: React.PropTypes.object,
+ close: React.PropTypes.func,
+ transitionTo: React.PropTypes.func,
+ note: React.PropTypes.object
+ },
+ getInitialState: function () {
+ var note = Object.assign({
+ title: '',
+ content: '',
+ Tags: []
+ }, this.props.note)
+ note.Tags = note.Tags.map(function (tag) {
+ return {
+ label: tag.name,
+ value: tag.name
+ }
+ })
+ return {
+ note: note,
+ mode: EDIT_MODE
+ }
+ },
+ componentDidMount: function () {
+ React.findDOMNode(this.refs.title).focus()
+ },
+ handleTagsChange: function (selected, all) {
+ var note = this.state.note
+ note.Tags = all
+ this.setState({note: note})
+ },
+ handleContentChange: function (e, value) {
+ var note = this.state.note
+ note.content = value
+ this.setState({note: note})
+ },
+ togglePreview: function () {
+ this.setState({mode: this.state.mode === EDIT_MODE ? PREVIEW_MODE : EDIT_MODE})
+ },
+ submit: function () {
+ var planet = this.props.planet
+ var note = this.state.note
+ note.Tags = note.Tags.map(function (tag) {
+ return tag.value
+ })
+
+ if (this.props.note == null) {
+ Hq.createNote(planet.userName, planet.name, this.state.note)
+ .then(function (res) {
+ var note = res.body
+ PlanetStore.Actions.updateNote(note)
+ this.props.close()
+ this.props.transitionTo('notes', {userName: planet.userName, planetName: planet.name, localId: note.localId})
+ }.bind(this))
+ .catch(function (err) {
+ console.error(err)
+ })
+ } else {
+ Hq.updateNote(planet.userName, planet.name, this.props.note.localId, this.state.note)
+ .then(function (res) {
+ var note = res.body
+ PlanetStore.Actions.updateNote(note)
+ this.props.close()
+ }.bind(this))
+ }
+ },
+ render: function () {
+ var content = this.state.mode === EDIT_MODE ? (
+
+
+
+ ) : (
+
+ )
+
+ return (
+
+
+
+
+
+ {content}
+
+
+
+
+
+
+
+
+
+
+
+
+
+ )
+ }
+})
diff --git a/browser/main/Components/PlanetArticleDetail.jsx b/browser/main/Components/PlanetArticleDetail.jsx
new file mode 100644
index 00000000..1594fef7
--- /dev/null
+++ b/browser/main/Components/PlanetArticleDetail.jsx
@@ -0,0 +1,99 @@
+var React = require('react/addons')
+var moment = require('moment')
+
+var CodeViewer = require('../Components/CodeViewer')
+
+var CodeEditModal = require('../Components/CodeEditModal')
+var CodeDeleteModal = require('../Components/CodeDeleteModal')
+var NoteEditModal = require('../Components/NoteEditModal')
+var NoteDeleteModal = require('../Components/NoteDeleteModal')
+var MarkdownPreview = require('../Components/MarkdownPreview')
+
+var Modal = require('../Mixins/Modal')
+var ForceUpdate = require('../Mixins/ForceUpdate')
+
+module.exports = React.createClass({
+ mixins: [ForceUpdate(60000), Modal],
+ propTypes: {
+ article: React.PropTypes.object,
+ showOnlyWithTag: React.PropTypes.func,
+ planet: React.PropTypes.object
+ },
+ getInitialState: function () {
+ return {
+ isEditModalOpen: false
+ }
+ },
+ openEditModal: function () {
+ switch (this.props.article.type) {
+ case 'code' :
+ this.openModal(CodeEditModal, {code: this.props.article, planet: this.props.planet})
+ break
+ case 'note' :
+ this.openModal(NoteEditModal, {note: this.props.article, planet: this.props.planet})
+ }
+ },
+ openDeleteModal: function () {
+ switch (this.props.article.type) {
+ case 'code' :
+ this.openModal(CodeDeleteModal, {code: this.props.article, planet: this.props.planet})
+ break
+ case 'note' :
+ this.openModal(NoteDeleteModal, {note: this.props.article, planet: this.props.planet})
+ }
+ },
+ render: function () {
+ var article = this.props.article
+ if (article == null) {
+ return (
+
+ Nothing selected
+
+ )
+ }
+ var tags = article.Tags.length > 0 ? article.Tags.map(function (tag) {
+ return (
+ #{tag.name}
+ )
+ }.bind(this)) : (
+ Not tagged yet
+ )
+ if (article.type === 'code') {
+ return (
+
+
+ {article.callSign} {moment(article.updatedAt).fromNow()}
+
+
+
+
+
+
+
+
{article.description}
+
{tags}
+
+
+
+
+
+
+ )
+ }
+ return (
+
+
+ {article.title} {moment(article.updatedAt).fromNow()}
+
+
+
+
+
+
+
+ )
+ }
+})
diff --git a/browser/main/Components/PlanetArticleList.jsx b/browser/main/Components/PlanetArticleList.jsx
new file mode 100644
index 00000000..0111c3fc
--- /dev/null
+++ b/browser/main/Components/PlanetArticleList.jsx
@@ -0,0 +1,94 @@
+var React = require('react/addons')
+var ReactRouter = require('react-router')
+var moment = require('moment')
+
+var ForceUpdate = require('../Mixins/ForceUpdate')
+var Markdown = require('../Mixins/Markdown')
+
+var ProfileImage = require('../Components/ProfileImage')
+
+module.exports = React.createClass({
+ mixins: [ReactRouter.Navigation, ReactRouter.State, ForceUpdate(60000), Markdown],
+ propTypes: {
+ articles: React.PropTypes.array,
+ showOnlyWithTag: React.PropTypes.func
+ },
+ render: function () {
+ var articles = this.props.articles.map(function (article) {
+ var tags = article.Tags.length > 0 ? article.Tags.map(function (tag) {
+ return (
+ #{tag.name}
+ )
+ }.bind(this)) : (
+ Not tagged yet
+ )
+ var params = this.getParams()
+ var isActive = article.type === 'code' ? this.isActive('codes') && parseInt(params.localId, 10) === article.localId : this.isActive('notes') && parseInt(params.localId, 10) === article.localId
+
+ var handleClick
+
+ if (article.type === 'code') {
+
+ handleClick = function () {
+ this.transitionTo('codes', {
+ userName: params.userName,
+ planetName: params.planetName,
+ localId: article.localId
+ })
+ }.bind(this)
+
+ return (
+
+
+
+
+
{moment(article.updatedAt).fromNow()}
+
{article.description.length > 50 ? article.description.substring(0, 50) + ' …' : article.description}
+
{tags}
+
+
+
+
+ )
+ }
+
+ handleClick = function () {
+ this.transitionTo('notes', {
+ userName: params.userName,
+ planetName: params.planetName,
+ localId: article.localId
+ })
+ }.bind(this)
+
+ return (
+
+
+
+
+
+
{moment(article.updatedAt).fromNow()}
+
{article.title}
+
{tags}
+
+
+
+
+ )
+
+ }.bind(this))
+
+ return (
+
+ )
+ }
+})
diff --git a/browser/main/Components/PlanetCreateModal.jsx b/browser/main/Components/PlanetCreateModal.jsx
new file mode 100644
index 00000000..974a06a7
--- /dev/null
+++ b/browser/main/Components/PlanetCreateModal.jsx
@@ -0,0 +1,84 @@
+/* global localStorage */
+
+var React = require('react/addons')
+
+var Hq = require('../Services/Hq')
+
+var LinkedState = require('../Mixins/LinkedState')
+
+var PlanetStore = require('../Stores/PlanetStore')
+
+module.exports = React.createClass({
+ mixins: [LinkedState],
+ propTypes: {
+ ownerName: React.PropTypes.string,
+ transitionTo: React.PropTypes.func,
+ close: React.PropTypes.func
+ },
+ getInitialState: function () {
+ var currentUser = JSON.parse(localStorage.getItem('currentUser'))
+ var ownerName = this.props.ownerName != null ? this.props.ownerName : currentUser.name
+ return {
+ user: currentUser,
+ planet: {
+ name: '',
+ public: true
+ },
+ ownerName: ownerName
+ }
+ },
+ componentDidMount: function () {
+ React.findDOMNode(this.refs.name).focus()
+ },
+ onListen: function (res) {
+ if (res.status === 'planetCreated') {
+ this.props.close()
+ }
+ },
+ handleSubmit: function () {
+ Hq.createPlanet(this.state.ownerName, this.state.planet)
+ .then(function (res) {
+ var planet = res.body
+
+ PlanetStore.Actions.update(planet)
+
+ if (this.props.transitionTo != null) {
+ this.props.transitionTo('planetHome', {userName: planet.userName, planetName: planet.name})
+ }
+
+ this.props.close()
+ }.bind(this))
+ .catch(function (err) {
+ console.error(err)
+ })
+ },
+ render: function () {
+ var teamOptions = this.state.user.Teams.map(function (team) {
+ return (
+
+ )
+ })
+ return (
+
+
+
+
+ of
+
+ as
+
+
+
+
+
+ )
+ }
+})
diff --git a/browser/main/Components/PlanetHeader.jsx b/browser/main/Components/PlanetHeader.jsx
new file mode 100644
index 00000000..279f3629
--- /dev/null
+++ b/browser/main/Components/PlanetHeader.jsx
@@ -0,0 +1,66 @@
+var React = require('react/addons')
+var ReactRouter = require('react-router')
+var Link = ReactRouter.Link
+
+var Modal = require('../Mixins/Modal')
+var ExternalLink = require('../Mixins/ExternalLink')
+
+var PlanetSettingModal = require('./PlanetSettingModal')
+
+module.exports = React.createClass({
+ mixins: [ReactRouter.State, Modal, ExternalLink],
+ propTypes: {
+ search: React.PropTypes.string,
+ fetchPlanet: React.PropTypes.func,
+ onSearchChange: React.PropTypes.func,
+ currentPlanet: React.PropTypes.object
+ },
+ getInitialState: function () {
+ return {
+ search: ''
+ }
+ },
+ componentDidMount: function () {
+ React.findDOMNode(this.refs.search).focus()
+ },
+ openPlanetSettingModal: function () {
+ this.openModal(PlanetSettingModal, {planet: this.props.currentPlanet})
+ },
+ refresh: function () {
+ this.props.fetchPlanet()
+ },
+ render: function () {
+ var currentPlanetName = this.props.currentPlanet.name
+ var currentUserName = this.props.currentPlanet.userName
+
+ return (
+
+
+
{currentUserName}
+
{currentPlanetName}
+
+ {this.props.currentPlanet.public ? null : (
+
+ )}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ )
+ }
+})
diff --git a/browser/main/Components/PlanetNavigator.jsx b/browser/main/Components/PlanetNavigator.jsx
new file mode 100644
index 00000000..0df7b4f6
--- /dev/null
+++ b/browser/main/Components/PlanetNavigator.jsx
@@ -0,0 +1,58 @@
+var React = require('react/addons')
+var ReactRouter = require('react-router')
+var Navigation = ReactRouter.Navigation
+
+var Modal = require('../Mixins/Modal')
+var LaunchModal = require('../Components/LaunchModal')
+
+var PlanetNavigator = React.createClass({
+ mixins: [Modal, Navigation],
+ propTypes: {
+ planet: React.PropTypes.shape({
+ name: React.PropTypes.string
+ }),
+ search: React.PropTypes.string,
+ toggleCodeFilter: React.PropTypes.func,
+ toggleNoteFilter: React.PropTypes.func
+ },
+ getInitialState: function () {
+ return {
+ isLaunchModalOpen: false
+ }
+ },
+ submitLaunchModal: function (ret) {
+ this.setState({isLaunchModalOpen: false})
+ },
+ openLaunchModal: function () {
+ this.openModal(LaunchModal, {planet: this.props.planet, transitionTo: this.transitionTo})
+ },
+ render: function () {
+ var keywords = this.props.search.split(' ')
+ var usingCodeFilter = keywords.some(function (keyword) {
+ if (keyword === '$c') return true
+ return false
+ })
+ var usingNoteFilter = keywords.some(function (keyword) {
+ if (keyword === '$n') return true
+ return false
+ })
+
+ return (
+
+ )
+ }
+})
+
+module.exports = PlanetNavigator
diff --git a/browser/main/Components/PlanetSettingModal.jsx b/browser/main/Components/PlanetSettingModal.jsx
new file mode 100644
index 00000000..eb9f525e
--- /dev/null
+++ b/browser/main/Components/PlanetSettingModal.jsx
@@ -0,0 +1,154 @@
+var React = require('react/addons')
+
+var Hq = require('../Services/Hq')
+
+var LinkedState = require('../Mixins/LinkedState')
+
+var PlanetStore = require('../Stores/PlanetStore')
+
+module.exports = React.createClass({
+ mixins: [LinkedState],
+ propTypes: {
+ close: React.PropTypes.func,
+ planet: React.PropTypes.shape({
+ name: React.PropTypes.string,
+ public: React.PropTypes.bool,
+ userName: React.PropTypes.string
+ })
+ },
+ getInitialState: function () {
+ var deleteTextCandidates = [
+ 'Confirm',
+ 'Exterminatus',
+ 'Avada Kedavra'
+ ]
+ var random = Math.round(Math.random() * 10) % 10
+ var randomDeleteText = random > 1 ? deleteTextCandidates[0] : random === 1 ? deleteTextCandidates[1] : deleteTextCandidates[2]
+
+ return {
+ currentTab: 'profile',
+ planet: {
+ name: this.props.planet.name,
+ public: this.props.planet.public
+ },
+ randomDeleteText: randomDeleteText,
+ deleteConfirmation: ''
+ }
+ },
+ activePlanetProfile: function () {
+ this.setState({currentTab: 'profile'})
+ },
+ activePlanetDelete: function () {
+ this.setState({currentTab: 'delete'})
+ },
+ handlePublicChange: function (value) {
+ return function () {
+ this.state.planet.public = value
+ this.setState({planet: this.state.planet})
+ }.bind(this)
+ },
+ handleSavePlanetProfile: function (e) {
+ var planet = this.props.planet
+
+ this.setState({profileSubmitStatus: 'sending'}, function () {
+ Hq.updatePlanet(planet.userName, planet.name, this.state.planet)
+ .then(function (res) {
+ var planet = res.body
+
+ this.setState({profileSubmitStatus: 'done'})
+
+ PlanetStore.Actions.update(planet)
+ }.bind(this))
+ .catch(function (err) {
+ this.setState({profileSubmitStatus: 'error'})
+ console.error(err)
+ }.bind(this))
+ })
+ },
+ handleDeletePlanetClick: function () {
+ var planet = this.props.planet
+
+ this.setState({deleteSubmitStatus: 'sending'}, function () {
+ Hq.destroyPlanet(planet.userName, planet.name)
+ .then(function (res) {
+ var planet = res.body
+
+ PlanetStore.Actions.destroy(planet)
+ this.setState({deleteSubmitStatus: 'done'}, function () {
+ this.props.close()
+ })
+ }.bind(this))
+ .catch(function (err) {
+ this.setState({deleteSubmitStatus: 'error'})
+ console.error(err)
+ }.bind(this))
+ })
+
+ },
+ render: function () {
+ var content
+
+ content = this.state.currentTab === 'profile' ? this.renderPlanetProfileTab() : this.renderPlanetDeleteTab()
+
+ return (
+
+
+
Planet setting
+
+
+
+
+ {content}
+
+
+ )
+ },
+ renderPlanetProfileTab: function () {
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
on Sending...
+
+
Connection failed.. Try again.
+
+
Successfully done!!
+
+
+ )
+ },
+ renderPlanetDeleteTab: function () {
+ var disabled = !this.state.deleteConfirmation.match(new RegExp('^' + this.props.planet.userName + '/' + this.props.planet.name + '$'))
+
+ return (
+
+
Are you sure to destroy '{this.props.planet.userName + '/' + this.props.planet.name}'?
+
If you are sure, write '{this.props.planet.userName + '/' + this.props.planet.name}' to input below and click '{this.state.randomDeleteText}' button.
+
+
+
+
+
on Sending...
+
+
Connection failed.. Try again.
+
+
Successfully done!!
+
+
+ )
+ }
+})
diff --git a/browser/main/Components/ProfileImage.jsx b/browser/main/Components/ProfileImage.jsx
new file mode 100644
index 00000000..1cb3cf6d
--- /dev/null
+++ b/browser/main/Components/ProfileImage.jsx
@@ -0,0 +1,15 @@
+var React = require('react/addons')
+var md5 = require('md5')
+
+module.exports = React.createClass({
+ propTypes: {
+ email: React.PropTypes.string,
+ size: React.PropTypes.string,
+ className: React.PropTypes.string
+ },
+ render: function () {
+ return (
+
+ )
+ }
+})
diff --git a/browser/main/Components/TeamCreateModal.jsx b/browser/main/Components/TeamCreateModal.jsx
new file mode 100644
index 00000000..d258cf2c
--- /dev/null
+++ b/browser/main/Components/TeamCreateModal.jsx
@@ -0,0 +1,57 @@
+/* global localStorage */
+
+var React = require('react/addons')
+
+var Hq = require('../Services/Hq')
+
+var LinkedState = require('../Mixins/LinkedState')
+
+var UserStore = require('../Stores/UserStore')
+
+module.exports = React.createClass({
+ mixins: [LinkedState],
+ propTypes: {
+ user: React.PropTypes.shape({
+ name: React.PropTypes.string
+ }),
+ transitionTo: React.PropTypes.func,
+ close: React.PropTypes.func
+ },
+ getInitialState: function () {
+ return {
+ team: {
+ name: ''
+ }
+ }
+ },
+ handleSubmit: function () {
+ Hq.createTeam(this.props.user.name, this.state.team)
+ .then(function (res) {
+ var currentUser = JSON.parse(localStorage.getItem('currentUser'))
+ var team = res.body
+
+ currentUser.Teams.push(team)
+ localStorage.setItem('currentUser', JSON.stringify(currentUser))
+ UserStore.Actions.update(currentUser)
+
+ if (this.props.transitionTo != null) {
+ this.props.transitionTo('userHome', {userName: team.name})
+ }
+ this.props.close()
+ }.bind(this))
+ .catch(function (err) {
+ console.error(err)
+ })
+ },
+ render: function () {
+ return (
+
+
+
+
+
+ )
+ }
+})
diff --git a/browser/main/Components/TeamSettingsModal.jsx b/browser/main/Components/TeamSettingsModal.jsx
new file mode 100644
index 00000000..572b507f
--- /dev/null
+++ b/browser/main/Components/TeamSettingsModal.jsx
@@ -0,0 +1,273 @@
+/* global localStorage */
+
+var React = require('react/addons')
+var Reflux = require('reflux')
+var Select = require('react-select')
+
+var Hq = require('../Services/Hq')
+
+var LinkedState = require('../Mixins/LinkedState')
+var Helper = require('../Mixins/Helper')
+
+var UserStore = require('../Stores/UserStore')
+
+var getOptions = function (input, callback) {
+ Hq.searchUser(input)
+ .then(function (res) {
+ callback(null, {
+ options: res.body.map(function (user) {
+ return {
+ label: user.name,
+ value: user.name
+ }
+ }),
+ complete: false
+ })
+ })
+ .catch(function (err) {
+ console.error(err)
+ })
+}
+
+module.exports = React.createClass({
+ mixins: [LinkedState, Reflux.listenTo(UserStore, 'onUserChange'), Helper],
+ propTypes: {
+ team: React.PropTypes.shape({
+ id: React.PropTypes.number,
+ name: React.PropTypes.string,
+ profileName: React.PropTypes.string,
+ email: React.PropTypes.string,
+ Members: React.PropTypes.array
+ })
+ },
+ getInitialState: function () {
+ var team = this.props.team
+ return {
+ currentTab: 'teamInfo',
+ team: {
+ profileName: team.profileName
+ },
+ userSubmitStatus: null,
+ member: {
+ name: '',
+ role: 'member'
+ },
+ updatingMember: false
+ }
+ },
+ onUserChange: function (res) {
+ var member
+ switch (res.status) {
+ case 'memberAdded':
+ member = res.data
+ if (member.TeamMember.TeamId === this.props.team.id) {
+ this.forceUpdate()
+ }
+ break
+ case 'memberRemoved':
+ member = res.data
+ if (member.TeamMember.TeamId === this.props.team.id) {
+ this.forceUpdate()
+ }
+ break
+ }
+ },
+ selectTab: function (tabName) {
+ return function () {
+ this.setState({currentTab: tabName})
+ }.bind(this)
+ },
+ saveUserInfo: function () {
+ this.setState({
+ userSubmitStatus: 'sending'
+ }, function () {
+ Hq.updateUser(this.props.team.name, this.state.team)
+ .then(function (res) {
+ this.setState({userSubmitStatus: 'done'}, function () {
+ UserStore.Actions.update(res.body)
+ this.forceUpdate()
+ })
+ }.bind(this))
+ .catch(function (err) {
+ console.error(err)
+ this.setState({userSubmitStatus: 'error'})
+ }.bind(this))
+ })
+ },
+ handleMemberNameChange: function (value) {
+ var member = this.state.member
+ member.name = value
+ this.setState({member: member})
+ },
+ addMember: function () {
+ this.setState({updatingMember: true}, function () {
+ Hq
+ .addMember(this.props.team.name, {
+ userName: this.state.member.name,
+ role: this.state.member.role
+ })
+ .then(function (res) {
+ UserStore.Actions.addMember(res.body)
+ this.setState({updatingMember: false})
+ }.bind(this))
+ .catch(function (err) {
+ console.error(err)
+ this.setState({updatingMember: false})
+ }.bind(this))
+ })
+ },
+ roleChange: function (memberName) {
+ return function (e) {
+ var role = e.target.value
+ this.setState({updatingMember: true}, function () {
+ Hq
+ .addMember(this.props.team.name, {
+ userName: memberName,
+ role: role
+ })
+ .then(function (res) {
+ UserStore.Actions.addMember(res.body)
+ this.setState({updatingMember: false})
+ }.bind(this))
+ .catch(function (err) {
+ console.error(err)
+ this.setState({updatingMember: false})
+ }.bind(this))
+ })
+ }.bind(this)
+ },
+ removeMember: function (memberName) {
+ return function () {
+ this.setState({updatingMember: true}, function () {
+ Hq
+ .removeMember(this.props.team.name, {
+ userName: memberName
+ })
+ .then(function (res) {
+ UserStore.Actions.removeMember(res.body)
+ this.setState({updatingMember: false})
+ }.bind(this))
+ .catch(function (err) {
+ console.error(err)
+ this.setState({updatingMember: false})
+ }.bind(this))
+ })
+ }.bind(this)
+ },
+ render: function () {
+ var content
+
+ switch (this.state.currentTab) {
+ case 'teamInfo':
+ content = this.renderTeamInfoTab()
+ break
+ case 'members':
+ content = this.renderMembersTab()
+ break
+ }
+
+ return (
+
+
+
Team settings
+
+
+
+
+
+
+ {content}
+
+
+ )
+ },
+ renderTeamInfoTab: function () {
+ return (
+
+
+
+
+
+
+
+
+
on Sending...
+
+
Connection failed.. Try again.
+
+
Successfully done!!
+
+
+ )
+ },
+ renderMembersTab: function () {
+ var currentUser = JSON.parse(localStorage.getItem('currentUser'))
+
+ var members = this.props.team.Members.map(function (member) {
+ var isCurrentUser = currentUser.id === member.id
+ return (
+
+ | {member.profileName}({member.name}) |
+
+ {isCurrentUser ? (
+ 'Owner'
+ ) : (
+
+ )}
+ |
+
+ {isCurrentUser ? '-' : (
+
+ )}
+ |
+
+ )
+ }.bind(this))
+
+ var belowLimit = members.length < 5
+
+ return (
+
+
+
+
+ | Username |
+ Role |
+ Control |
+
+
+
+ {members}
+
+
+ {belowLimit ? (
+
+
Add Member
+
+
+
+
+
+
+ ) : (
+
+ Maximum numbr of members is 5 on Beta version. Please contact us if you want futher use.
+
+ )}
+
+ )
+ }
+})
diff --git a/browser/main/Containers/HomeContainer.jsx b/browser/main/Containers/HomeContainer.jsx
new file mode 100644
index 00000000..e61204f1
--- /dev/null
+++ b/browser/main/Containers/HomeContainer.jsx
@@ -0,0 +1,29 @@
+/* global localStorage */
+
+var React = require('react/addons')
+var ReactRouter = require('react-router')
+var RouteHandler = ReactRouter.RouteHandler
+var State = ReactRouter.State
+var Navigation = ReactRouter.Navigation
+
+var AuthFilter = require('../Mixins/AuthFilter')
+
+var HomeNavigator = require('../Components/HomeNavigator')
+
+module.exports = React.createClass({
+ mixins: [AuthFilter.OnlyUser, State, Navigation],
+ componentDidMount: function () {
+ if (this.isActive('homeEmpty')) {
+ var user = JSON.parse(localStorage.getItem('currentUser'))
+ this.transitionTo('userHome', {userName: user.name})
+ }
+ },
+ render: function () {
+ return (
+
+
+
+
+ )
+ }
+})
diff --git a/browser/main/Containers/LoginContainer.jsx b/browser/main/Containers/LoginContainer.jsx
new file mode 100644
index 00000000..b2cde41f
--- /dev/null
+++ b/browser/main/Containers/LoginContainer.jsx
@@ -0,0 +1,106 @@
+/* global localStorage */
+var React = require('react/addons')
+var ReactRouter = require('react-router')
+var Link = ReactRouter.Link
+
+var AuthFilter = require('../Mixins/AuthFilter')
+var LinkedState = require('../Mixins/LinkedState')
+var Hq = require('../Services/Hq')
+
+module.exports = React.createClass({
+ mixins: [LinkedState, ReactRouter.Navigation, AuthFilter.OnlyGuest],
+ getInitialState: function () {
+ return {
+ user: {},
+ authenticationFailed: false,
+ connectionFailed: false,
+ isSending: false
+ }
+ },
+ onListen: function (res) {
+ if (res.status === 'failedToLogIn') {
+ if (res.data.status === 401) {
+ // Wrong E-mail or Password
+ this.setState({
+ authenticationFailed: true,
+ connectionFailed: false,
+ isSending: false
+ })
+ return
+ }
+ // Connection Failed or Whatever
+ this.setState({
+ authenticationFailed: false,
+ connectionFailed: true,
+ isSending: false
+ })
+ return
+ }
+ },
+ handleSubmit: function (e) {
+ this.setState({
+ authenticationFailed: false,
+ connectionFailed: false,
+ isSending: true
+ }, function () {
+ Hq.login(this.state.user)
+ .then(function (res) {
+ localStorage.setItem('token', res.body.token)
+ localStorage.setItem('currentUser', JSON.stringify(res.body.user))
+
+ this.transitionTo('userHome', {userName: res.body.user.name})
+ }.bind(this))
+ .catch(function (err) {
+ if (err.status === 401) {
+ this.setState({
+ authenticationFailed: true,
+ connectionFailed: false,
+ isSending: false
+ })
+ return
+ }
+ this.setState({
+ authenticationFailed: false,
+ connectionFailed: true,
+ isSending: false
+ })
+ }.bind(this))
+ })
+
+ e.preventDefault()
+ },
+ render: function () {
+ return (
+
+

+
+
+
+
+
+ )
+ }
+})
diff --git a/browser/main/Containers/MainContainer.jsx b/browser/main/Containers/MainContainer.jsx
new file mode 100644
index 00000000..45743e7a
--- /dev/null
+++ b/browser/main/Containers/MainContainer.jsx
@@ -0,0 +1,104 @@
+/* global localStorage */
+
+var ipc = require('ipc')
+
+var React = require('react/addons')
+var ReactRouter = require('react-router')
+var RouteHandler = ReactRouter.RouteHandler
+var Navigation = ReactRouter.Navigation
+var State = ReactRouter.State
+
+var Hq = require('../Services/Hq')
+
+var Modal = require('../Mixins/Modal')
+
+var UserStore = require('../Stores/UserStore')
+
+var ContactModal = require('../Components/ContactModal')
+
+function fetchPlanet (userName, planetName) {
+ Hq.fetchPlanet(userName, planetName)
+ .then(function (res) {
+ var planet = res.body
+
+ planet.Codes.forEach(function (code) {
+ code.type = 'code'
+ })
+
+ planet.Notes.forEach(function (note) {
+ note.type = 'note'
+ })
+
+ console.log('planet-' + planet.id + ' fetched!')
+ localStorage.setItem('planet-' + planet.id, JSON.stringify(planet))
+ })
+ .catch(function (err) {
+ console.error(err)
+ })
+}
+
+module.exports = React.createClass({
+ mixins: [State, Navigation, Modal],
+ getInitialState: function () {
+ return {
+ updateAvailable: false
+ }
+ },
+ componentDidMount: function () {
+ ipc.on('update-available', function (message) {
+ this.setState({updateAvailable: true})
+ }.bind(this))
+
+ if (this.isActive('root')) {
+ if (localStorage.getItem('currentUser') == null) {
+ this.transitionTo('login')
+ return
+ } else {
+ this.transitionTo('home')
+ return
+ }
+ }
+
+ Hq.getUser()
+ .then(function (res) {
+ var user = res.body
+ localStorage.setItem('currentUser', JSON.stringify(user))
+ UserStore.Actions.update(user)
+
+ user.Planets.forEach(function (planet) {
+ fetchPlanet(planet.userName, planet.name)
+ })
+ user.Teams.forEach(function (team) {
+ team.Planets.forEach(function (planet) {
+ fetchPlanet(planet.userName, planet.name)
+ })
+ })
+ })
+ .catch(function (err) {
+ if (err.status === 401) {
+ console.log('Not logged in yet')
+ localStorage.removeItem('currentUser')
+ this.transitionTo('login')
+ return
+ }
+ console.error(err)
+ }.bind(this))
+ },
+ updateApp: function () {
+ ipc.send('update-app', 'Deal with it.')
+ },
+ openContactModal: function () {
+ this.openModal(ContactModal)
+ },
+ render: function () {
+ return (
+
+ {this.state.updateAvailable ? (
+
+ ) : null}
+
+
+
+ )
+ }
+})
diff --git a/browser/main/Containers/PlanetContainer.jsx b/browser/main/Containers/PlanetContainer.jsx
new file mode 100644
index 00000000..64bb29d0
--- /dev/null
+++ b/browser/main/Containers/PlanetContainer.jsx
@@ -0,0 +1,373 @@
+/* global localStorage*/
+'strict'
+var React = require('react/addons')
+var ReactRouter = require('react-router')
+var Reflux = require('reflux')
+
+var PlanetHeader = require('../Components/PlanetHeader')
+var PlanetNavigator = require('../Components/PlanetNavigator')
+var PlanetArticleList = require('../Components/PlanetArticleList')
+var PlanetArticleDetail = require('../Components/PlanetArticleDetail')
+
+var Hq = require('../Services/Hq')
+
+var Modal = require('../Mixins/Modal')
+var ArticleFilter = require('../Mixins/ArticleFilter')
+var Helper = require('../Mixins/Helper')
+
+var UserStore = require('../Stores/UserStore')
+var PlanetStore = require('../Stores/PlanetStore')
+
+module.exports = React.createClass({
+ mixins: [ReactRouter.Navigation, ReactRouter.State, Modal, Reflux.listenTo(UserStore, 'onUserChange'), Reflux.listenTo(PlanetStore, 'onPlanetChange'), ArticleFilter, Helper],
+ propTypes: {
+ params: React.PropTypes.object,
+ planetName: React.PropTypes.string
+ },
+ getInitialState: function () {
+ return {
+ currentUser: JSON.parse(localStorage.getItem('currentUser')),
+ planet: null,
+ search: ''
+ }
+ },
+ componentDidMount: function () {
+ this.fetchPlanet(this.props.params.userName, this.props.params.planetName)
+ },
+ componentDidUpdate: function () {
+ if (this.isActive('planetHome') && this.refs.list != null && this.refs.list.props.articles.length > 0) {
+ var article = this.refs.list.props.articles[0]
+ var planet = this.state.planet
+ switch (article.type) {
+ case 'code':
+ this.transitionTo('codes', {userName: planet.userName, planetName: planet.name, localId: article.localId})
+ break
+ case 'note':
+ this.transitionTo('notes', {userName: planet.userName, planetName: planet.name, localId: article.localId})
+ break
+ }
+ }
+ },
+ componentWillReceiveProps: function (nextProps) {
+ if (this.state.planet == null) {
+ this.fetchPlanet(nextProps.params.userName, nextProps.params.planetName)
+ return
+ }
+
+ if (nextProps.params.userName !== this.state.planet.userName || nextProps.params.planetName !== this.state.planet.name) {
+ this.setState({
+ planet: null
+ }, function () {
+ this.fetchPlanet(nextProps.params.userName, nextProps.params.planetName)
+ })
+ }
+ },
+ onPlanetChange: function (res) {
+ if (this.state.planet == null) return
+
+ var planet, code, note, articleIndex, articlesCount
+ switch (res.status) {
+ case 'updated':
+ planet = res.data
+ if (this.state.planet.id === planet.id) {
+ if (this.state.planet.name === planet.name) {
+ this.setState({planet: planet})
+ } else {
+ this.transitionTo('planetHome', {userName: planet.userName, planetName: planet.name})
+ }
+ }
+ break
+ case 'destroyed':
+ planet = res.data
+ if (this.state.planet.id === planet.id) {
+ this.transitionTo('userHome', {userName: this.state.planet.userName})
+ }
+ break
+ case 'codeUpdated':
+ code = res.data
+ if (code.PlanetId === this.state.planet.id) {
+ this.state.planet.Codes = this.updateItemToTargetArray(code, this.state.planet.Codes)
+
+ this.setState({planet: this.state.planet})
+ }
+ break
+ case 'noteUpdated':
+ note = res.data
+ if (note.PlanetId === this.state.planet.id) {
+ this.state.planet.Notes = this.updateItemToTargetArray(note, this.state.planet.Notes)
+
+ this.setState({planet: this.state.planet})
+ }
+ break
+ case 'codeDestroyed':
+ code = res.data
+ if (code.PlanetId === this.state.planet.id) {
+ this.state.planet.Codes = this.deleteItemFromTargetArray(code, this.state.planet.Codes)
+
+ if (this.refs.detail.props.article != null && this.refs.detail.props.article.type === code.type && this.refs.detail.props.article.localId === code.localId) {
+ articleIndex = this.getFilteredIndexOfCurrentArticle()
+ articlesCount = this.refs.list.props.articles.length
+
+ this.setState({planet: this.state.planet}, function () {
+ if (articlesCount > 1) {
+ if (articleIndex > 0) {
+ this.selectArticleByListIndex(articleIndex - 1)
+ } else {
+ this.selectArticleByListIndex(articleIndex)
+ }
+ }
+ })
+ return
+ }
+
+ this.setState({planet: this.state.planet})
+ }
+ break
+ case 'noteDestroyed':
+ note = res.data
+ if (note.PlanetId === this.state.planet.id) {
+ this.state.planet.Notes = this.deleteItemFromTargetArray(note, this.state.planet.Notes)
+
+ if (this.refs.detail.props.article != null && this.refs.detail.props.article.type === note.type && this.refs.detail.props.article.localId === note.localId) {
+ articleIndex = this.getFilteredIndexOfCurrentArticle()
+ articlesCount = this.refs.list.props.articles.length
+
+ this.setState({planet: this.state.planet}, function () {
+ if (articlesCount > 1) {
+ if (articleIndex > 0) {
+ this.selectArticleByListIndex(articleIndex - 1)
+ } else {
+ this.selectArticleByListIndex(articleIndex)
+ }
+ }
+ })
+ return
+ }
+
+ this.setState({planet: this.state.planet})
+ }
+ break
+ }
+ },
+ onUserChange: function () {
+
+ },
+ fetchPlanet: function (userName, planetName) {
+ if (userName == null) userName = this.props.params.userName
+ if (planetName == null) planetName = this.props.params.planetName
+
+ Hq.fetchPlanet(userName, planetName)
+ .then(function (res) {
+ var planet = res.body
+
+ planet.Codes.forEach(function (code) {
+ code.type = 'code'
+ })
+
+ planet.Notes.forEach(function (note) {
+ note.type = 'note'
+ })
+
+ localStorage.setItem('planet-' + planet.id, JSON.stringify(planet))
+
+ this.setState({planet: planet})
+ }.bind(this))
+ .catch(function (err) {
+ console.error(err)
+ })
+ },
+ getFilteredIndexOfCurrentArticle: function () {
+ var params = this.props.params
+ var index = 0
+
+ if (this.isActive('codes')) {
+ this.refs.list.props.articles.some(function (_article, _index) {
+ if (_article.type === 'code' && _article.localId === parseInt(params.localId, 10)) {
+ index = _index
+ }
+ })
+ } else if (this.isActive('notes')) {
+ this.refs.list.props.articles.some(function (_article, _index) {
+ if (_article.type === 'note' && _article.localId === parseInt(params.localId, 10)) {
+ index = _index
+ return true
+ }
+ return false
+ })
+ }
+
+ return index
+ },
+ selectArticleByListIndex: function (index) {
+ var article = this.refs.list.props.articles[index]
+ var params = this.props.params
+
+ if (article == null) {
+ this.transitionTo('planetHome', params)
+ return
+ }
+
+ if (article.type === 'code') {
+ params.localId = article.localId
+ this.transitionTo('codes', params)
+ return
+ }
+
+ if (article.type === 'note') {
+ params.localId = article.localId
+ this.transitionTo('notes', params)
+ return
+ }
+ },
+ selectNextArticle: function () {
+ if (this.state.planet == null) return
+
+ var index = this.getFilteredIndexOfCurrentArticle()
+
+ if (index < this.refs.list.props.articles.length - 1) {
+ this.selectArticleByListIndex(index + 1)
+ }
+ },
+ selectPriorArticle: function () {
+ if (this.state.planet == null) {
+ return
+ }
+ var index = this.getFilteredIndexOfCurrentArticle()
+
+ if (index > 0) {
+ this.selectArticleByListIndex(index - 1)
+ } else {
+ React.findDOMNode(this).querySelector('.PlanetHeader .searchInput input').focus()
+ }
+ },
+ handleSearchChange: function (e) {
+ this.setState({search: e.target.value}, function () {
+ this.selectArticleByListIndex(0)
+ })
+ },
+ showAll: function () {
+ this.setState({search: ''})
+ },
+ toggleCodeFilter: function () {
+ var keywords = typeof this.state.search === 'string' ? this.state.search.split(' ') : []
+
+ var usingCodeFilter = false
+ var usingNoteFilter = false
+ keywords = keywords.filter(function (keyword) {
+ if (keyword === '$n') {
+ usingNoteFilter = true
+ return false
+ }
+ if (keyword === '$c') usingCodeFilter = true
+ return true
+ })
+
+ if (usingCodeFilter && !usingNoteFilter) {
+ keywords = keywords.filter(function (keyword) {
+ return keyword !== '$c'
+ })
+ }
+
+ if (!usingCodeFilter) {
+ keywords.unshift('$c')
+ }
+
+ this.setState({search: keywords.join(' ')}, function () {
+ this.selectArticleByListIndex(0)
+ })
+ },
+ toggleNoteFilter: function () {
+ var keywords = typeof this.state.search === 'string' ? this.state.search.split(' ') : []
+
+ var usingCodeFilter = false
+ var usingNoteFilter = false
+ keywords = keywords.filter(function (keyword) {
+ if (keyword === '$c') {
+ usingCodeFilter = true
+ return false
+ }
+ if (keyword === '$n') usingNoteFilter = true
+ return true
+ })
+
+ if (usingNoteFilter && !usingCodeFilter) {
+ keywords = keywords.filter(function (keyword) {
+ return keyword !== '$n'
+ })
+ }
+
+ if (!usingNoteFilter) {
+ keywords.unshift('$n')
+ }
+
+ this.setState({search: keywords.join(' ')}, function () {
+ this.selectArticleByListIndex(0)
+ })
+ },
+ applyTagFilter: function (tag) {
+ return function () {
+ this.setState({search: '#' + tag})
+ }.bind(this)
+ },
+ focus: function () {
+ React.findDOMNode(this).focus()
+ },
+ render: function () {
+ if (this.state.planet == null) return ()
+
+ var localId = parseInt(this.props.params.localId, 10)
+
+ var codes = this.state.planet.Codes
+ var notes = this.state.planet.Notes
+
+ var article
+ if (this.isActive('codes')) {
+ codes.some(function (_article) {
+ if (localId === _article.localId) {
+ article = _article
+ return true
+ }
+ return false
+ })
+ } else if (this.isActive('notes')) {
+ notes.some(function (_article) {
+ if (localId === _article.localId) {
+ article = _article
+ return true
+ }
+ return false
+ })
+ }
+
+ var articles = codes.concat(notes)
+
+ var filteredArticles = this.searchArticle(this.state.search, articles)
+
+ return (
+
+ )
+ }
+})
diff --git a/browser/main/Containers/SignupContainer.jsx b/browser/main/Containers/SignupContainer.jsx
new file mode 100644
index 00000000..e1ea48b9
--- /dev/null
+++ b/browser/main/Containers/SignupContainer.jsx
@@ -0,0 +1,136 @@
+/* global localStorage */
+
+var React = require('react/addons')
+var ReactRouter = require('react-router')
+var Link = ReactRouter.Link
+
+var AuthFilter = require('../Mixins/AuthFilter')
+var LinkedState = require('../Mixins/LinkedState')
+var Hq = require('../Services/Hq')
+
+module.exports = React.createClass({
+ mixins: [LinkedState, ReactRouter.Navigation, AuthFilter.OnlyGuest],
+ getInitialState: function () {
+ return {
+ user: {},
+ connectionFailed: false,
+ emailConflicted: false,
+ nameConflicted: false,
+ validationFailed: false,
+ isSending: false
+ }
+ },
+ handleSubmit: function (e) {
+ this.setState({
+ connectionFailed: false,
+ emailConflicted: false,
+ nameConflicted: false,
+ validationFailed: false,
+ isSending: true
+ }, function () {
+ Hq.signup(this.state.user)
+ .then(function (res) {
+ localStorage.setItem('token', res.body.token)
+ localStorage.setItem('currentUser', JSON.stringify(res.body.user))
+
+ this.transitionTo('userHome', {userName: res.body.user.name})
+ }.bind(this))
+ .catch(function (err) {
+ console.error(err)
+ var res = err.response
+ if (err.status === 409) {
+ // Confliction
+ var emailConflicted = res.body.errors[0].path === 'email'
+ var nameConflicted = res.body.errors[0].path === 'name'
+
+ this.setState({
+ connectionFailed: false,
+ emailConflicted: emailConflicted,
+ nameConflicted: nameConflicted,
+ validationFailed: false,
+ isSending: false
+ })
+ return
+ }
+
+ if (err.status === 422) {
+ // Validation Failed
+ this.setState({
+ connectionFailed: false,
+ emailConflicted: false,
+ nameConflicted: false,
+ validationFailed: {
+ errors: res.body.errors.map(function (error) {
+ return error.path
+ })
+ },
+ isSending: false
+ })
+ return
+ }
+
+ // Connection Failed or Whatever
+ this.setState({
+ connectionFailed: true,
+ emailConflicted: false,
+ nameConflicted: false,
+ validationFailed: false,
+ isSending: false
+ })
+ return
+ }.bind(this))
+ })
+
+ e.preventDefault()
+ },
+ render: function () {
+ return (
+
+

+
+
+
+
+
+
会員登録することで、当サイトの利用規約及びCookieの使用を含むデータに関するポリシーに同意するものとします。
+
+ )
+ }
+})
diff --git a/browser/main/Containers/UserContainer.jsx b/browser/main/Containers/UserContainer.jsx
new file mode 100644
index 00000000..8d19af92
--- /dev/null
+++ b/browser/main/Containers/UserContainer.jsx
@@ -0,0 +1,366 @@
+/* global localStorage */
+
+var React = require('react/addons')
+var ReactRouter = require('react-router')
+var Navigation = ReactRouter.Navigation
+var State = ReactRouter.State
+var RouteHandler = ReactRouter.RouteHandler
+var Link = ReactRouter.Link
+var Reflux = require('reflux')
+
+var LinkedState = require('../Mixins/LinkedState')
+var Modal = require('../Mixins/Modal')
+var Helper = require('../Mixins/Helper')
+
+var Hq = require('../Services/Hq')
+
+var ProfileImage = require('../Components/ProfileImage')
+var EditProfileModal = require('../Components/EditProfileModal')
+var TeamSettingsModal = require('../Components/TeamSettingsModal')
+var PlanetCreateModal = require('../Components/PlanetCreateModal')
+var AddMemberModal = require('../Components/AddMemberModal')
+var TeamCreateModal = require('../Components/TeamCreateModal')
+
+var UserStore = require('../Stores/UserStore')
+var PlanetStore = require('../Stores/PlanetStore')
+
+module.exports = React.createClass({
+ mixins: [LinkedState, State, Navigation, Modal, Reflux.listenTo(UserStore, 'onUserChange'), Reflux.listenTo(PlanetStore, 'onPlanetChange'), Helper],
+ propTypes: {
+ params: React.PropTypes.shape({
+ userName: React.PropTypes.string,
+ planetName: React.PropTypes.string
+ })
+ },
+ getInitialState: function () {
+ return {
+ user: null
+ }
+ },
+ componentDidMount: function () {
+ this.fetchUser()
+ },
+ componentWillReceiveProps: function (nextProps) {
+ if (this.state.user == null) {
+ this.fetchUser(nextProps.params.userName)
+ return
+ }
+
+ if (nextProps.params.userName !== this.state.user.name) {
+ this.setState({
+ user: null
+ }, function () {
+ this.fetchUser(nextProps.params.userName)
+ })
+ }
+ },
+ onUserChange: function (res) {
+ if (this.state.user == null) return
+
+ var member
+ switch (res.status) {
+ case 'userUpdated':
+ if (this.state.user.id === res.data.id) {
+ this.setState({user: res.data})
+ }
+ break
+ case 'memberAdded':
+ member = res.data
+ if (this.state.user.userType === 'team' && member.TeamMember.TeamId === this.state.user.id) {
+ this.state.user.Members = this.updateItemToTargetArray(member, this.state.user.Members)
+
+ this.setState({user: this.state.user})
+ }
+ break
+ case 'memberRemoved':
+ member = res.data
+ if (this.state.user.userType === 'team' && member.TeamMember.TeamId === this.state.user.id) {
+ this.state.user.Members = this.deleteItemFromTargetArray(member, this.state.user.Members)
+
+ this.setState({user: this.state.user})
+ }
+ break
+ }
+ },
+ onPlanetChange: function (res) {
+ if (this.state.user == null) return
+
+ var currentUser, planet, isOwner, team
+ switch (res.status) {
+ case 'updated':
+ // if state.user is currentUser, planet will be fetched by UserStore
+ currentUser = JSON.parse(localStorage.getItem('currentUser'))
+ if (currentUser.id === this.state.user.id) return
+
+ planet = res.data
+ isOwner = planet.Owner.id === this.state.user.id
+ if (isOwner) {
+ this.state.user.Planets = this.updateItemToTargetArray(planet, this.state.user.Planets)
+ this.setState({user: this.state.user})
+ return
+ }
+ // check if team of user has this planet
+ team = null
+ this.state.user.userType !== 'team' && this.state.user.Teams.some(function (_team) {
+ if (planet.Owner.id === _team.id) {
+ team = _team
+ return true
+ }
+ return false
+ })
+ if (team != null) {
+ team.Planets = this.updateItemToTargetArray(planet, team.Planets)
+ this.setState({user: this.state.user})
+ return
+ }
+
+ break
+ case 'destroyed':
+ // if state.user is currentUser, planet will be fetched by UserStore
+ currentUser = JSON.parse(localStorage.getItem('currentUser'))
+ if (currentUser.id === this.state.user.id) return
+
+ planet = res.data
+ isOwner = planet.Owner.id === this.state.user.id
+ if (isOwner) {
+ this.state.user.Planets = this.deleteItemFromTargetArray(planet, this.state.user.Planets)
+ this.setState({user: this.state.user})
+ return
+ }
+ // check if team of user has this planet
+ team = null
+ this.state.user.userType !== 'team' && this.state.user.Teams.some(function (_team) {
+ if (planet.Owner.id === _team.id) {
+ team = _team
+ return true
+ }
+ return false
+ })
+ if (team != null) {
+ team.Planets = this.deleteItemFromTargetArray(planet, team.Planets)
+ this.setState({user: this.state.user})
+ return
+ }
+ break
+ }
+ },
+ fetchUser: function (userName) {
+ if (userName == null) userName = this.props.params.userName
+
+ Hq.fetchUser(userName)
+ .then(function (res) {
+ this.setState({user: res.body})
+ }.bind(this))
+ .catch(function (err) {
+ console.error(err)
+ })
+ },
+ openEditProfileModal: function () {
+ this.openModal(EditProfileModal, {user: this.state.user})
+ },
+ openTeamSettingsModal: function () {
+ this.openModal(TeamSettingsModal, {team: this.state.user})
+ },
+ openAddUserModal: function () {
+ this.openModal(AddMemberModal, {team: this.state.user})
+ },
+ openTeamCreateModal: function () {
+ this.openModal(TeamCreateModal, {user: this.state.user})
+ },
+ openPlanetCreateModalWithOwnerName: function (name) {
+ return function () {
+ this.openModal(PlanetCreateModal, {ownerName: name})
+ }.bind(this)
+ },
+ render: function () {
+ var user = this.state.user
+
+ var currentUser = JSON.parse(localStorage.getItem('currentUser'))
+
+ if (this.isActive('userHome')) {
+ if (user == null) {
+ return (
+
+ User Loading...
+
+ )
+ } else if (user.userType === 'team') {
+ return this.renderTeamHome(currentUser)
+ } else {
+ return this.renderUserHome(currentUser)
+ }
+ } else if (this.isActive('planet') && user != null && user.userType === 'team') {
+ console.log(user.Members)
+ var members = user.Members.map(function (member) {
+ return (
+
+
+
+
{member.profileName}
+
@{member.name}
+
+
+ )
+ })
+ return (
+
+ )
+ } else {
+ return (
+
+
+
+ )
+ }
+ },
+ renderTeamHome: function (currentUser) {
+ var user = this.state.user
+
+ var isOwner = true
+
+ var userPlanets = user.Planets.map(function (planet) {
+ return (
+
+ {planet.userName}/{planet.name}
+ {!planet.public ? () : null}
+
+ )
+ })
+
+ var members = user.Members == null ? [] : user.Members.map(function (member) {
+ return (
+
+
+
+
+
{member.profileName} ({member.TeamMember.role})
+
@{member.name}
+
+
+
+
+ )
+ })
+ return (
+
+
+
+
+
{user.profileName}
+
{user.name}
+
+
+
+
+
+
{members.length} {members.length > 1 ? 'Members' : 'Member'}
+
+ {members}
+ {isOwner ? () : null}
+
+
+
+
{userPlanets.length} {userPlanets.length > 0 ? 'Planets' : 'Planet'}
+
+
+ {userPlanets}
+ {isOwner ? () : null}
+
+
+
+
+ )
+ },
+ renderUserHome: function (currentUser) {
+ var user = this.state.user
+
+ var isOwner = currentUser.id === user.id
+
+ var userPlanets = user.Planets.map(function (planet) {
+ return (
+
+ {planet.userName}/{planet.name}
+ {!planet.public ? () : null}
+
+ )
+ })
+
+ var teams = user.Teams == null ? [] : user.Teams.map(function (team) {
+ return (
+
+
+
+
{team.profileName}
+
@{team.name}
+
+
+
+ )
+ })
+
+ var teamPlanets = user.Teams == null ? [] : user.Teams.map(function (team) {
+ var planets = (team.Planets == null ? [] : team.Planets).map(function (planet) {
+ return (
+
+ {planet.userName}/{planet.name}
+ {!planet.public ? () : null}
+
+ )
+ })
+ return (
+
+
{team.name}
+
+ {planets}
+ {isOwner ? () : null}
+
+
+ )
+ }.bind(this))
+
+ var planetCount = userPlanets.length + user.Teams.reduce(function (sum, team) {
+ return sum + (team.Planets != null ? team.Planets.length : 0)
+ }, 0)
+
+ return (
+
+
+
+
+
{user.profileName}
+
{user.name}
+
+
+ {isOwner ? (
+ ) : null}
+
+
+
{teams.length} {teams.length > 1 ? 'Teams' : 'Team'}
+
+ {teams}
+ {isOwner ? () : null}
+
+
+
+
{planetCount} {planetCount > 1 ? 'Planets' : 'Planet'}
+
+
{user.profileName}
+
+ {userPlanets}
+ {isOwner ? () : null}
+
+
+ {teamPlanets}
+
+
+ )
+ }
+})
diff --git a/browser/main/Mixins/ArticleFilter.js b/browser/main/Mixins/ArticleFilter.js
new file mode 100644
index 00000000..d3506e8d
--- /dev/null
+++ b/browser/main/Mixins/ArticleFilter.js
@@ -0,0 +1,67 @@
+function basicFilter (keyword, articles) {
+ if (keyword === '' || keyword == null) return articles
+ var firstFiltered = articles.filter(function (article) {
+
+ var first = article.type === 'code' ? article.description : article.title
+ if (first.match(new RegExp(keyword, 'i'))) return true
+
+ return false
+ })
+
+ var secondFiltered = articles.filter(function (article) {
+ var second = article.type === 'code' ? article.content : article.content
+ if (second.match(new RegExp(keyword, 'i'))) return true
+
+ return false
+ })
+
+ return firstFiltered.concat(secondFiltered).filter(function (value, index, self) {
+ return self.indexOf(value) === index
+ })
+}
+
+function codeFilter (articles) {
+ return articles.filter(function (article) {
+ return article.type === 'code'
+ })
+}
+
+function noteFilter (articles) {
+ return articles.filter(function (article) {
+ return article.type === 'note'
+ })
+}
+
+function tagFilter (keyword, articles) {
+ return articles.filter(function (article) {
+ return article.Tags.some(function (tag) {
+ return tag.name.match(new RegExp('^' + keyword, 'i'))
+ })
+ })
+}
+
+function searchArticle (search, articles) {
+ var keywords = search.split(' ')
+
+ for (var keyword of keywords) {
+ if (keyword.match(/^\$c/, 'i')) {
+ articles = codeFilter(articles)
+ continue
+ } else if (keyword.match(/^\$n/, 'i')) {
+ articles = noteFilter(articles)
+ continue
+ } else if (keyword.match(/^#[A-Za-z0-9]+/)) {
+ articles = tagFilter(keyword.substring(1, keyword.length), articles)
+ continue
+ }
+ articles = basicFilter(keyword, articles)
+ }
+
+ return articles.sort(function (a, b) {
+ return new Date(b.updatedAt) - new Date(a.updatedAt)
+ })
+}
+
+module.exports = {
+ searchArticle: searchArticle
+}
diff --git a/browser/main/Mixins/AuthFilter.js b/browser/main/Mixins/AuthFilter.js
new file mode 100644
index 00000000..22629fc9
--- /dev/null
+++ b/browser/main/Mixins/AuthFilter.js
@@ -0,0 +1,27 @@
+/* global localStorage*/
+
+var mixin = {}
+
+mixin.OnlyGuest = {
+ componentDidMount: function () {
+ var currentUser = localStorage.getItem('currentUser')
+
+ if (currentUser == null) {
+ return
+ }
+ this.transitionTo('userHome', {userName: currentUser.name})
+ }
+}
+
+mixin.OnlyUser = {
+ componentDidMount: function () {
+ var currentUser = localStorage.getItem('currentUser')
+
+ if (currentUser == null) {
+ this.transitionTo('login')
+ return
+ }
+ }
+}
+
+module.exports = mixin
diff --git a/browser/main/Mixins/ExternalLink.js b/browser/main/Mixins/ExternalLink.js
new file mode 100644
index 00000000..45005a04
--- /dev/null
+++ b/browser/main/Mixins/ExternalLink.js
@@ -0,0 +1,8 @@
+var shell = require('shell')
+
+module.exports = {
+ openExternal: function (e) {
+ shell.openExternal(e.currentTarget.href)
+ e.preventDefault()
+ }
+}
diff --git a/browser/main/Mixins/ForceUpdate.js b/browser/main/Mixins/ForceUpdate.js
new file mode 100644
index 00000000..db49bc8e
--- /dev/null
+++ b/browser/main/Mixins/ForceUpdate.js
@@ -0,0 +1,14 @@
+var ForceUpdate = function (interval) {
+ return {
+ componentDidMount: function () {
+ this.refreshTimer = setInterval(function () {
+ this.forceUpdate()
+ }.bind(this), interval)
+ },
+ componentWillUnmount: function () {
+ clearInterval(this.refreshTimer)
+ }
+ }
+}
+
+module.exports = ForceUpdate
diff --git a/browser/main/Mixins/Helper.js b/browser/main/Mixins/Helper.js
new file mode 100644
index 00000000..fa8ec774
--- /dev/null
+++ b/browser/main/Mixins/Helper.js
@@ -0,0 +1,30 @@
+function deleteItemFromTargetArray (item, targetArray) {
+ targetArray.some(function (_item, index) {
+ if (_item.id === item.id) {
+ targetArray.splice(index, 1)
+ return true
+ }
+ return false
+ })
+
+ return targetArray
+}
+
+function updateItemToTargetArray (item, targetArray) {
+ var isNew = !targetArray.some(function (_item, index) {
+ if (_item.id === item.id) {
+ targetArray.splice(index, 1, item)
+ return true
+ }
+ return false
+ })
+
+ if (isNew) targetArray.push(item)
+
+ return targetArray
+}
+
+module.exports = {
+ deleteItemFromTargetArray: deleteItemFromTargetArray,
+ updateItemToTargetArray: updateItemToTargetArray
+}
diff --git a/browser/main/Mixins/LinkedState.js b/browser/main/Mixins/LinkedState.js
new file mode 100644
index 00000000..57fc6ea6
--- /dev/null
+++ b/browser/main/Mixins/LinkedState.js
@@ -0,0 +1,31 @@
+function getIn (object, path) {
+ var stack = path.split('.')
+ while (stack.length > 1) {
+ object = object[stack.shift()]
+ }
+ return object[stack.shift()]
+}
+
+function updateIn (object, path, value) {
+ var current = object
+ var stack = path.split('.')
+ while (stack.length > 1) {
+ current = current[stack.shift()]
+ }
+ current[stack.shift()] = value
+ return object
+}
+
+function setPartialState (component, path, value) {
+ component.setState(
+ updateIn(component.state, path, value))
+}
+
+module.exports = {
+ linkState: function (path) {
+ return {
+ value: getIn(this.state, path),
+ requestChange: setPartialState.bind(null, this, path)
+ }
+ }
+}
diff --git a/browser/main/Mixins/Markdown.js b/browser/main/Mixins/Markdown.js
new file mode 100644
index 00000000..6d26080e
--- /dev/null
+++ b/browser/main/Mixins/Markdown.js
@@ -0,0 +1,13 @@
+var markdownit = require('markdown-it')
+var md = markdownit({
+ typographer: true,
+ linkify: true
+})
+
+var Markdown = {
+ markdown: function (content) {
+ return md.render(content)
+ }
+}
+
+module.exports = Markdown
diff --git a/browser/main/Mixins/Modal.jsx b/browser/main/Mixins/Modal.jsx
new file mode 100644
index 00000000..1a14f5c1
--- /dev/null
+++ b/browser/main/Mixins/Modal.jsx
@@ -0,0 +1,42 @@
+var React = require('react/addons')
+var ModalBase = React.createClass({
+ getInitialState: function () {
+ return {
+ component: null,
+ componentProps: {},
+ isHidden: true
+ }
+ },
+ close: function () {
+ this.setState({component: null, componentProps: null, isHidden: true})
+ },
+ render: function () {
+ var componentProps = this.state.componentProps
+ return (
+
+
+ {this.state.component == null ? null : (
+
+ )}
+
+ )
+ }
+})
+
+var modalBase = null
+
+module.exports = {
+ componentDidMount: function () {
+ if (modalBase == null) {
+ var el = document.createElement('div')
+ document.body.appendChild(el)
+ modalBase = React.render(, el)
+ }
+ },
+ openModal: function (component, props) {
+ modalBase.setState({component: component, componentProps: props, isHidden: false})
+ },
+ closeModal: function () {
+ modalBase.setState({isHidden: true})
+ }
+}
diff --git a/browser/main/Services/Hq.js b/browser/main/Services/Hq.js
new file mode 100644
index 00000000..518d7916
--- /dev/null
+++ b/browser/main/Services/Hq.js
@@ -0,0 +1,166 @@
+/* global localStorage */
+
+var request = require('superagent-promise')(require('superagent'), Promise)
+var apiUrl = require('../../../config').apiUrl
+
+module.exports = {
+ // Auth
+ login: function (input) {
+ return request
+ .post(apiUrl + 'auth')
+ .send(input)
+ },
+ signup: function (input) {
+ return request
+ .post(apiUrl + 'auth/signup')
+ .send(input)
+ },
+ getUser: function () {
+ return request
+ .get(apiUrl + 'auth/user')
+ .set({
+ Authorization: 'Bearer ' + localStorage.getItem('token')
+ })
+ },
+ changePassword: function (input) {
+ return request
+ .post(apiUrl + 'auth/password')
+ .set({
+ Authorization: 'Bearer ' + localStorage.getItem('token')
+ })
+ .send(input)
+ },
+
+ // Resources
+ fetchUser: function (userName) {
+ return request
+ .get(apiUrl + 'resources/' + userName)
+ },
+ updateUser: function (userName, input) {
+ return request
+ .put(apiUrl + 'resources/' + userName)
+ .set({
+ Authorization: 'Bearer ' + localStorage.getItem('token')
+ })
+ .send(input)
+ },
+ createTeam: function (userName, input) {
+ return request
+ .post(apiUrl + 'resources/' + userName + '/teams')
+ .set({
+ Authorization: 'Bearer ' + localStorage.getItem('token')
+ })
+ .send(input)
+ },
+ addMember: function (userName, input) {
+ return request
+ .post(apiUrl + 'resources/' + userName + '/members')
+ .set({
+ Authorization: 'Bearer ' + localStorage.getItem('token')
+ })
+ .send(input)
+ },
+ removeMember: function (userName, input) {
+ return request
+ .del(apiUrl + 'resources/' + userName + '/members')
+ .set({
+ Authorization: 'Bearer ' + localStorage.getItem('token')
+ })
+ .send(input)
+ },
+ createPlanet: function (userName, input) {
+ return request
+ .post(apiUrl + 'resources/' + userName + '/planets')
+ .set({
+ Authorization: 'Bearer ' + localStorage.getItem('token')
+ })
+ .send(input)
+ },
+ fetchPlanet: function (userName, planetName) {
+ return request
+ .get(apiUrl + 'resources/' + userName + '/planets/' + planetName)
+ },
+ updatePlanet: function (userName, planetName, input) {
+ return request
+ .put(apiUrl + 'resources/' + userName + '/planets/' + planetName)
+ .set({
+ Authorization: 'Bearer ' + localStorage.getItem('token')
+ })
+ .send(input)
+ },
+ destroyPlanet: function (userName, planetName) {
+ return request
+ .del(apiUrl + 'resources/' + userName + '/planets/' + planetName)
+ .set({
+ Authorization: 'Bearer ' + localStorage.getItem('token')
+ })
+ },
+ createCode: function (userName, planetName, input) {
+ return request
+ .post(apiUrl + 'resources/' + userName + '/planets/' + planetName + '/codes')
+ .set({
+ Authorization: 'Bearer ' + localStorage.getItem('token')
+ })
+ .send(input)
+ },
+ updateCode: function (userName, planetName, localId, input) {
+ return request
+ .put(apiUrl + 'resources/' + userName + '/planets/' + planetName + '/codes/' + localId)
+ .set({
+ Authorization: 'Bearer ' + localStorage.getItem('token')
+ })
+ .send(input)
+ },
+ destroyCode: function (userName, planetName, localId) {
+ return request
+ .del(apiUrl + 'resources/' + userName + '/planets/' + planetName + '/codes/' + localId)
+ .set({
+ Authorization: 'Bearer ' + localStorage.getItem('token')
+ })
+ },
+ createNote: function (userName, planetName, input) {
+ return request
+ .post(apiUrl + 'resources/' + userName + '/planets/' + planetName + '/notes')
+ .set({
+ Authorization: 'Bearer ' + localStorage.getItem('token')
+ })
+ .send(input)
+ },
+ updateNote: function (userName, planetName, localId, input) {
+ return request
+ .put(apiUrl + 'resources/' + userName + '/planets/' + planetName + '/notes/' + localId)
+ .set({
+ Authorization: 'Bearer ' + localStorage.getItem('token')
+ })
+ .send(input)
+ },
+ destroyNote: function (userName, planetName, localId) {
+ return request
+ .del(apiUrl + 'resources/' + userName + '/planets/' + planetName + '/notes/' + localId)
+ .set({
+ Authorization: 'Bearer ' + localStorage.getItem('token')
+ })
+ },
+
+ // Search
+ searchTag: function (tagName) {
+ return request
+ .get(apiUrl + 'search/tags')
+ .query({name: tagName})
+ },
+ searchUser: function (userName) {
+ return request
+ .get(apiUrl + 'search/users')
+ .query({name: userName})
+ },
+
+ // Mail
+ sendEmail: function (input) {
+ return request
+ .post(apiUrl + 'mail')
+ .set({
+ Authorization: 'Bearer ' + localStorage.getItem('token')
+ })
+ .send(input)
+ }
+}
diff --git a/browser/main/Stores/AuthStore.js b/browser/main/Stores/AuthStore.js
new file mode 100644
index 00000000..5f64f310
--- /dev/null
+++ b/browser/main/Stores/AuthStore.js
@@ -0,0 +1,131 @@
+/* global localStorage */
+var Reflux = require('reflux')
+var request = require('superagent')
+
+var apiUrl = require('../../../config').apiUrl
+
+var AuthStore = Reflux.createStore({
+ init: function () {
+ },
+ // Reflux Store
+ login: function (input) {
+ request
+ .post(apiUrl + 'auth/login')
+ .send(input)
+ .set('Accept', 'application/json')
+ .end(function (err, res) {
+ if (err) {
+ console.error(err)
+ this.trigger({
+ status: 'failedToLogIn',
+ data: res
+ })
+ return
+ }
+
+ var user = res.body.user
+ localStorage.setItem('token', res.body.token)
+ localStorage.setItem('user', JSON.stringify(res.body.user))
+
+ this.trigger({
+ status: 'loggedIn',
+ data: user
+ })
+ }.bind(this))
+ },
+ register: function (input) {
+ request
+ .post(apiUrl + 'auth/signup')
+ .send(input)
+ .set('Accept', 'application/json')
+ .end(function (err, res) {
+ if (err) {
+ console.error(res)
+ this.trigger({
+ status: 'failedToRegister',
+ data: res
+ })
+ return
+ }
+
+ var user = res.body.user
+ localStorage.setItem('token', res.body.token)
+ localStorage.setItem('user', JSON.stringify(res.body.user))
+
+ this.trigger({
+ status: 'registered',
+ data: user
+ })
+ }.bind(this))
+ },
+ refreshUser: function () {
+ request
+ .get(apiUrl + 'auth/user')
+ .set({
+ Authorization: 'Bearer ' + localStorage.getItem('token')
+ })
+ .end(function (err, res) {
+ if (err) {
+ console.error(err)
+ if (res.status === 401 || res.status === 403) {
+ AuthActions.logout()
+ }
+ return
+ }
+
+ var user = res.body
+ localStorage.setItem('user', JSON.stringify(user))
+
+ this.trigger({
+ status: 'userRefreshed',
+ data: user
+ })
+ }.bind(this))
+ },
+ logout: function () {
+ localStorage.removeItem('token')
+ localStorage.removeItem('currentUser')
+
+ this.trigger({
+ status: 'loggedOut'
+ })
+ },
+ updateProfile: function (input) {
+ request
+ .put(apiUrl + 'auth/user')
+ .set({
+ Authorization: 'Bearer ' + localStorage.getItem('token')
+ })
+ .send(input)
+ .end(function (err, res) {
+ if (err) {
+ console.error(err)
+ this.trigger({
+ status: 'userProfileUpdatingFailed',
+ data: err
+ })
+ return
+ }
+
+ var user = res.body
+ localStorage.setItem('user', JSON.stringify(user))
+
+ this.trigger({
+ status: 'userProfileUpdated',
+ data: user
+ })
+ }.bind(this))
+ },
+ // Methods
+ check: function () {
+ if (localStorage.getItem('token')) return true
+ return false
+ },
+ getUser: function () {
+ var userJSON = localStorage.getItem('currentUser')
+ if (userJSON == null) return null
+ return JSON.parse(userJSON)
+ }
+})
+
+module.exports = AuthStore
diff --git a/browser/main/Stores/PlanetStore.js b/browser/main/Stores/PlanetStore.js
new file mode 100644
index 00000000..f7559876
--- /dev/null
+++ b/browser/main/Stores/PlanetStore.js
@@ -0,0 +1,159 @@
+/* global localStorage */
+
+var Reflux = require('reflux')
+
+var UserStore = require('./UserStore')
+
+var Helper = require('../Mixins/Helper')
+
+var actions = Reflux.createActions([
+ 'update',
+ 'destroy',
+ 'updateCode',
+ 'destroyCode',
+ 'updateNote',
+ 'destroyNote'
+])
+
+module.exports = Reflux.createStore({
+ mixins: [Helper],
+ listenables: [actions],
+ Actions: actions,
+ onUpdate: function (planet) {
+ // Copy the planet object
+ var aPlanet = Object.assign({}, planet)
+ delete aPlanet.Codes
+ delete aPlanet.Notes
+
+ // Check if the planet should be updated to currentUser
+ var currentUser = JSON.parse(localStorage.getItem('currentUser'))
+
+ var ownedByCurrentUser = currentUser.id === aPlanet.OwnerId
+
+ if (ownedByCurrentUser) {
+ currentUser.Planets = this.updateItemToTargetArray(aPlanet, currentUser.Planets)
+ }
+
+ if (!ownedByCurrentUser) {
+ var team = null
+ currentUser.Teams.some(function (_team) {
+ if (_team.id === aPlanet.OwnerId) {
+ team = _team
+ return true
+ }
+ return
+ })
+
+ if (team) {
+ team.Planets = this.updateItemToTargetArray(aPlanet, team.Planets)
+ }
+ }
+
+ // Update currentUser
+ localStorage.setItem('currentUser', JSON.stringify(currentUser))
+ UserStore.Actions.update(currentUser)
+
+ // Update the planet
+ localStorage.setItem('planet-' + planet.id, JSON.stringify(planet))
+
+ this.trigger({
+ status: 'updated',
+ data: planet
+ })
+ },
+ onDestroy: function (planet) {
+ // Check if the planet should be updated to currentUser
+ var currentUser = JSON.parse(localStorage.getItem('currentUser'))
+
+ var ownedByCurrentUser = currentUser.id === planet.OwnerId
+
+ if (ownedByCurrentUser) {
+ currentUser.Planets = this.deleteItemFromTargetArray(planet, currentUser.Planets)
+ }
+
+ if (!ownedByCurrentUser) {
+ var team = null
+ currentUser.Teams.some(function (_team) {
+ if (_team.id === planet.OwnerId) {
+ team = _team
+ return true
+ }
+ return
+ })
+
+ if (team) {
+ team.Planets = this.deleteItemFromTargetArray(planet, team.Planets)
+ }
+ }
+
+ // Update currentUser
+ localStorage.setItem('currentUser', JSON.stringify(currentUser))
+ UserStore.Actions.update(currentUser)
+
+ // Update the planet
+ localStorage.setItem('planet-' + planet.id, JSON.stringify(planet))
+
+ this.trigger({
+ status: 'destroyed',
+ data: planet
+ })
+ },
+ onUpdateCode: function (code) {
+ code.type = 'code'
+
+ var planet = JSON.parse(localStorage.getItem('planet-' + code.PlanetId))
+ if (planet != null) {
+ planet.Codes = this.updateItemToTargetArray(code, planet.Codes)
+
+ localStorage.setItem('planet-' + code.PlanetId, JSON.stringify(planet))
+ }
+
+ this.trigger({
+ status: 'codeUpdated',
+ data: code
+ })
+ },
+ onDestroyCode: function (code) {
+ var planet = JSON.parse(localStorage.getItem('planet-' + code.PlanetId))
+ if (planet != null) {
+ planet.Codes = this.deleteItemFromTargetArray(code, planet.Codes)
+
+ localStorage.setItem('planet-' + code.PlanetId, JSON.stringify(planet))
+ }
+ code.type = 'code'
+
+ this.trigger({
+ status: 'codeDestroyed',
+ data: code
+ })
+ },
+ onUpdateNote: function (note) {
+ note.type = 'note'
+
+ var planet = JSON.parse(localStorage.getItem('planet-' + note.PlanetId))
+ if (planet != null) {
+ planet.Notes = this.updateItemToTargetArray(note, planet.Notes)
+
+ localStorage.setItem('planet-' + note.PlanetId, JSON.stringify(planet))
+ }
+
+ this.trigger({
+ status: 'noteUpdated',
+ data: note
+ })
+ },
+ onDestroyNote: function (note) {
+ var planet = JSON.parse(localStorage.getItem('planet-' + note.PlanetId))
+ if (planet != null) {
+ planet.Notes = this.deleteItemFromTargetArray(note, planet.Notes)
+
+ localStorage.setItem('planet-' + note.PlanetId, JSON.stringify(planet))
+ }
+ note.type = 'note'
+
+ this.trigger({
+ status: 'noteDestroyed',
+ data: note
+ })
+ }
+})
diff --git a/browser/main/Stores/UserStore.js b/browser/main/Stores/UserStore.js
new file mode 100644
index 00000000..de8a74e5
--- /dev/null
+++ b/browser/main/Stores/UserStore.js
@@ -0,0 +1,69 @@
+/* global localStorage */
+
+var Reflux = require('reflux')
+
+var actions = Reflux.createActions([
+ 'update',
+ 'destroy',
+ 'addMember',
+ 'removeMember'
+])
+
+module.exports = Reflux.createStore({
+ listenables: [actions],
+ onUpdate: function (user) {
+ var currentUser = JSON.parse(localStorage.getItem('currentUser'))
+
+ if (currentUser.id === user.id) {
+ localStorage.setItem('currentUser', JSON.stringify(user))
+ }
+
+ if (user.userType === 'team') {
+ var isMyTeam = user.Members.some(function (member) {
+ if (currentUser.id === member.id) {
+ return true
+ }
+ return false
+ })
+
+ if (isMyTeam) {
+ var isNew = !currentUser.Teams.some(function (team, index) {
+ if (user.id === team.id) {
+ currentUser.Teams.splice(index, 1, user)
+ return true
+ }
+ return false
+ })
+
+ if (isNew) {
+ currentUser.Teams.push(user)
+ }
+ localStorage.setItem('currentUser', JSON.stringify(currentUser))
+ }
+ }
+
+ this.trigger({
+ status: 'userUpdated',
+ data: user
+ })
+ },
+ onDestroy: function (user) {
+ this.trigger({
+ status: 'userDestroyed',
+ data: user
+ })
+ },
+ onAddMember: function (member) {
+ this.trigger({
+ status: 'memberAdded',
+ data: member
+ })
+ },
+ onRemoveMember: function (member) {
+ this.trigger({
+ status: 'memberRemoved',
+ data: member
+ })
+ },
+ Actions: actions
+})
diff --git a/browser/main/favicon.ico b/browser/main/favicon.ico
new file mode 100644
index 00000000..ad6a19a4
Binary files /dev/null and b/browser/main/favicon.ico differ
diff --git a/browser/main/index.electron.html b/browser/main/index.electron.html
new file mode 100644
index 00000000..3ebc2ab6
--- /dev/null
+++ b/browser/main/index.electron.html
@@ -0,0 +1,59 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/browser/main/index.html b/browser/main/index.html
new file mode 100644
index 00000000..243ec598
--- /dev/null
+++ b/browser/main/index.html
@@ -0,0 +1,56 @@
+
+
+
+ CodeXen
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/browser/main/index.jsx b/browser/main/index.jsx
new file mode 100644
index 00000000..f8f26e81
--- /dev/null
+++ b/browser/main/index.jsx
@@ -0,0 +1,40 @@
+var React = require('react/addons')
+
+var ReactRouter = require('react-router')
+var Route = ReactRouter.Route
+var DefaultRoute = ReactRouter.DefaultRoute
+
+var MainContainer = require('./Containers/MainContainer')
+
+var LoginContainer = require('./Containers/LoginContainer')
+var SignupContainer = require('./Containers/SignupContainer')
+
+var HomeContainer = require('./Containers/HomeContainer')
+var UserContainer = require('./Containers/UserContainer')
+
+var PlanetContainer = require('./Containers/PlanetContainer')
+
+var routes = (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+)
+
+ReactRouter.run(routes, ReactRouter.HashLocation, function (Root) {
+ React.render(, document.getElementById('content'))
+})
diff --git a/browser/main/resources/favicon-230x230.png b/browser/main/resources/favicon-230x230.png
new file mode 100644
index 00000000..ee3bcee9
Binary files /dev/null and b/browser/main/resources/favicon-230x230.png differ
diff --git a/browser/main/style.js b/browser/main/style.js
new file mode 100644
index 00000000..dd1009a9
--- /dev/null
+++ b/browser/main/style.js
@@ -0,0 +1,2 @@
+require('../styles/main/index.styl')
+require('react-select/dist/default.css')
diff --git a/browser/styles/finder/index.styl b/browser/styles/finder/index.styl
new file mode 100644
index 00000000..3d1d0060
--- /dev/null
+++ b/browser/styles/finder/index.styl
@@ -0,0 +1,78 @@
+@import '../../../node_modules/nib/lib/nib'
+@import '../vars'
+@import '../mixins/*'
+global-reset()
+@import '../shared/*'
+
+body
+ font-family "Lato"
+ color textColor
+ font-size fontSize
+
+.Finder
+ absolute top bottom left right
+ .FinderInput
+ position absolute
+ top 11px
+ left 11px
+ right 11px
+ margin 0 auto
+ height 44px
+ box-sizing border-box
+ border-bottom solid 1px borderColor
+ input
+ display block
+ width 100%
+ border solid 1px borderColor
+ padding 0 10px
+ font-size 1em
+ height 33px
+ border-radius 5px
+ box-sizing border-box
+ border-radius 16.5px
+ &:focus, &.focus
+ border-color brandBorderColor
+ outline none
+ .FinderList
+ absolute left bottom
+ top 55px
+ border-right solid 1px borderColor
+ box-sizing border-box
+ width 250px
+ overflow-y auto
+ &>ul>li
+ .articleItem
+ padding 10px
+ border solid 2px transparent
+ box-sizing border-box
+ cursor pointer
+ .divider
+ box-sizing border-box
+ border-bottom solid 1px borderColor
+ &.active
+ .articleItem
+ border-color brandColor
+
+ .FinderDetail
+ absolute right bottom
+ top 55px
+ left 250px
+ .header
+ absolute top left right
+ height 44px
+ box-sizing border-box
+ padding 0 10px
+ border-bottom solid 1px borderColor
+ line-height 44px
+ font-size 1.3em
+ .content
+ .ace_editor, .marked
+ position absolute
+ top 49px
+ left 5px
+ right 5px
+ bottom 5px
+ box-sizing border-box
+ .marked
+ marked()
+ overflow-y auto
diff --git a/browser/styles/main/components/Select.styl b/browser/styles/main/components/Select.styl
new file mode 100644
index 00000000..08265706
--- /dev/null
+++ b/browser/styles/main/components/Select.styl
@@ -0,0 +1,260 @@
+/**
+ * React Select
+ * ============
+ * Created by Jed Watson and Joss Mackison for KeystoneJS, http://www.keystonejs.com/
+ * https://twitter.com/jedwatson https://twitter.com/jossmackison https://twitter.com/keystonejs
+ * MIT License: https://github.com/keystonejs/react-select
+*/
+.Select {
+ position: relative;
+}
+.Select-control {
+ position: relative;
+ overflow: hidden;
+ background-color: #ffffff;
+ border: 1px solid #cccccc;
+ border-color: #d9d9d9 #cccccc #b3b3b3;
+ border-radius: 4px;
+ box-sizing: border-box;
+ color: #333333;
+ cursor: default;
+ outline: none;
+ padding: 8px 52px 8px 10px;
+ transition: all 200ms ease;
+}
+.Select-control:hover {
+ box-shadow: 0 1px 0 rgba(0, 0, 0, 0.06);
+}
+.is-searchable.is-open > .Select-control {
+ cursor: text;
+}
+.is-open > .Select-control {
+ border-bottom-right-radius: 0;
+ border-bottom-left-radius: 0;
+ background: #ffffff;
+ border-color: #b3b3b3 #cccccc #d9d9d9;
+}
+.is-open > .Select-control > .Select-arrow {
+ border-color: transparent transparent #999999;
+ border-width: 0 5px 5px;
+}
+.is-searchable.is-focused:not(.is-open) > .Select-control {
+ cursor: text;
+}
+.is-focused:not(.is-open) > .Select-control {
+ border-color: #0088cc #0099e6 #0099e6;
+ box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1), 0 0 5px -1px rgba(0, 136, 204, 0.5);
+}
+.Select-placeholder {
+ color: #aaaaaa;
+ padding: 8px 52px 8px 10px;
+ position: absolute;
+ top: 0;
+ left: 0;
+ right: -15px;
+ max-width: 100%;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+}
+.has-value > .Select-control > .Select-placeholder {
+ color: #333333;
+}
+.Select-input > input {
+ cursor: default;
+ background: none transparent;
+ box-shadow: none;
+ height: auto;
+ border: 0 none;
+ font-family: inherit;
+ font-size: inherit;
+ margin: 0;
+ padding: 0;
+ outline: none;
+ display: inline-block;
+ -webkit-appearance: none;
+}
+.is-focused .Select-input > input {
+ cursor: text;
+}
+.Select-control:not(.is-searchable) > .Select-input {
+ outline: none;
+}
+.Select-loading {
+ -webkit-animation: Select-animation-spin 400ms infinite linear;
+ -o-animation: Select-animation-spin 400ms infinite linear;
+ animation: Select-animation-spin 400ms infinite linear;
+ width: 16px;
+ height: 16px;
+ box-sizing: border-box;
+ border-radius: 50%;
+ border: 2px solid #cccccc;
+ border-right-color: #333333;
+ display: inline-block;
+ position: relative;
+ margin-top: -8px;
+ position: absolute;
+ right: 30px;
+ top: 50%;
+}
+.has-value > .Select-control > .Select-loading {
+ right: 46px;
+}
+.Select-clear {
+ color: #999999;
+ cursor: pointer;
+ display: inline-block;
+ font-size: 16px;
+ padding: 6px 10px;
+ position: absolute;
+ right: 17px;
+ top: 0;
+}
+.Select-clear:hover {
+ color: #c0392b;
+}
+.Select-clear > span {
+ font-size: 1.1em;
+}
+.Select-arrow-zone {
+ content: " ";
+ display: block;
+ position: absolute;
+ right: 0;
+ top: 0;
+ bottom: 0;
+ width: 30px;
+ cursor: pointer;
+}
+.Select-arrow {
+ border-color: #999999 transparent transparent;
+ border-style: solid;
+ border-width: 5px 5px 0;
+ content: " ";
+ display: block;
+ height: 0;
+ margin-top: -ceil(2.5px);
+ position: absolute;
+ right: 10px;
+ top: 14px;
+ width: 0;
+ cursor: pointer;
+}
+.Select-menu-outer {
+ border-bottom-right-radius: 4px;
+ border-bottom-left-radius: 4px;
+ background-color: #ffffff;
+ border: 1px solid #cccccc;
+ border-top-color: #e6e6e6;
+ box-shadow: 0 1px 0 rgba(0, 0, 0, 0.06);
+ box-sizing: border-box;
+ margin-top: -1px;
+ max-height: 200px;
+ position: absolute;
+ top: 100%;
+ width: 100%;
+ z-index: 1000;
+ -webkit-overflow-scrolling: touch;
+}
+.Select-menu {
+ max-height: 198px;
+ overflow-y: auto;
+}
+.Select-option {
+ box-sizing: border-box;
+ color: #666666;
+ cursor: pointer;
+ display: block;
+ padding: 8px 10px;
+}
+.Select-option:last-child {
+ border-bottom-right-radius: 4px;
+ border-bottom-left-radius: 4px;
+}
+.Select-option.is-focused {
+ background-color: #f2f9fc;
+ color: #333333;
+}
+.Select-option.is-disabled {
+ color: #cccccc;
+ cursor: not-allowed;
+}
+.Select-noresults {
+ box-sizing: border-box;
+ color: #999999;
+ cursor: default;
+ display: block;
+ padding: 8px 10px;
+}
+.Select.is-multi .Select-control {
+ padding: 2px 52px 2px 3px;
+}
+.Select.is-multi .Select-input {
+ vertical-align: middle;
+ border: 1px solid transparent;
+ margin: 2px;
+ padding: 3px 0;
+}
+.Select-item {
+ background-color: #f2f9fc;
+ border-radius: 2px;
+ border: 1px solid #c9e6f2;
+ color: #0088cc;
+ display: inline-block;
+ font-size: 1em;
+ margin: 2px;
+}
+.Select-item-icon,
+.Select-item-label {
+ display: inline-block;
+ vertical-align: middle;
+}
+.Select-item-label {
+ cursor: default;
+ border-bottom-right-radius: 2px;
+ border-top-right-radius: 2px;
+ padding: 3px 5px;
+}
+.Select-item-label .Select-item-label__a {
+ color: #0088cc;
+ cursor: pointer;
+}
+.Select-item-icon {
+ cursor: pointer;
+ border-bottom-left-radius: 2px;
+ border-top-left-radius: 2px;
+ border-right: 1px solid #c9e6f2;
+ padding: 2px 5px 4px;
+}
+.Select-item-icon:hover,
+.Select-item-icon:focus {
+ background-color: #ddeff7;
+ color: #0077b3;
+}
+.Select-item-icon:active {
+ background-color: #c9e6f2;
+}
+.Select.is-multi.is-disabled .Select-item {
+ background-color: #f2f2f2;
+ border: 1px solid #d9d9d9;
+ color: #888888;
+}
+.Select.is-multi.is-disabled .Select-item-icon {
+ cursor: not-allowed;
+ border-right: 1px solid #d9d9d9;
+}
+.Select.is-multi.is-disabled .Select-item-icon:hover,
+.Select.is-multi.is-disabled .Select-item-icon:focus,
+.Select.is-multi.is-disabled .Select-item-icon:active {
+ background-color: #f2f2f2;
+}
+@keyframes Select-animation-spin {
+ to {
+ transform: rotate(1turn);
+ }
+}
+@-webkit-keyframes Select-animation-spin {
+ to {
+ -webkit-transform: rotate(1turn);
+ }
+}
diff --git a/browser/styles/main/containers/LoginContainer.styl b/browser/styles/main/containers/LoginContainer.styl
new file mode 100644
index 00000000..c190cf44
--- /dev/null
+++ b/browser/styles/main/containers/LoginContainer.styl
@@ -0,0 +1,82 @@
+.LoginContainer, .SignupContainer
+ margin 0 auto
+ padding 25px 15px
+ box-sizing border-box
+ color inactiveTextColor
+ .logo
+ width 150px
+ height 150px
+ display block
+ margin 0 auto
+ .authNavigator
+ margin 15px 0 25px
+ a
+ font-size 1.5em
+ text-decoration none
+ color inactiveTextColor
+ &:hover, &.hover, &:active, &.active
+ color brandColor
+ .socialControl
+ text-align center
+ margin 25px 0
+ p
+ margin-bottom 25px
+ .facebookBtn, .githubBtn
+ margin 0 45px
+ width 50px
+ height 50px
+ line-height 50px
+ font-size 25px
+ text-align center
+ background-image none
+ color white
+ border none
+ border-radius 25px
+ cursor pointer
+ .facebookBtn
+ background-color facebookColor
+ &:hover, &.hover
+ background-color lighten(facebookColor, 25%)
+ .githubBtn
+ background-color githubBtn
+ font-size 30px
+ line-height 30px
+ &:hover, &.hover
+ background-color lighten(githubBtn, 25%)
+ .divider
+ .dividerLabel
+ text-align center
+ position relative
+ top -27px
+ font-size 1.3em
+ background-color backgroundColor
+ margin 0 auto
+ width 50px
+ form
+ width 400px
+ margin 0 auto 45px
+ .alertInfo, .alertError
+ margin-top 15px
+ margin-bottom 15px
+ height 44px
+ padding 5px
+ border-radius 10px
+ line-height 44px
+ text-align center
+ .alertInfo
+ alertInfo()
+ .alertError
+ alertError()
+ div.form-group:last-child
+ margin-top 15px
+ button.logInButton
+ btnPrimary()
+ height 44px
+ border-radius 22px
+ display block
+ width 200px
+ font-size 1em
+ margin 0 auto
+ p.alert
+ text-align center
+ font-size 0.8em
diff --git a/browser/styles/main/containers/PlanetContainer.styl b/browser/styles/main/containers/PlanetContainer.styl
new file mode 100644
index 00000000..276fd180
--- /dev/null
+++ b/browser/styles/main/containers/PlanetContainer.styl
@@ -0,0 +1,274 @@
+navigationWidth= 200px
+articleListWidth= 275px
+
+.PlanetContainer
+ absolute top bottom right left
+ .tags
+ white-space: nowrap;
+ overflow-x: auto;
+ a
+ margin 0 2px
+ text-decoration underline
+ cursor pointer
+ font-size 0.9em
+ &.noTag
+ color inactiveTextColor
+ font-size 0.8em
+
+.PlanetHeader
+ absolute left right top
+ overflow-y hidden
+ height 55px
+ background-color white
+ border-bottom solid 1px borderColor
+ box-sizing border-box
+ padding 5px 15px
+ clearfix()
+ .headerLabel
+ noSelect()
+ absolute top left bottom
+ overflow hidden
+ display inline-block
+ width navigationWidth
+ .userName
+ position absolute
+ left 15px
+ top 30px
+ width 140px
+ font-size 1em
+ color textColor
+ text-decoration none
+ &:hover
+ color darken(lightButtonColor, 50%)
+ text-decoration underline
+ .planetName
+ position absolute
+ top 5px
+ left 10px
+ width 145px
+ font-size 1.6em
+ color brandColor
+ overflow hidden
+ text-overflow ellipsis
+ white-space nowrap
+ &:hover
+ color darken(brandBorderColor, 30%)
+ .private
+ position absolute
+ top 12px
+ right 38px
+ width 33px
+ height 33px
+ line-height 33px
+ text-align center
+ color inactiveColor
+ &:hover
+ color textColor
+ .privateTooltip
+ position fixed
+ z-index popupZIndex
+ background-color transparentify(invBackgroundColor, 80%)
+ color invTextColor
+ padding 10px
+ font-size 0.9em
+ line-height 0.9em
+ border-radius 5px
+ white-space nowrap
+ opacity 0
+ transition 0.1s
+ pointer-events none
+ margin-left -30px
+ &:hover .privateTooltip
+ opacity 1
+
+
+ .menuBtn
+ position absolute
+ top 12px
+ right 5px
+ font-size 1em
+ btnDefault()
+ box-sizing border-box
+ circle()
+ width 33px
+ height 33px
+ text-align center
+ cursor pointer
+ transition 0.1s
+ transform scale(0.8)
+ &:focus, &.focus
+ outline none
+ .headerControl
+ noSelect()
+ absolute top bottom right
+ left navigationWidth
+ .searchInput
+ display block
+ position absolute
+ top 12px
+ left 0
+ input
+ padding-left 32px
+ width 300px
+ .fa
+ position absolute
+ top 8px
+ left 12px
+ color inactiveTextColor
+ .refreshButton
+ display block
+ position absolute
+ top 12px
+ right 55px
+ width 28px
+ height 28px
+ btnDefault()
+ circle()
+ text-align center
+ cursor pointer
+ transition 0.1s
+ &:focus, &.focus
+ outline none
+ .logo
+ display block
+ position absolute
+ top 4px
+ right 10px
+ cursor pointer
+ transition 0.1s
+ opacity 0.9
+ &:hover, &.hover
+ opacity 1
+
+.PlanetNavigator
+ absolute bottom left
+ noSelect()
+ top 55px
+ width navigationWidth
+ border-right solid 1px highlightenBorderColor
+ padding 10px
+ box-sizing border-box
+ .launchButton
+ border-radius 22px
+ font-size 1.1em
+ nav
+ a
+ display block
+ box-sizing border-box
+ padding 15px 15px
+ margin 10px 0
+ border-radius 10px
+ text-decoration none
+ background-color transparent
+ color textColor
+ cursor pointer
+ transition 0.1s
+ btnDefault()
+ border none
+
+.PlanetArticleList
+ absolute bottom right
+ left navigationWidth
+ top 55px
+ width articleListWidth
+ border-right solid 1px highlightenBorderColor
+
+ &>ul
+ absolute top bottom left right
+ overflow-y auto
+ li
+ .articleItem
+ user-select none
+ border solid 2px transparent
+ padding 10px
+ cursor pointer
+ transition 0.1s
+ clearfix()
+ .itemLeft
+ float left
+ width 25px
+ text-align center
+ .profileImage
+ margin-bottom 5px
+ .fa
+ line-height 25px
+ .itemRight
+ float left
+ width 225px
+ overflow-x hidden
+ padding-left 10px
+ .updatedAt
+ margin-bottom 10px
+ color lighten(textColor, 25%)
+ font-size 0.7em
+ .description
+ line-height 120%
+ margin-bottom 15px
+ font-size 1em
+ &:hover, &.hover
+ background-color hoverBackgroundColor
+ &:active, &.active
+ background-color white
+ &:active, &.active
+ border-color brandBorderColor
+ .divider
+ border-bottom solid 1px borderColor
+
+.PlanetArticleDetail
+ absolute right bottom
+ top 55px
+ left navigationWidth + articleListWidth
+ &>.viewer-header
+ height 44px
+ line-height 44px
+ padding 0 15px
+ box-sizing border-box
+ font-size 1.2em
+ small
+ font-size 0.8em
+ color lighten(textColor, 25%)
+ .control-group
+ float right
+ button
+ margin 10px 3px
+ .viewer-body
+ absolute bottom right
+ left 1px
+ top 44px
+ &.codeDetail>.viewer-body
+ .viewer-detail
+ border-bottom solid 1px borderColor
+ height 150px
+ box-sizing border-box
+ padding 10px
+ .description
+ height 100px
+ line-height 1.4em
+ overflow-y auto
+ .tags
+ position absolute
+ left 15px
+ right 15px
+ top 120px
+ .content
+ .ace_editor
+ absolute left right
+ top 155px
+ bottom 5px
+ &.noteDetail>.viewer-body
+ .tags
+ absolute top
+ left 15px
+ right 15px
+ height 24px
+ line-height 24px
+ .content
+ absolute left right bottom
+ top 30px
+ box-sizing border-box
+ padding 5px
+ border-top solid 1px borderColor
+ padding 10px
+ overflow-x hidden
+ overflow-y auto
+ marked()
diff --git a/browser/styles/main/containers/UserContainer.styl b/browser/styles/main/containers/UserContainer.styl
new file mode 100644
index 00000000..bb192611
--- /dev/null
+++ b/browser/styles/main/containers/UserContainer.styl
@@ -0,0 +1,319 @@
+.HomeContainer
+ .HomeNavigator
+ background-color planetNavBgColor
+ absolute left top bottom
+ width 55px
+ text-align center
+ box-sizing border-box
+ border-right solid 1px borderColor
+ .profileButton
+ display block
+ width 55px
+ height 55px
+ border-bottom solid 1px borderColor
+ overflow hidden
+ background-color black
+ margin 0
+ padding 0
+ cursor pointer
+ box-sizing border-box
+ border none
+ img
+ transition 0.1s
+ opacity 0.9
+ &.vivid.active, &.focus, &:focus, &.hover, &:hover
+ img
+ opacity 1
+ .profilePopup
+ position fixed
+ left 35px
+ top 35px
+ z-index popupZIndex
+ width 200px
+ background-color backgroundColor
+ box-shadow popupShadow
+ border-radius 10px
+ padding 10px 0 0px
+ &.close
+ display none
+ .profileGroup
+ margin-bottom 10px
+ .profileGroupLabel
+ text-align left
+ height 1em
+ padding 0 15px
+ span
+ position absolute
+ z-index 2
+ background-color backgroundColor
+ padding-right 5px
+ color inactiveTextColor
+ font-size 0.8em
+ &::before
+ content ''
+ position absolute
+ display block
+ z-index 1
+ height 0.5em
+ width 175px
+ border-bottom solid 1px borderColor
+ .profileGroupList
+ li
+ clearfix()
+ &:hover
+ background-color hoverBackgroundColor
+ .userName
+ float left
+ width 155px
+ padding 10px 15px
+ text-align left
+ display block
+ text-decoration none
+ cursor pointer
+ .userSetting
+ float right
+ display block
+ padding 10px 0
+ width 45px
+ cursor pointer
+ .createNewTeam
+ btnStripDefault()
+ width 100%
+ padding 10px 20px
+ font-size 1em
+ cursor pointer
+ text-align left
+ .controlGroup
+ list-style none
+ border-top solid 1px borderColor
+ padding 10px 0
+ li
+ &:hover
+ background-color hoverBackgroundColor
+ button
+ btnStripDefault()
+ width 100%
+ padding 10px 20px
+ font-size 1em
+ cursor pointer
+ text-align left
+
+ ul.planetList>li
+ margin 15px 0
+ .shortCut
+ margin-top 5px
+ color lighten(textColor, 5%)
+ font-size 0.8em
+ &.active
+ a
+ background-color planetAnchorActiveBgColor
+ color planetAnchorActiveColor
+ a
+ display block
+ width 44px
+ height 44px
+ margin 0 auto
+ text-align center
+ background-color planetAnchorBgColor
+ text-decoration none
+ color planetAnchorColor
+ line-height 44px
+ font-size 1.1em
+ cursor pointer
+ circle()
+ transition 0.1s
+ &:hover, &:active
+ background-color white
+ .planetTooltip
+ position absolute
+ z-index popupZIndex
+ background-color transparentify(invBackgroundColor, 80%)
+ color invTextColor
+ padding 10px
+ line-height 1em
+ border-radius 5px
+ margin-top -41px
+ margin-left 52px
+ white-space nowrap
+ opacity 0
+ transition 0.1s
+ pointer-events none
+ &:hover .planetTooltip
+ opacity 1
+ img
+ circle()
+ width 55px
+ height 55px
+ button.newPlanet
+ display block
+ margin 0 auto
+ width 30px
+ height 30px
+ circle()
+ border solid 1px lightButtonColor
+ color lightButtonColor
+ text-align center
+ font-size 1
+ background-image none
+ background-color transparent
+ box-sizing border-box
+ absolute left bottom right
+ bottom 15px
+ &:hover, &.hover, &:focus, &.focus
+ border-color darken(lightButtonColor, 50%)
+ color darken(lightButtonColor, 50%)
+ &:active, &.active
+ border-color darken(brandBorderColor, 10%)
+ background-color brandColor
+ color white
+ .newPlanetTooltip
+ position fixed
+ z-index 500
+ background-color transparentify(invBackgroundColor, 80%)
+ color invTextColor
+ padding 10px
+ line-height 1em
+ border-radius 5px
+ margin-top -23px
+ margin-left 33px
+ white-space nowrap
+ font-size 1.1em
+ opacity 0
+ transition 0.1s
+ pointer-events none
+ &:hover .newPlanetTooltip
+ opacity 1
+ .UserContainer
+ absolute top bottom right
+ left 55px
+ .memberPopup
+ absolute left
+ top 235px
+ z-index popupZIndex
+ padding 0 15px 10px
+ width 200px
+ .label
+ padding 10px 0
+ font-size 0.9em
+ border-bottom solid 1px borderColor
+ margin-bottom 15px
+ .members
+ li
+ padding 0 10px
+ margin-bottom 15px
+ clearfix()
+ .memberImage
+ float left
+ margin-right 7px
+ .memberInfo
+ float left
+ .memberProfileName
+ margin-bottom 5px
+ .memberName
+ margin-left 5px
+ font-size 0.8em
+ color inactiveTextColor
+ a:hover .memberProfileName, a:hover .memberName
+ text-decoration underline
+ .userProfile
+ absolute top left right
+ padding 15px
+ border-bottom solid 1px borderColor
+ height 125px
+ clearfix()
+ .userPhoto
+ circle()
+ float left
+ margin 5px 15px 15px
+ .userInfo
+ float left
+ margin-top 15px
+ .userProfileName
+ font-size 1.5em
+ color brandColor
+ margin-bottom 10px
+ .userName
+ font-size 1.1em
+ .editProfileButton
+ float right
+ btnDefault()
+ margin-top 25px
+ padding 10px 15px
+ border-radius 5px
+ .teamList, .memberList
+ absolute left bottom
+ top 125px
+ width 200px
+ padding 15px
+ border-right solid 1px borderColor
+ overflow-y auto
+ .teamLabel, .memberLabel
+ font-size 1.2em
+ margin-bottom 15px
+ .teams
+ li
+ padding 0 10px
+ margin-bottom 15px
+ clearfix()
+ .teamInfo
+ float left
+ .teamProfileName
+ margin-bottom 5px
+ .teamName
+ margin-left 5px
+ font-size 0.8em
+ color inactiveTextColor
+ a:hover .teamProfileName, a:hover .teamName
+ text-decoration underline
+ margin-bottom 10px
+ font-size 1.1em
+ .createTeamButton, .addMemberButton
+ btnStripDefault()
+ .members
+ li
+ padding 0 10px
+ margin-bottom 15px
+ clearfix()
+ .memberImage
+ float left
+ margin-right 7px
+ .memberInfo
+ float left
+ .memberProfileName
+ margin-bottom 5px
+ .memberRole
+ font-size 0.8em
+ color inactiveTextColor
+ .memberName
+ margin-left 5px
+ font-size 0.8em
+ color inactiveTextColor
+ .createTeamButton, .addMemberButton
+ btnStripDefault()
+ a:hover .memberProfileName, a:hover .memberName
+ text-decoration underline
+ .planetList
+ absolute right bottom
+ top 125px
+ left 200px
+ padding 15px
+ overflow-y auto
+ .planetLabel
+ font-size 1.2em
+ margin-bottom 15px
+ .planetGroup
+ margin-left 15px
+ .planetGroupLabel
+ font-size 1.1em
+ margin-bottom 15px
+ .planets
+ margin-left 15px
+ li
+ a
+ font-size 1.1em
+ text-decoration none
+ &:hover
+ text-decoration underline
+ margin-bottom 10px
+ .createPlanetButton
+ btnStripDefault()
diff --git a/browser/styles/main/index.styl b/browser/styles/main/index.styl
new file mode 100644
index 00000000..0a54beeb
--- /dev/null
+++ b/browser/styles/main/index.styl
@@ -0,0 +1,118 @@
+@import '../../../node_modules/nib/lib/nib'
+@import '../vars'
+@import '../mixins/*'
+global-reset()
+@import '../shared/*'
+@import './components/*'
+@import './containers/*'
+
+html, body
+ width 100%
+ height 100%
+ overflow hidden
+
+body
+ font-family "Lato"
+ color textColor
+ font-size fontSize
+ font-weight 400
+
+div, span, a, button, input, textarea
+ box-sizing border-box
+
+h1
+ font-size 2em
+h2
+ font-size 1.5em
+h3
+ font-size 1.17em
+h4
+ font-size 1em
+h5
+ font-size 0.83em
+h6
+ font-size 0.67em
+a
+ color brandColor
+ &:hover
+ color darken(brandColor, 15%)
+ &:visited
+ color brandColor
+
+hr
+ border-top none
+ border-bottom solid 1px borderColor
+ margin 15px 0
+
+button
+ font-weight 400
+ cursor pointer
+ &:focus, &.focus
+ outline none
+
+.text-center
+ text-align center
+
+.form-group
+ margin-bottom 15px
+ &>label
+ display block
+ margin-bottom 5px
+
+.stripInput
+ stripInput()
+ display block
+ width 100%
+ font-size 1em
+ height 33px
+
+.block-input, .inline-input
+ border solid 1px borderColor
+ padding 0 10px
+ font-size 1em
+ height 33px
+ border-radius 5px
+ box-sizing border-box
+ &:focus, &.focus
+ border solid 1px brandBorderColor
+ outline none
+ &.circleInput
+ border-radius 16.5px
+
+.block-input
+ display block
+ width 100%
+
+.inline-input
+ display inline-block
+ margin-right 5px
+
+.relative
+ position relative
+
+textarea.block-input
+ resize vertical
+ height 125px
+ border-radius 5px
+ padding 5px 10px
+
+#content
+ fullsize()
+
+.Main
+ .appUpdateButton
+ position fixed
+ z-index 2000
+ bottom 5px
+ right 53px
+ btnDefault()
+ padding 10px 15px
+ border-radius 5px
+ .contactButton
+ position fixed
+ z-index 2000
+ bottom 5px
+ right 5px
+ btnDefault()
+ padding 10px 15px
+ border-radius 5px
diff --git a/browser/styles/mixins/alert.styl b/browser/styles/mixins/alert.styl
new file mode 100644
index 00000000..59423747
--- /dev/null
+++ b/browser/styles/mixins/alert.styl
@@ -0,0 +1,11 @@
+alertSuccess()
+ background-color successBackgroundColor
+ color successTextColor
+
+alertError()
+ background-color errorBackgroundColor
+ color errorTextColor
+
+alertInfo()
+ background-color infoBackgroundColor
+ color infoTextColor
diff --git a/browser/styles/mixins/btn.styl b/browser/styles/mixins/btn.styl
new file mode 100644
index 00000000..fad6d60f
--- /dev/null
+++ b/browser/styles/mixins/btn.styl
@@ -0,0 +1,40 @@
+btnDefault()
+ border-style solid
+ border-width 1px
+ border-color lightButtonColor
+ background-color transparent
+ color lightButtonColor
+
+ &:hover, &.hover, &:focus, &.focus
+ border-color darken(lightButtonColor, 50%)
+ color darken(lightButtonColor, 50%)
+ &:active, &.active
+ border-color darken(brandBorderColor, 10%)
+ background-color brandColor
+ color white
+ &:disabled, &.disabled
+ opacity 0.6
+
+btnPrimary()
+ border-style solid
+ border-width 1px
+ border-color brandBorderColor
+ background-color transparent
+ color brandColor
+ &:hover, &.hover, &:focus, &.focus
+ border-color darken(brandBorderColor, 30%)
+ color darken(brandColor, 30%)
+ &:active, &.active
+ background-color brandColor
+ color white
+ &:disabled, &.disabled
+ opacity 0.6
+
+btnStripDefault()
+ border none
+ background-color transparent
+ color lightButtonColor
+ &:hover, &.hover, &:focus, &.focus
+ color darken(lightButtonColor, 50%)
+ &:active, &.active
+ color brandColor
diff --git a/browser/styles/mixins/circle.styl b/browser/styles/mixins/circle.styl
new file mode 100644
index 00000000..b20e891b
--- /dev/null
+++ b/browser/styles/mixins/circle.styl
@@ -0,0 +1,3 @@
+circle()
+ border-radius 50%
+ overflow hidden
diff --git a/browser/styles/mixins/fullsize.styl b/browser/styles/mixins/fullsize.styl
new file mode 100644
index 00000000..98866c01
--- /dev/null
+++ b/browser/styles/mixins/fullsize.styl
@@ -0,0 +1,6 @@
+fullsize()
+ position absolute
+ top 0
+ left 0
+ right 0
+ bottom 0
diff --git a/browser/styles/mixins/input.styl b/browser/styles/mixins/input.styl
new file mode 100644
index 00000000..186d96c0
--- /dev/null
+++ b/browser/styles/mixins/input.styl
@@ -0,0 +1,16 @@
+stripInput()
+ border none
+ border-bottom 1px solid borderColor
+ padding 5px 15px
+ transition 0.1s
+ &:focus, &.focus
+ border-bottom 1px solid brandBorderColor
+ outline none
+
+borderInput()
+ border solid 1px borderColor
+ padding 5px 15px
+ transition 0.1s
+ &:focus, &.focus
+ border-color brandBorderColor
+ outline none
diff --git a/browser/styles/mixins/marked.styl b/browser/styles/mixins/marked.styl
new file mode 100644
index 00000000..4e7beb05
--- /dev/null
+++ b/browser/styles/mixins/marked.styl
@@ -0,0 +1,97 @@
+marked()
+ hr
+ border-top none
+ border-bottom solid 1px borderColor
+ margin 15px 0
+ h1
+ font-size 2em
+ margin 0 auto 0.67em
+ h2
+ font-size 1.5em
+ margin 0 auto 0.83em
+ h3
+ font-size 1.17em
+ margin 0 auto 1em
+ h4
+ font-size 1em
+ margin 0 auto 1.33em
+ h5
+ font-size 0.83em
+ margin 0 auto 1.67em
+ h6
+ font-size 0.67em
+ margin 2.33em auto
+ h1, h2, h3, h4, h5, h6
+ font-weight font-weight 400
+ line-height 1.2em
+ p
+ line-height 1.2em
+ img
+ max-width 100%
+ strong
+ font-weight bold
+ em
+ font-style italic
+ s
+ text-decoration line-through
+ blockquote
+ border-left solid 4px brandBorderColor
+ margin 1em 0
+ padding 0 25px
+ ul
+ list-style-type disc
+ padding-left 35px
+ li
+ display list-item
+ margin 0.5em 0
+ &>li>ul
+ list-style-type circle
+ &>li>ul
+ list-style-type square
+ ol
+ list-style-type decimal
+ padding-left 35px
+ li
+ display list-item
+ margin 0.5em 0
+ code
+ font-family monospace
+ padding 2px 4px
+ border solid 1px borderColor
+ border-radius 4px
+ font-size 0.9em
+ pre
+ padding 5px
+ border solid 1px borderColor
+ border-radius 5px
+ margin 0.5em 0
+ overflow-x auto
+ &>code
+ padding 0
+ border none
+ border-radius 0
+ table
+ width 100%
+ margin 15px 0
+ thead
+ tr
+ background-color tableHeadBgColor
+ th
+ border-style: solid;
+ padding: 5px;
+ border-width: 1px 0 2px 1px;
+ border-color borderColor
+ &:last-child
+ border-right solid 1px borderColor
+ tbody
+ tr:nth-child(2n + 1)
+ background-color tableOddBgColor
+ tr:nth-child(2n)
+ background-color tableEvenBgColor
+ td
+ border-style: solid;
+ padding: 5px;
+ border-width: 0 0 1px 1px;
+ border-color borderColor
+ &:last-child
+ border-right solid 1px borderColor
diff --git a/browser/styles/mixins/util.styl b/browser/styles/mixins/util.styl
new file mode 100644
index 00000000..c6913cf1
--- /dev/null
+++ b/browser/styles/mixins/util.styl
@@ -0,0 +1,7 @@
+borderBox()
+ box-sizing border-box
+
+noSelect()
+ -webkit-user-select none
+ -webkit-app-region drag
+
diff --git a/browser/styles/shared/btn.styl b/browser/styles/shared/btn.styl
new file mode 100644
index 00000000..e148716b
--- /dev/null
+++ b/browser/styles/shared/btn.styl
@@ -0,0 +1,55 @@
+.btn-primary, .btn-default
+ border-style solid
+ border-width 1px
+ background-image none
+ height 44px
+ padding 0 15px
+ border-radius 5px
+ box-sizing border-box
+ font-size 1em
+ font-family 'Lato'
+ font-weight 400
+ transition 0.1s
+ cursor pointer
+ margin 0 5px
+
+.btn-block
+ display block
+ width 100%
+ margin 0 auto
+
+.btn-square
+ display inline-block
+ width 44px
+ padding 0
+ border-width 1px
+
+.btn-sm
+ height 32px
+ border-radius 16px
+ &.btn-square
+ width 32px
+
+.btn-primary
+ border-color brandBorderColor
+ background-color transparent
+ color brandColor
+ &:hover, &.hover, &:focus, &.focus
+ border-color darken(brandBorderColor, 30%)
+ color darken(brandColor, 30%)
+ &:active, &.active
+ background-color brandColor
+ color white
+
+.btn-default
+ border-color lightButtonColor
+ background-color transparent
+ color lightButtonColor
+
+ &:hover, &.hover, &:focus, &.focus
+ border-color darken(lightButtonColor, 50%)
+ color darken(lightButtonColor, 50%)
+ &:active, &.active
+ border-color darken(brandBorderColor, 10%)
+ background-color brandColor
+ color white
diff --git a/browser/styles/shared/modal.styl b/browser/styles/shared/modal.styl
new file mode 100644
index 00000000..2054f57e
--- /dev/null
+++ b/browser/styles/shared/modal.styl
@@ -0,0 +1,375 @@
+.ModalBase
+ fixed top left bottom right
+ z-index modalZIndex
+ &.hide
+ display none
+ .modalBack
+ absolute top left bottom right
+ background-color modalBackColor
+ z-index modalZIndex + 1
+ .modal
+ position relative
+ width 650px
+ margin 50px auto 0
+ z-index modalZIndex + 2
+ box-shadow popupShadow
+ background-color white
+ border-radius 10px
+ padding 15px
+ .modal-header
+ border-bottom solid 1px borderColor
+ margin-bottom 10px
+ h1
+ padding 10px 0 15px
+ font-size 1.5em
+ .modal-body
+ p
+ margin-bottom 10px
+ .modal-footer
+ clearfix()
+ border-top solid 1px borderColor
+ padding-top 10px
+ .modal-control
+ float right
+
+ .tabModal
+ height 500px
+ .leftPane
+ absolute top bottom left
+ width 175px
+ padding 20px
+ border-right solid 1px borderColor
+ .tabLabel
+ font-size 1.5em
+ margin-top 25px
+ margin-bottom 35px
+ color brandColor
+ .tabList button
+ btnStripDefault()
+ display block
+ width 100%
+ font-size 1.1em
+ padding 10px 5px
+ margin-bottom 15px
+ text-align left
+ .rightPane
+ absolute top bottom right
+ left 175px
+ padding 15px
+ overflow-y auto
+
+ .EditProfileModal, .PlanetSettingModal, .TeamSettingsModal
+ .userInfoTab, .passwordTab, .planetProfileTab, .userInfoTab, .membersTab
+ padding-top 45px
+ .formField
+ position relative
+ clearfix()
+ margin-bottom 15px
+ label
+ width 30%
+ display block
+ line-height 33px
+ float left
+ input
+ width 70%
+ display block
+ borderInput()
+ height 33px
+ font-size 1em
+ border-radius 5px
+ float left
+ .formRadioField
+ margin-bottom 15px
+ input
+ margin-left 25px
+ .formConfirm
+ position relative
+ clearfix()
+ margin-bottom 15px
+ button
+ float right
+ btnDefault()
+ padding 10px 15px
+ border-radius 5px
+ font-size 1em
+ margin-left 5px
+ .alertInfo, .alertSuccess, .alertError
+ float right
+ padding 12px 10px
+ border-radius 5px
+ width 200px
+ font-size 1em
+ overflow-x hidden
+ white-space nowrap
+ transition 0.1s
+ &.hide
+ width 0
+ padding 12px 0
+ .alertInfo
+ alertInfo()
+ .alertSuccess
+ alertSuccess()
+ .alertError
+ alertError()
+ .planetDeleteTab
+ padding-top 65px
+ p
+ margin-bottom 25px
+ strong
+ color brandColor
+ font-size 1.1em
+ input
+ borderInput()
+ margin-right 5px
+ height 33px
+ font-size 1em
+ border-radius 10px
+ .formConfirm
+ position relative
+ clearfix()
+ margin-bottom 15px
+ button
+ float right
+ btnDefault()
+ padding 10px 15px
+ border-radius 5px
+ font-size 1em
+ margin-left 5px
+ .alertInfo, .alertSuccess, .alertError
+ float right
+ padding 12px 10px
+ border-radius 5px
+ width 200px
+ font-size 1em
+ overflow-x hidden
+ white-space nowrap
+ transition 0.1s
+ &.hide
+ width 0
+ padding 12px 0
+ .alertInfo
+ alertInfo()
+ .alertSuccess
+ alertSuccess()
+ .alertError
+ alertError()
+ .membersTab
+ .memberTable
+ width 100%
+ margin-bottom 25px
+ th
+ border-bottom solid 2px borderColor
+ td
+ border-bottom solid 1px borderColor
+ height 38px
+ button
+ btnDefault()
+ padding 5px
+ border-radius 5px
+ .roleSelect
+ height 33px
+ border solid 1px borderColor
+ background-color backgroundColor
+ th, td
+ padding 5px 0
+ .addMemberForm
+ .formLabel
+ margin-bottom 5px
+ .formGroup
+ clearfix()
+ .userNameSelect
+ display block
+ width 200px
+ margin-right 5px
+ float left
+ .roleSelect
+ display block
+ height 33px
+ border solid 1px borderColor
+ background-color backgroundColor
+ float left
+ margin-right 5px
+ .confirmButton
+ display block
+ height 33px
+ btnDefault()
+ border-radius 5px
+ float left
+
+
+ .LaunchModal
+ .modal-tab
+ text-align center
+ margin-bottom 10px
+ .btn-primary, .btn-default
+ margin 0
+ border-radius 0
+ border-width 1px
+ width 150px
+ border-radius 0
+ &:nth-child(1)
+ border-right solid 1px borderColor
+ border-top-left-radius 5px
+ border-bottom-left-radius 5px
+ &:nth-child(2)
+ border-left none
+ border-top-right-radius 5px
+ border-bottom-right-radius 5px
+ .Select
+ .Select-control
+ border-color borderColor
+ &.is-focused
+ .Select-control
+ border-color brandBorderColor
+ .Select-menu-outer
+ border-color borderColor
+ .ace_editor
+ border-radius 5px
+ border solid 1px borderColor
+ .CodeForm, .NoteForm
+ .form-group
+ margin-bottom 10px
+ .CodeForm
+ textarea.codeDescription
+ height 75px
+ font-size 0.9em
+ margin-bottom 10px
+ .modeSelect.Select
+ display inline-block
+ width 200px
+ height 37px
+ .Select-control
+ height 37px
+ .ace_editor
+ height 258px
+ .NoteForm
+ .ace_editor
+ height 358px
+ .previewMode
+ absolute top right
+ font-size 0.8em
+ line-height 24px
+ padding 5 15px
+ background-color transparentify(invBackgroundColor, 0.2)
+ color invTextColor
+ border-top-right-radius 5px
+ .marked
+ height 360px
+ overflow-x hidden
+ overflow-y auto
+ box-sizing border-box
+ padding 5px
+ border solid 1px borderColor
+ border-radius 5px
+ marked()
+
+ .AboutModal
+ width 320px
+ .about1
+ margin-bottom 25px
+ .logo
+ display block
+ margin 0 auto
+ .appInfo
+ font-size 1.5em
+ text-align center
+ .about2
+ width 200px
+ margin 0 auto
+ .externalLabel
+ font-size 1.2em
+ margin-bottom 15px
+ .externalList
+ li
+ margin-bottom 15px
+
+ .PlanetCreateModal.modal, .TeamCreateModal.modal, .AddMemberModal.modal
+ padding 60px 0
+ .nameInput
+ width 80%
+ font-size 1.3em
+ margin 25px auto 15px
+ text-align center
+ .userNameSelect
+ width 80%
+ font-size 1.3em
+ margin 35px auto
+ text-align center
+ .formField
+ text-align center
+ margin 0 auto 25px
+ select
+ display inline-block
+ width 150px
+ height 33px
+ border solid 1px borderColor
+ background-color white
+ padding 0 10px
+ margin 0 15px
+ .submitButton
+ display block
+ margin 0 auto
+ box-sizing border-box
+ width 55px
+ height 55px
+ circle()
+ btnPrimary()
+
+ .ContactModal
+ padding 15px
+ .contactForm
+ .formField
+ width 100%
+ margin-bottom 10px
+ input, textarea
+ display block
+ width 100%
+ borderInput()
+ border-radius 5px
+ input
+ height 33px
+ font-size 1em
+ textarea
+ height 175px
+ font-size 1em
+ .formControl
+ clearfix()
+ button
+ float right
+ btnDefault()
+ height 44px
+ padding 0 15px
+ border-radius 5px
+ margin-left 5px
+ button.sendButton
+ btnPrimary()
+ .confirmation
+ .confirmationMessage
+ padding 35px 0
+ text-align center
+ font-size 1.1em
+ .doneButton
+ btnDefault()
+ height 44px
+ padding 0 35px
+ border-radius 5px
+ display block
+ margin 0 auto 25px
+
+ .LogoutModal
+ padding 65px 0 45px
+ width 350px
+ .messageLabel
+ text-align center
+ font-size 1.1em
+ margin-bottom 35px
+ .formControl
+ text-align center
+ button
+ btnDefault()
+ border-radius 5px
+ height 44px
+ margin 15px 5px
+ padding 0 15px
+ button.logoutButton
+ btnPrimary()
diff --git a/browser/styles/vars.styl b/browser/styles/vars.styl
new file mode 100644
index 00000000..ebe54635
--- /dev/null
+++ b/browser/styles/vars.styl
@@ -0,0 +1,51 @@
+borderColor = #E8E8E8
+highlightenBorderColor = darken(borderColor, 20%)
+invBorderColor = #404849
+brandBorderColor = #3FB399
+
+buttonBorderColor = #4C4C4C
+
+lightButtonColor = #898989
+
+hoverBackgroundColor= transparentify(#444, 4%)
+
+inactiveTextColor = #888
+textColor = #4D4D4D
+backgroundColor= white
+fontSize= 14px
+
+shadowColor= #C5C5C5
+
+invBackgroundColor = #4C4C4C
+invTextColor = white
+
+btnColor = #888
+btnHighlightenColor = #000
+
+brandColor = #2BAC8F
+
+planetNavBgColor = #ECECEC
+planetAnchorColor = #979797
+planetAnchorBgColor = #BEBEBE
+planetAnchorActiveColor = textColor
+planetAnchorActiveBgColor = white
+
+popupShadow = 0 0 5px 0 #888
+modalBackColor = transparentify(white, 65%)
+
+tableHeadBgColor = white
+tableOddBgColor = #F9F9F9
+tableEvenBgColor = white
+
+facebookColor= #3b5998
+githubBtn= #201F1F
+
+successBackgroundColor= #E0F0D9
+successTextColor= #3E753F
+errorBackgroundColor= #F2DEDE
+errorTextColor= #A64444
+infoBackgroundColor= #D9EDF7
+infoTextColor= #34708E
+
+modalZIndex= 1000
+popupZIndex= 500
diff --git a/build.config.js b/build.config.js
deleted file mode 100644
index d5e96a58..00000000
--- a/build.config.js
+++ /dev/null
@@ -1,48 +0,0 @@
-module.exports = {
- vendors: [
- {
- name: 'ace',
- src: 'node_modules/@rokt33r/ace-builds/src/**/*'
- },
- {
- name: 'angular',
- src: 'node_modules/angular/angular.js'
- },
- {
- name: 'angular-bootstrap',
- src: 'node_modules/angular-bootstrap/dist/ui-bootstrap-tpls.js'
- },
- {
- name: 'angular-sanitize',
- src: 'node_modules/angular-sanitize/angular-sanitize.js'
- },
- {
- name: 'angular-ui-router',
- src: 'node_modules/angular-ui-router/build/angular-ui-router.js'
- },
- {
- name: 'ui-select',
- src: 'node_modules/ui-select/dist/select.js'
- },
- {
- name: 'satellizer',
- src: 'node_modules/satellizer/satellizer.js'
- },
- {
- name: 'angular-md5',
- src: 'node_modules/angular-md5/angular-md5.js'
- },
- {
- name: 'moment',
- src: 'node_modules/moment/moment.js'
- },
- {
- name: 'angular-hotkeys',
- src: 'node_modules/angular-hotkeys/build/hotkeys.js'
- },
- {
- name: 'marked',
- src: 'node_modules/marked/lib/marked.js'
- }
- ]
-}
diff --git a/config.js b/config.js
new file mode 100644
index 00000000..265b0bf8
--- /dev/null
+++ b/config.js
@@ -0,0 +1,4 @@
+module.exports = {
+ apiUrl: 'http://codexen-server-dev2.elasticbeanstalk.com/'
+ // apiUrl: 'http://localhost:8000/'
+}
diff --git a/docs/events.md b/docs/events.md
deleted file mode 100644
index 62643c5f..00000000
--- a/docs/events.md
+++ /dev/null
@@ -1,7 +0,0 @@
-# Event List
-
-|name|Description|Delivery|
-|----|----|----|
-|userSignIn|a user signed in||
-|userSignOut|a user signed out||
-|snippetUpdated|snippet has been updated or created|snippet|
diff --git a/main.js b/main.js
new file mode 100644
index 00000000..41f24738
--- /dev/null
+++ b/main.js
@@ -0,0 +1,187 @@
+var app = require('app')
+var BrowserWindow = require('browser-window')
+var Menu = require('menu')
+var MenuItem = require('menu-item')
+var Tray = require('tray')
+var ipc = require('ipc')
+
+require('crash-reporter').start()
+
+var mainWindow = null
+var appIcon = null
+var menu = null
+var popUpWindow = null
+
+var update = null
+
+// app.on('window-all-closed', function () {
+// if (process.platform !== 'darwin') app.quit()
+// })
+
+var version = app.getVersion()
+global.version = version
+var versionText = (version == null || version.length === 0) ? 'DEV version' : 'v' + version
+var nn = require('node-notifier')
+var autoUpdater = require('auto-updater')
+var path = require('path')
+
+autoUpdater
+ .on('error', function (err, message) {
+ nn.notify({
+ title: 'Error! ' + versionText,
+ icon: path.join(__dirname, 'browser/main/resources/favicon-230x230.png'),
+ message: message
+ })
+ })
+ .on('checking-for-update', function () {
+ nn.notify({
+ title: 'Boost launched!! ' + versionText,
+ icon: path.join(__dirname, 'browser/main/resources/favicon-230x230.png'),
+ message: 'Checking update is available....'
+ })
+ })
+ .on('update-available', function () {
+ nn.notify({
+ title: 'Update is available!! ' + versionText,
+ icon: path.join(__dirname, 'browser/main/resources/favicon-230x230.png'),
+ message: 'Download started.. wait for the update ready.'
+ })
+ })
+ .on('update-not-available', function () {
+ nn.notify({
+ title: 'Latest Build!! ' + versionText,
+ icon: path.join(__dirname, 'browser/main/resources/favicon-230x230.png'),
+ message: 'Hope you to enjoy our app :D'
+ })
+ })
+ .on('update-downloaded', function (event, releaseNotes, releaseName, releaseDate, updateUrl, quitAndUpdate) {
+ nn.notify({
+ title: 'Ready to Update!! ' + versionText,
+ icon: path.join(__dirname, 'browser/main/resources/favicon-230x230.png'),
+ message: 'Click tray icon to update app: ' + releaseName
+ })
+ update = quitAndUpdate
+
+ if (mainWindow != null && !mainWindow.webContents.isLoading()) {
+ mainWindow.webContents.send('update-available', 'Update available!')
+ }
+ })
+
+app.on('ready', function () {
+ console.log('Version ' + version)
+ autoUpdater.setFeedUrl('http://orbital.b00st.io/rokt33r/boost/latest?version=' + version)
+ autoUpdater.checkForUpdates()
+ // menu start
+ var template = require('./modules/menu-template')
+
+ ipc.on('update-app', function (event, msg) {
+ if (update != null) {
+ update()
+ }
+ })
+
+ menu = Menu.buildFromTemplate(template)
+
+ Menu.setApplicationMenu(menu)
+ // menu end
+ appIcon = new Tray(__dirname + '/tray-icon.png')
+ appIcon.setToolTip('Codexen')
+
+ var trayMenu = new Menu()
+ trayMenu.append(new MenuItem({
+ label: 'Open main window',
+ click: function () {
+ if (mainWindow == null) {
+ makeNewMainWindow()
+ }
+ mainWindow.show()
+ }
+ }))
+ trayMenu.append(new MenuItem({
+ label: 'Update App',
+ click: function () {
+ if (update != null) {
+ update()
+ }
+ }
+ }))
+ trayMenu.append(new MenuItem({
+ label: 'Quit',
+ click: function () {
+ app.quit()
+ }
+ }))
+ appIcon.setContextMenu(trayMenu)
+
+ makeNewMainWindow()
+
+ app.on('activate-with-no-open-windows', function () {
+ if (mainWindow == null) {
+ makeNewMainWindow()
+ return
+ }
+ mainWindow.show()
+ })
+
+ popUpWindow = new BrowserWindow({
+ width: 600,
+ height: 400,
+ show: false,
+ frame: false,
+ 'zoom-factor': 1.0,
+ 'always-on-top': true,
+ 'web-preferences': {
+ 'overlay-scrollbars': true,
+ 'skip-taskbar': true
+ }
+ })
+
+ popUpWindow.loadUrl('file://' + __dirname + '/browser/finder/index.electron.html')
+
+ popUpWindow.on('blur', function () {
+ popUpWindow.hide()
+ })
+ popUpWindow.setVisibleOnAllWorkspaces(true)
+
+ var globalShortcut = require('global-shortcut')
+
+ globalShortcut.register('ctrl+tab+shift', function () {
+ if (mainWindow != null && !mainWindow.isFocused()) {
+ mainWindow.hide()
+ }
+ popUpWindow.show()
+ })
+
+ global.hideFinder = function () {
+ if (mainWindow == null || !mainWindow.isVisible()) {
+ Menu.sendActionToFirstResponder('hide:')
+ }
+ popUpWindow.hide()
+ }
+})
+
+function makeNewMainWindow () {
+ console.log('new Window!')
+ mainWindow = new BrowserWindow({
+ width: 1080,
+ height: 720,
+ 'zoom-factor': 1.0,
+ 'web-preferences': {
+ 'overlay-scrollbars': true
+ }
+ })
+ if (update != null) {
+ mainWindow.webContents.on('did-finish-load', function () {
+ mainWindow.webContents.send('update-available', 'whoooooooh!')
+ })
+ }
+
+ mainWindow.loadUrl('file://' + __dirname + '/browser/main/index.electron.html')
+
+ mainWindow.on('closed', function () {
+ console.log('main closed')
+ mainWindow = null
+ app.dock.hide()
+ })
+ app.dock.show()
+}
diff --git a/modules/ace-modes.js b/modules/ace-modes.js
new file mode 100644
index 00000000..f4f2c72f
--- /dev/null
+++ b/modules/ace-modes.js
@@ -0,0 +1,10 @@
+var fs = require('fs')
+
+module.exports = fs.readdirSync(__dirname + '/../browser/ace/src-min')
+ .filter(function (file) {
+ return file.match(/^mode-/)
+ })
+ .map(function (file) {
+ var match = file.match(/^mode-([a-z0-9\_]+).js$/)
+ return match[1]
+ })
diff --git a/modules/menu-template.js b/modules/menu-template.js
new file mode 100644
index 00000000..33da0d3f
--- /dev/null
+++ b/modules/menu-template.js
@@ -0,0 +1,128 @@
+var BrowserWindow = require('browser-window')
+
+module.exports = [
+ {
+ label: 'Electron',
+ submenu: [
+ {
+ label: 'About Electron',
+ selector: 'orderFrontStandardAboutPanel:'
+ },
+ {
+ type: 'separator'
+ },
+ {
+ label: 'Services',
+ submenu: []
+ },
+ {
+ type: 'separator'
+ },
+ {
+ label: 'Hide Electron',
+ accelerator: 'Command+H',
+ selector: 'hide:'
+ },
+ {
+ label: 'Hide Others',
+ accelerator: 'Command+Shift+H',
+ selector: 'hideOtherApplications:'
+ },
+ {
+ label: 'Show All',
+ selector: 'unhideAllApplications:'
+ },
+ {
+ type: 'separator'
+ },
+ {
+ label: 'Quit',
+ accelerator: 'Command+Q',
+ selector: 'terminate:'
+ }
+ ]
+ },
+ {
+ label: 'Edit',
+ submenu: [
+ {
+ label: 'Undo',
+ accelerator: 'Command+Z',
+ selector: 'undo:'
+ },
+ {
+ label: 'Redo',
+ accelerator: 'Shift+Command+Z',
+ selector: 'redo:'
+ },
+ {
+ type: 'separator'
+ },
+ {
+ label: 'Cut',
+ accelerator: 'Command+X',
+ selector: 'cut:'
+ },
+ {
+ label: 'Copy',
+ accelerator: 'Command+C',
+ selector: 'copy:'
+ },
+ {
+ label: 'Paste',
+ accelerator: 'Command+V',
+ selector: 'paste:'
+ },
+ {
+ label: 'Select All',
+ accelerator: 'Command+A',
+ selector: 'selectAll:'
+ }
+ ]
+ },
+ {
+ label: 'View',
+ submenu: [
+ {
+ label: 'Reload',
+ accelerator: 'Command+R',
+ click: function () {
+ BrowserWindow.getFocusedWindow().reload()
+ }
+ },
+ {
+ label: 'Toggle DevTools',
+ accelerator: 'Alt+Command+I',
+ click: function () {
+ BrowserWindow.getFocusedWindow().toggleDevTools()
+ }
+ }
+ ]
+ },
+ {
+ label: 'Window',
+ submenu: [
+ {
+ label: 'Minimize',
+ accelerator: 'Command+M',
+ selector: 'performMiniaturize:'
+ },
+ {
+ label: 'Close',
+ accelerator: 'Command+W',
+ selector: 'performClose:'
+ },
+ {
+ type: 'separator'
+ },
+ {
+ label: 'Bring All to Front',
+ selector: 'arrangeInFront:'
+ }
+ ]
+ },
+ {
+ label: 'Help',
+ submenu: []
+ }
+]
diff --git a/package.json b/package.json
index 752fdafc..37562ab7 100644
--- a/package.json
+++ b/package.json
@@ -1,24 +1,25 @@
{
- "name": "codexen-app-builder",
- "version": "0.2.0",
- "description": "CodeXen App Builder",
+ "name": "boost",
+ "version": "0.2.1",
+ "description": "Boost App",
+ "main": "main.js",
"scripts": {
- "install": "gulp build",
- "start": "http-server build",
- "test": "echo \"Error: no test specified\" && exit 1"
+ "start": "electron ./main.js",
+ "web": "npm run serve | npm run dev",
+ "serve": "./node_modules/.bin/http-server ./browser -p 8080",
+ "dev": "webpack-dev-server --progress --colors --port 8090"
},
"repository": {
"type": "git",
"url": "git+https://github.com/Rokt33r/codexen-app.git"
},
"keywords": [
- "codexen",
+ "boost",
+ "b00st",
"snippet",
"template",
"task",
"runner",
- "remote",
- "automator",
"code",
"storage",
"short code"
@@ -30,48 +31,37 @@
},
"homepage": "https://github.com/Rokt33r/codexen-app#readme",
"dependencies": {
- "dotenv": "^1.1.0",
- "robotjs": "^0.1.2",
- "node-notifier": "^4.2.1"
+ "electron-stylus": "^0.1.0",
+ "font-awesome": "^4.3.0",
+ "markdown-it": "^4.3.1",
+ "md5": "^2.0.0",
+ "moment": "^2.10.3",
+ "nib": "^1.1.0",
+ "node-jsx": "^0.13.3",
+ "node-notifier": "^4.2.3",
+ "react": "^0.13.3",
+ "react-router": "^0.13.3",
+ "react-select": "^0.5.4",
+ "reflux": "^0.2.8",
+ "superagent": "^1.2.0",
+ "superagent-promise": "^1.0.3"
},
"devDependencies": {
- "@rokt33r/ace-builds": "^1.1.9",
- "@rokt33r/angular-ui-ace": "^0.2.3",
- "angular": "^1.3.15",
- "angular-bootstrap": "^0.12.0",
- "angular-hotkeys": "^1.4.5",
- "angular-md5": "^0.1.7",
- "angular-sanitize": "^1.3.15",
- "angular-ui-router": "^0.2.15",
- "bootstrap-styl": "^4.0.4",
- "del": "^1.2.0",
- "font-awesome": "^4.3.0",
- "globby": "^2.0.0",
- "gulp": "^3.8.11",
- "gulp-angular-templatecache": "^1.6.0",
- "gulp-autoprefixer": "^2.3.0",
- "gulp-cached": "^1.1.0",
- "gulp-changed": "^1.2.1",
- "gulp-concat": "^2.5.2",
- "gulp-inject": "^1.3.1",
- "gulp-livereload": "^3.8.0",
- "gulp-minify-css": "^1.1.1",
- "gulp-minify-html": "^1.0.3",
- "gulp-ng-annotate": "^0.5.3",
- "gulp-notify": "^2.2.0",
- "gulp-plumber": "^1.0.1",
- "gulp-remember": "^0.3.0",
- "gulp-rename": "^1.2.2",
- "gulp-rev": "^4.0.0",
- "gulp-stylus": "^2.0.3",
- "gulp-template": "^3.0.0",
- "gulp-uglify": "^1.2.0",
- "marked": "^0.3.3",
- "merge-stream": "^0.1.7",
- "moment": "^2.10.3",
- "run-sequence": "^1.1.0",
- "satellizer": "^0.10.1",
- "streamqueue": "^1.1.0",
- "ui-select": "^0.11.2"
+ "css-loader": "^0.15.1",
+ "http-server": "^0.8.0",
+ "jsx-loader": "^0.13.2",
+ "node-libs-browser": "^0.5.2",
+ "style-loader": "^0.12.3",
+ "stylus-loader": "^1.2.1",
+ "webpack": "^1.10.0",
+ "webpack-dev-server": "^1.10.1"
+ },
+ "standard": {
+ "ignore": [
+ "/browser/ace/"
+ ],
+ "global": [
+ "localStorage"
+ ]
}
}
diff --git a/readme.md b/readme.md
index cfe6a27b..f08d4273 100644
--- a/readme.md
+++ b/readme.md
@@ -1,4 +1,4 @@
-# CodeXen app
+# CodeXen app 0.2.0

Short code(Snippet/Templatefile/Command) storage + boosting service
diff --git a/src/app-logo.png b/src/app-logo.png
deleted file mode 100644
index 053bfc43..00000000
Binary files a/src/app-logo.png and /dev/null differ
diff --git a/src/browser/main/app.js b/src/browser/main/app.js
deleted file mode 100644
index 0409f18e..00000000
--- a/src/browser/main/app.js
+++ /dev/null
@@ -1,13 +0,0 @@
-/* global angular */
-angular.module('codexen', [
- 'codexen.shared',
- 'ngSanitize',
- 'ui.select',
- 'ui.ace',
- 'ui.router',
- 'ui.bootstrap',
- 'satellizer',
- 'angular-md5',
- 'templates'])
- .constant('appName', 'main')
-angular.module('templates', [])
diff --git a/src/browser/main/config/states.js b/src/browser/main/config/states.js
deleted file mode 100644
index 64de2ae9..00000000
--- a/src/browser/main/config/states.js
+++ /dev/null
@@ -1,111 +0,0 @@
-/* global angular */
-angular.module('codexen')
- .config(function ($stateProvider, $urlRouterProvider, $httpProvider) {
- $httpProvider.interceptors.push(function ($q, $injector) {
- return {
- responseError: function (res) {
- switch (res.status) {
- case 401:
- var $state = $injector.get('$state')
- $state.go('auth.signin')
- break
- }
-
- return $q.reject(res)
- }
- }
- })
-
- $urlRouterProvider
- .when('/auth', '/auth/register')
- .when('/auth/', '/auth/register')
- .otherwise('/')
-
- $stateProvider
- /* Auth */
- .state('auth', {
- url: '/auth',
- views: {
- 'main-view': {
- templateUrl: 'tpls/states/auth.tpl.html'
- }
- }
- })
- .state('auth.register', {
- url: '/register',
- templateUrl: 'tpls/states/auth.register.tpl.html',
- controller: 'AuthRegisterController as vm'
- })
- .state('auth.signin', {
- url: '/signin',
- templateUrl: 'tpls/states/auth.signin.tpl.html',
- controller: 'AuthSignInController as vm'
- })
-
- .state('settings', {
- url: '/settings',
- views: {
- 'main-view': {
- templateUrl: 'tpls/states/settings.tpl.html',
- controller: 'SettingsController as vm'
- }
- }
- })
-
- /* Snippets */
- .state('snippets', {
- url: '/snippets',
- views: {
- 'main-view': {
- templateUrl: 'tpls/states/snippets.list.tpl.html',
- controller: 'SnippetsListController as vm'
- }
- },
- resolve: {
- mySnippets: function (Snippet) {
- return Snippet.findMine().then(function (res) {
- return res.data
- })
- }
- }
- })
- .state('snippets.detail', {
- url: '/:id',
- templateUrl: 'tpls/states/snippets.detail.tpl.html',
- controller: 'SnippetsDetailController as vm'
- })
-
- /* Home */
- .state('home', {
- url: '/',
- views: {
- 'main-view': {
- templateUrl: 'tpls/states/home.tpl.html',
- controller: 'HomeController as vm'
- }
- }
- })
-
- /* Recipes */
- .state('recipes', {
- url: '/recipes',
- views: {
- 'main-view': {
- templateUrl: 'tpls/states/recipes.list.tpl.html',
- controller: 'RecipesListController as vm'
- }
- },
- resolve: {
- myRecipes: function (Recipe) {
- return Recipe.findMine().then(function (res) {
- return res.data
- })
- }
- }
- })
- .state('recipes.detail', {
- url: '/:id',
- templateUrl: 'tpls/states/recipes.detail.html',
- controller: 'RecipesDetailController as vm'
- })
- })
diff --git a/src/browser/main/controllers/modals/DeleteRecipeModalController.js b/src/browser/main/controllers/modals/DeleteRecipeModalController.js
deleted file mode 100644
index 1cdae3b4..00000000
--- a/src/browser/main/controllers/modals/DeleteRecipeModalController.js
+++ /dev/null
@@ -1,16 +0,0 @@
-/* global angular */
-angular.module('codexen')
- .controller('DeleteRecipeModalController', function ($modalInstance, Recipe, recipe) {
- var vm = this
-
- vm.submit = function () {
- Recipe.delete(recipe.id)
- .success(function (recipe) {
- $modalInstance.close(recipe)
- })
- }
-
- vm.cancel = function () {
- $modalInstance.dismiss()
- }
- })
diff --git a/src/browser/main/controllers/modals/DeleteSnippetModalController.js b/src/browser/main/controllers/modals/DeleteSnippetModalController.js
deleted file mode 100644
index b12f388b..00000000
--- a/src/browser/main/controllers/modals/DeleteSnippetModalController.js
+++ /dev/null
@@ -1,16 +0,0 @@
-/* global angular */
-angular.module('codexen')
- .controller('DeleteSnippetModalController', function ($modalInstance, Snippet, snippet) {
- var vm = this
-
- vm.submit = function () {
- Snippet.delete(snippet.id)
- .success(function (snippet) {
- $modalInstance.close(snippet)
- })
- }
-
- vm.cancel = function () {
- $modalInstance.dismiss()
- }
- })
diff --git a/src/browser/main/controllers/modals/EditRecipeModalController.js b/src/browser/main/controllers/modals/EditRecipeModalController.js
deleted file mode 100644
index d587e52f..00000000
--- a/src/browser/main/controllers/modals/EditRecipeModalController.js
+++ /dev/null
@@ -1,42 +0,0 @@
-/* global angular */
-angular.module('codexen')
- .controller('EditRecipeModalController', function (Recipe, Tag, $modalInstance, recipe) {
- var vm = this
-
- vm.recipe = recipe
-
- vm.submit = function () {
- var params = {
- title: vm.recipe.title,
- content: vm.recipe.content,
- Tags: angular.isArray(vm.recipe.Tags) ? vm.recipe.Tags.map(function (tag) { return tag.name }) : []
- }
-
- Recipe.update(vm.recipe.id, params)
- .success(function (data) {
- $modalInstance.close(data)
- })
- }
-
- // vm.tags = []
- vm.tagCandidates = []
- vm.refreshTagCandidates = function (tagName) {
- if (tagName == null || tagName === '') return null
- return Tag.findByName(tagName)
- .success(function (data) {
- console.log('tags fetched!!', data)
- vm.tagCandidates = data
- })
- }
- vm.transform = function (tagName) {
- return {
- id: 0,
- name: tagName
- }
- }
-
- vm.cancel = function () {
- $modalInstance.dismiss()
- }
-
- })
diff --git a/src/browser/main/controllers/modals/EditSnippetModalController.js b/src/browser/main/controllers/modals/EditSnippetModalController.js
deleted file mode 100644
index 6254b525..00000000
--- a/src/browser/main/controllers/modals/EditSnippetModalController.js
+++ /dev/null
@@ -1,45 +0,0 @@
-/* global angular */
-angular.module('codexen')
- .controller('EditSnippetModalController', function ($modalInstance, aceModes, $log, Snippet, $rootScope, Tag, snippet) {
- var vm = this
-
- vm.aceModes = aceModes
- vm.snippet = snippet
-
- vm.submit = function () {
- var params = {
- description: vm.snippet.description,
- callSign: vm.snippet.callSign,
- mode: vm.snippet.mode == null ? null : vm.snippet.mode.toLowerCase(),
- content: vm.snippet.content,
- Tags: angular.isArray(vm.snippet.Tags) ? vm.snippet.Tags.map(function (tag) { return tag.name }) : []
- }
- Snippet.update(vm.snippet.id, params)
- .success(function (data) {
- console.log('updated res :', data)
- $rootScope.$broadcast('snippetUpdated', snippet)
- $modalInstance.close(data)
- })
- }
-
- // vm.tags = []
- vm.tagCandidates = []
- vm.refreshTagCandidates = function (tagName) {
- if (tagName == null || tagName === '') return null
- return Tag.findByName(tagName)
- .success(function (data) {
- console.log('tags fetched!!', data)
- vm.tagCandidates = data
- })
- }
- vm.transform = function (tagName) {
- return {
- id: 0,
- name: tagName
- }
- }
-
- vm.cancel = function () {
- $modalInstance.dismiss()
- }
- })
diff --git a/src/browser/main/controllers/modals/ExpandRecipeModalController.js b/src/browser/main/controllers/modals/ExpandRecipeModalController.js
deleted file mode 100644
index 9b59309f..00000000
--- a/src/browser/main/controllers/modals/ExpandRecipeModalController.js
+++ /dev/null
@@ -1,23 +0,0 @@
-/* global angular */
-angular.module('codexen')
- .controller('ExpandRecipeModalController', function (recipe, $modalInstance, $scope, Modal) {
- var vm = this
- console.log(recipe)
-
- vm.recipe = recipe
-
- vm.cancel = function () {
- $modalInstance.dismiss('cancel')
- }
-
- vm.insert = function (type) {
- $scope.$broadcast('insertRequested', type)
- }
-
- vm.insertSnippet = function () {
- Modal.selectSnippet()
- .then(function (snippet) {
- $scope.$broadcast('insertSnippetRequested', snippet)
- })
- }
- })
diff --git a/src/browser/main/controllers/modals/NewRecipeModalController.js b/src/browser/main/controllers/modals/NewRecipeModalController.js
deleted file mode 100644
index e1647964..00000000
--- a/src/browser/main/controllers/modals/NewRecipeModalController.js
+++ /dev/null
@@ -1,42 +0,0 @@
-/* global angular */
-angular.module('codexen')
- .controller('NewRecipeModalController', function (Recipe, Tag, $modalInstance) {
- var vm = this
-
- vm.recipe = {}
-
- vm.submit = function () {
- var params = {
- title: vm.recipe.title,
- content: vm.recipe.content,
- Tags: angular.isArray(vm.recipe.Tags) ? vm.recipe.Tags.map(function (tag) { return tag.name }) : []
- }
-
- Recipe.create(params)
- .success(function (data) {
- $modalInstance.close(data)
- })
- }
-
- // vm.tags = []
- vm.tagCandidates = []
- vm.refreshTagCandidates = function (tagName) {
- if (tagName == null || tagName === '') return null
- return Tag.findByName(tagName)
- .success(function (data) {
- console.log('tags fetched!!', data)
- vm.tagCandidates = data
- })
- }
- vm.transform = function (tagName) {
- return {
- id: 0,
- name: tagName
- }
- }
-
- vm.cancel = function () {
- $modalInstance.dismiss()
- }
-
- })
diff --git a/src/browser/main/controllers/modals/NewSnippetModalController.js b/src/browser/main/controllers/modals/NewSnippetModalController.js
deleted file mode 100644
index 7fac0952..00000000
--- a/src/browser/main/controllers/modals/NewSnippetModalController.js
+++ /dev/null
@@ -1,43 +0,0 @@
-/* global angular */
-angular.module('codexen')
- .controller('NewSnippetModalController', function ($modalInstance, aceModes, $log, Snippet, Tag) {
- var vm = this
-
- vm.aceModes = aceModes
-
- vm.submit = function () {
- var params = {
- description: vm.description,
- callSign: vm.callSign,
- mode: vm.mode == null ? null : vm.mode.toLowerCase(),
- content: vm.content,
- Tags: angular.isArray(vm.Tags) ? vm.Tags.map(function (tag) { return tag.name }) : []
- }
-
- Snippet.create(params)
- .success(function (data) {
- $modalInstance.close(data)
- })
- }
-
- // vm.tags = []
- vm.tagCandidates = []
- vm.refreshTagCandidates = function (tagName) {
- if (tagName == null || tagName === '') return null
- return Tag.findByName(tagName)
- .success(function (data) {
- console.log('tags fetched!!', data)
- vm.tagCandidates = data
- })
- }
- vm.transform = function (tagName) {
- return {
- id: 0,
- name: tagName
- }
- }
-
- vm.cancel = function () {
- $modalInstance.dismiss()
- }
- })
diff --git a/src/browser/main/controllers/modals/SelectSnippetModalController.js b/src/browser/main/controllers/modals/SelectSnippetModalController.js
deleted file mode 100644
index be9b78e7..00000000
--- a/src/browser/main/controllers/modals/SelectSnippetModalController.js
+++ /dev/null
@@ -1,18 +0,0 @@
-/* global angular */
-angular.module('codexen')
- .controller('SelectSnippetModalController', function (Snippet, $modalInstance) {
- var vm = this
-
- vm.select = function (snippet) {
- $modalInstance.close(snippet)
- }
-
- vm.cancel = function () {
- $modalInstance.dismiss('cancel')
- }
-
- Snippet.findMine()
- .success(function (snippets) {
- vm.snippets = snippets
- })
- })
diff --git a/src/browser/main/controllers/modals/SignOutModalController.js b/src/browser/main/controllers/modals/SignOutModalController.js
deleted file mode 100644
index 77065e36..00000000
--- a/src/browser/main/controllers/modals/SignOutModalController.js
+++ /dev/null
@@ -1,13 +0,0 @@
-/* global angular */
-angular.module('codexen')
- .controller('SignOutModalController', function ($modalInstance) {
- var vm = this
-
- vm.submit = function () {
- $modalInstance.close()
- }
-
- vm.cancel = function () {
- $modalInstance.dismiss('cancel')
- }
- })
diff --git a/src/browser/main/controllers/states/AuthSignInController.js b/src/browser/main/controllers/states/AuthSignInController.js
deleted file mode 100644
index 394a9d3a..00000000
--- a/src/browser/main/controllers/states/AuthSignInController.js
+++ /dev/null
@@ -1,21 +0,0 @@
-/* global angular */
-angular.module('codexen')
- .controller('AuthSignInController', function ($auth, $rootScope) {
- var vm = this
-
- vm.authFailed = false
-
- vm.signIn = function () {
- vm.authFailed = false
- $auth.login({
- email: vm.email,
- password: vm.password
- }).then(function (data) {
- console.log(data)
- $rootScope.$broadcast('userSignIn')
- }, function (err) {
- console.log(err)
- vm.authFailed = true
- })
- }
- })
diff --git a/src/browser/main/controllers/states/HomeController.js b/src/browser/main/controllers/states/HomeController.js
deleted file mode 100644
index 74246d5d..00000000
--- a/src/browser/main/controllers/states/HomeController.js
+++ /dev/null
@@ -1,3 +0,0 @@
-/* global angular */
-angular.module('codexen')
- .controller('HomeController', function ($auth, Snippet, $scope) {})
diff --git a/src/browser/main/controllers/states/RecipesDetailController.js b/src/browser/main/controllers/states/RecipesDetailController.js
deleted file mode 100644
index 1eb365ab..00000000
--- a/src/browser/main/controllers/states/RecipesDetailController.js
+++ /dev/null
@@ -1,32 +0,0 @@
-/* global angular */
-angular.module('codexen')
- .controller('RecipesDetailController', function (Recipe, $state, $rootScope, $scope, Modal) {
- var vm = this
-
- vm.isLoaded = false
-
- var recipeId = $state.params.id
-
- Recipe.show(recipeId)
- .success(function (data) {
- vm.recipe = data
- vm.isLoaded = true
- })
-
- $scope.$on('taggingRequested', function (e) {
- e.stopPropagation()
- e.preventDefault()
- Modal.editRecipe(angular.copy(vm.recipe))
- .then(function (recipe) {
- console.log('edited', recipe)
- }, function () {
- console.log('edit recipe modal dismissed')
- })
- })
-
- $scope.$on('recipeUpdated', function (e, recipe) {
- console.log('event received', recipe)
- if (recipe.id === vm.recipe.id) vm.recipe = recipe
- })
-
- })
diff --git a/src/browser/main/controllers/states/RecipesListController.js b/src/browser/main/controllers/states/RecipesListController.js
deleted file mode 100644
index c5d10714..00000000
--- a/src/browser/main/controllers/states/RecipesListController.js
+++ /dev/null
@@ -1,98 +0,0 @@
-/* global angular */
-angular.module('codexen')
- .controller('RecipesListController', function (Recipe, $state, $scope, $filter, myRecipes, User, $auth) {
- var vm = this
-
-
- vm.recipes = myRecipes
-
- vm.searchRecipes = searchRecipes
- vm.searchRecipes()
-
- vm.isAuthenticated = $auth.isAuthenticated()
- var reloadUser = function () {
- if (vm.isAuthenticated) {
- User.me().success(function (data) {
- vm.currentUser = data
- })
- }
- }
- reloadUser()
-
- $scope.$on('$stateChangeSuccess', function (e, toState, toParams) {
- if (!toState.name.match(/recipes/)) return null
-
- vm.recipeId = parseInt(toParams.id, 10)
-
- if (!vm.recipeId && vm.filtered && vm.filtered[0]) {
- $state.go('recipes.detail', {id: vm.filtered[0].id})
- }
- })
-
- $scope.$on('recipeUpdated', function (e, recipe) {
- if (!myRecipes.some(function (_recipe, index) {
- if (_recipe.id === recipe.id) {
- myRecipes[index] = recipe
- return true
- }
- return false
- })) myRecipes.unshift(recipe)
-
- searchRecipes()
- vm.recipeId = recipe.id
- $state.go('recipes.detail', {id: recipe.id})
- })
-
- $scope.$on('recipeDeleted', function () {
- if ($state.is('recipes.detail')) {
- var currentRecipeId = parseInt($state.params.id, 10)
- // Delete recipe from recipe list
- for (var i = 0; i < vm.recipes.length; i++) {
- if (vm.recipes[i].id === currentRecipeId) {
- vm.recipes.splice(i, 1)
- break
- }
- }
- // Delete recipe from `filtered list`
- // And redirect `next filtered recipe`
- for (i = 0; i < vm.filtered.length; i++) {
- if (vm.filtered[i].id === currentRecipeId) {
- if (vm.filtered[i + 1] != null) $state.go('recipes.detail', {id: vm.filtered[i + 1].id})
- else if (vm.filtered[i - 1] != null) $state.go('recipes.detail', {id: vm.filtered[i - 1].id})
- else $state.go('recipes')
-
- vm.filtered.splice(i, 1)
- break
- }
- }
-
- }
- })
-
- $scope.$on('tagSelected', function (e, tag) {
- e.stopPropagation()
- $scope.$apply(function () {
- vm.search = '#' + tag.name
- searchRecipes()
- })
- })
-
- function loadRecipes () {
- if ($auth.isAuthenticated) {
- Recipe.findMine()
- .success(function (data) {
- vm.recipes = data
- })
- } else {
- vm.recipes = void 0
- }
- }
-
- function searchRecipes () {
- vm.filtered = $filter('searchSnippets')(myRecipes, vm.search)
- if (vm.search && vm.filtered && vm.filtered[0] && (!vm.recipeId || vm.recipeId !== vm.filtered[0].id)) {
- $state.go('recipes.detail', {id: vm.filtered[0].id})
- }
- }
-
- })
diff --git a/src/browser/main/controllers/states/SettingsController.js b/src/browser/main/controllers/states/SettingsController.js
deleted file mode 100644
index d09e9f77..00000000
--- a/src/browser/main/controllers/states/SettingsController.js
+++ /dev/null
@@ -1,33 +0,0 @@
-/* global angular */
-angular.module('codexen')
- .controller('SettingsController', function (Settings) {
- var vm = this
-
- vm.changePassword = changePassword
- vm.isSuccess = false
- vm.isError = false
-
- function changePassword () {
- var params = {
- password: vm.password,
- newPassword: vm.newPassword
- }
-
- Settings.changePassword(params)
- .success(function (data) {
- resetInput()
- vm.isSuccess = true
- vm.isError = false
- })
- .error(function () {
- resetInput()
- vm.isError = true
- vm.isSuccess = false
- })
- }
-
- function resetInput () {
- vm.password = ''
- vm.newPassword = ''
- }
- })
diff --git a/src/browser/main/controllers/states/SnippetsDetailController.js b/src/browser/main/controllers/states/SnippetsDetailController.js
deleted file mode 100644
index c9d43312..00000000
--- a/src/browser/main/controllers/states/SnippetsDetailController.js
+++ /dev/null
@@ -1,31 +0,0 @@
-/* global angular */
-angular.module('codexen')
- .controller('SnippetsDetailController', function (Snippet, $state, $rootScope, $scope, Modal) {
- var vm = this
-
- vm.isLoaded = false
-
- var snippetId = $state.params.id
-
- Snippet.show(snippetId)
- .success(function (data) {
- vm.snippet = data
- vm.isLoaded = true
- })
-
- $scope.$on('taggingRequested', function (e) {
- e.stopPropagation()
- e.preventDefault()
- Modal.editSnippet(angular.copy(vm.snippet))
- .then(function (snippet) {
- console.log('edited', snippet)
- }, function () {
- console.log('edit snippet modal dismissed')
- })
- })
-
- $scope.$on('snippetUpdated', function (e, snippet) {
- console.log('event received', snippet)
- if (snippet.id === vm.snippet.id) vm.snippet = snippet
- })
- })
diff --git a/src/browser/main/controllers/states/SnippetsListController.js b/src/browser/main/controllers/states/SnippetsListController.js
deleted file mode 100644
index 384ccb32..00000000
--- a/src/browser/main/controllers/states/SnippetsListController.js
+++ /dev/null
@@ -1,107 +0,0 @@
-/* global angular */
-angular.module('codexen')
- .controller('SnippetsListController', function ($auth, Snippet, $scope, $state, $filter, mySnippets, User) {
- var vm = this
-
- vm.snippetId = parseInt($state.params.id)
-
- vm.snippets = mySnippets
-
- vm.searchSnippets = searchSnippets
- vm.searchSnippets()
-
- vm.isAuthenticated = $auth.isAuthenticated()
- var reloadUser = function () {
- if (vm.isAuthenticated) {
- User.me().success(function (data) {
- vm.currentUser = data
- })
- }
- }
- reloadUser()
-
- // TODO: add Navigation methods
- // vm.nextSnippet()
- // vm.priorSnippet()
- // vm.firstSnippet()
- // vm.lastSnippet()
-
- // TODO: keyboard navigating UX
-
- $scope.$on('$stateChangeSuccess', function (e, toState, toParams) {
- if (!toState.name.match(/snippets/)) return null
-
- vm.snippetId = parseInt(toParams.id, 10)
-
- if (!vm.snippetId && vm.filtered[0]) {
- $state.go('snippets.detail', {id: vm.filtered[0].id})
- }
- })
-
- $scope.$on('snippetUpdated', function (e, snippet) {
- if (!mySnippets.some(function (_snippet, index) {
- if (_snippet.id === snippet.id) {
- mySnippets[index] = snippet
- return true
- }
- return false
- })) mySnippets.unshift(snippet)
-
- searchSnippets()
- vm.snippetId = snippet.id
- $state.go('snippets.detail', {id: snippet.id})
- })
-
- $scope.$on('snippetDeleted', function () {
- if ($state.is('snippets.detail')) {
- var currentSnippetId = parseInt($state.params.id, 10)
- // Delete snippet from snippet list
- for (var i = 0; i < vm.snippets.length; i++) {
- if (vm.snippets[i].id === currentSnippetId) {
- vm.snippets.splice(i, 1)
- break
- }
- }
- // Delete snippet from `filtered list`
- // And redirect `next filtered snippet`
- for (i = 0; i < vm.filtered.length; i++) {
- if (vm.filtered[i].id === currentSnippetId) {
- if (vm.filtered[i + 1] != null) $state.go('snippets.detail', {id: vm.filtered[i + 1].id})
- else if (vm.filtered[i - 1] != null) $state.go('snippets.detail', {id: vm.filtered[i - 1].id})
- else $state.go('snippets')
-
- vm.filtered.splice(i, 1)
- break
- }
- }
-
- }
- })
-
- $scope.$on('tagSelected', function (e, tag) {
- e.stopPropagation()
- $scope.$apply(function () {
- vm.search = '#' + tag.name
- searchSnippets()
- })
- })
-
- function loadSnippets() {
- if ($auth.isAuthenticated) {
- Snippet.findMine()
- .success(function (data) {
- vm.snippets = data
- })
- } else {
- vm.snippets = void 0
- }
- }
-
- function searchSnippets () {
- vm.filtered = $filter('searchSnippets')(mySnippets, vm.search)
- if (vm.search && vm.filtered[0] && (!vm.snippetId || vm.snippetId !== vm.filtered[0].id)) {
- $state.go('snippets.detail', {id: vm.filtered[0].id})
- }
- }
-
- })
diff --git a/src/browser/main/directives/btn-delete-recipe.js b/src/browser/main/directives/btn-delete-recipe.js
deleted file mode 100644
index 78d6683f..00000000
--- a/src/browser/main/directives/btn-delete-recipe.js
+++ /dev/null
@@ -1,19 +0,0 @@
-/* global angular */
-angular.module('codexen')
- .directive('btnDeleteRecipe', function (Modal, $rootScope) {
- return {
- scope: {
- recipe: '=btnDeleteRecipe'
- },
- link: function (scope, el) {
- el.on('click', function () {
- Modal.deleteRecipe(scope.recipe)
- .then(function (recipe) {
- console.log('deleted', recipe)
- }, function () {
- console.log('delete snippet modal dismissed')
- })
- })
- }
- }
- })
diff --git a/src/browser/main/directives/btn-delete-snippet.js b/src/browser/main/directives/btn-delete-snippet.js
deleted file mode 100644
index 83e2b0af..00000000
--- a/src/browser/main/directives/btn-delete-snippet.js
+++ /dev/null
@@ -1,19 +0,0 @@
-/* global angular */
-angular.module('codexen')
- .directive('btnDeleteSnippet', function (Modal, $rootScope) {
- return {
- scope: {
- snippet: '=btnDeleteSnippet'
- },
- link: function (scope, el) {
- el.on('click', function () {
- Modal.deleteSnippet(scope.snippet)
- .then(function (snippet) {
- console.log('deleted', snippet)
- }, function () {
- console.log('delete snippet modal dismissed')
- })
- })
- }
- }
- })
diff --git a/src/browser/main/directives/btn-edit-recipe.js b/src/browser/main/directives/btn-edit-recipe.js
deleted file mode 100644
index db3149ae..00000000
--- a/src/browser/main/directives/btn-edit-recipe.js
+++ /dev/null
@@ -1,14 +0,0 @@
-/* global angular */
-angular.module('codexen')
- .directive('btnEditRecipe', function (Modal) {
- return {
- scope: {
- recipe: '=btnEditRecipe'
- },
- link: function (scope, el) {
- el.on('click', function () {
- Modal.editRecipe(angular.copy(scope.recipe))
- })
- }
- }
- })
diff --git a/src/browser/main/directives/btn-edit-snippet.js b/src/browser/main/directives/btn-edit-snippet.js
deleted file mode 100644
index 20467fc4..00000000
--- a/src/browser/main/directives/btn-edit-snippet.js
+++ /dev/null
@@ -1,14 +0,0 @@
-/* global angular */
-angular.module('codexen')
- .directive('btnEditSnippet', function (Modal) {
- return {
- scope: {
- snippet: '=btnEditSnippet'
- },
- link: function (scope, el) {
- el.on('click', function () {
- Modal.editSnippet(angular.copy(scope.snippet))
- })
- }
- }
- })
diff --git a/src/browser/main/directives/btn-expand-recipe.js b/src/browser/main/directives/btn-expand-recipe.js
deleted file mode 100644
index 41f3e2a0..00000000
--- a/src/browser/main/directives/btn-expand-recipe.js
+++ /dev/null
@@ -1,15 +0,0 @@
-/* global angular */
-angular.module('codexen')
- .directive('btnExpandRecipe', function (Modal) {
- return {
- restrict: 'A',
- scope: {
- recipe: '=btnExpandRecipe'
- },
- link: function (scope, el) {
- el.on('click', function () {
- Modal.expandRecipe(scope.recipe)
- })
- }
- }
- })
diff --git a/src/browser/main/directives/btn-new-recipe.js b/src/browser/main/directives/btn-new-recipe.js
deleted file mode 100644
index c40bac8e..00000000
--- a/src/browser/main/directives/btn-new-recipe.js
+++ /dev/null
@@ -1,12 +0,0 @@
-/* global angular */
-angular.module('codexen')
- .directive('btnNewRecipe', function (Modal) {
- return {
- restrict: 'A',
- link: function (scope, el) {
- el.on('click', function () {
- Modal.newRecipe()
- })
- }
- }
- })
diff --git a/src/browser/main/directives/btn-new-snippet.js b/src/browser/main/directives/btn-new-snippet.js
deleted file mode 100644
index c47c09e8..00000000
--- a/src/browser/main/directives/btn-new-snippet.js
+++ /dev/null
@@ -1,11 +0,0 @@
-/* global angular */
-angular.module('codexen')
- .directive('btnNewSnippet', function (Modal, $rootScope) {
- return {
- link: function (scope, el) {
- el.on('click', function () {
- Modal.newSnippet()
- })
- }
- }
- })
diff --git a/src/browser/main/directives/recipe-item.js b/src/browser/main/directives/recipe-item.js
deleted file mode 100644
index 32c42f1d..00000000
--- a/src/browser/main/directives/recipe-item.js
+++ /dev/null
@@ -1,19 +0,0 @@
-/* global angular */
-angular.module('codexen')
- .directive('recipeItem', function (Modal, $rootScope) {
- return {
- restrict: 'A',
- transclude: true,
- template: '',
- scope: {
- recipe: '=recipeItem'
- },
- link: function (scope, elem) {
- scope.$on('taggingRequested', function (e) {
- e.stopPropagation()
- e.preventDefault()
- Modal.editRecipe(angular.copy(scope.recipe))
- })
- }
- }
- })
diff --git a/src/browser/main/directives/side-nav.js b/src/browser/main/directives/side-nav.js
deleted file mode 100644
index 4f84a045..00000000
--- a/src/browser/main/directives/side-nav.js
+++ /dev/null
@@ -1,8 +0,0 @@
-/* global angular */
-angular.module('codexen')
- .directive('sideNav', function () {
- return {
- templateUrl: 'tpls/directives/side-nav.tpl.html',
- controller: 'SideNavController as vm'
- }
- })
diff --git a/src/browser/main/directives/snippet-item.js b/src/browser/main/directives/snippet-item.js
deleted file mode 100644
index 823c3941..00000000
--- a/src/browser/main/directives/snippet-item.js
+++ /dev/null
@@ -1,19 +0,0 @@
-/* global angular */
-angular.module('codexen')
- .directive('snippetItem', function (Modal, $rootScope) {
- return {
- restrict: 'A',
- transclude: true,
- template: '',
- scope: {
- snippet: '=snippetItem'
- },
- link: function (scope, elem) {
- scope.$on('taggingRequested', function (e) {
- e.stopPropagation()
- e.preventDefault()
- Modal.editSnippet(angular.copy(scope.snippet))
- })
- }
- }
- })
diff --git a/src/browser/main/directives/tag-item.js b/src/browser/main/directives/tag-item.js
deleted file mode 100644
index d919c461..00000000
--- a/src/browser/main/directives/tag-item.js
+++ /dev/null
@@ -1,16 +0,0 @@
-/* global angular */
-angular.module('codexen')
- .directive('tagItem', function () {
- return {
- restrict: 'A',
- template: '#',
- scope: {
- tag: '=tagItem'
- },
- link: function (scope, el) {
- el.on('click', function () {
- scope.$emit('tagSelected', scope.tag)
- })
- }
- }
- })
diff --git a/src/browser/main/directives/tag-list.js b/src/browser/main/directives/tag-list.js
deleted file mode 100644
index 8daf350b..00000000
--- a/src/browser/main/directives/tag-list.js
+++ /dev/null
@@ -1,28 +0,0 @@
-/* global angular */
-angular.module('codexen')
- .directive('tagList', function () {
- return {
- restrict: 'A',
- template: '' +
- ' ' +
- '' +
- ' Not tagged yet' +
- '
',
- scope: {
- tags: '=tagList'
- },
- link: function (scope, el) {
- el.ready(function () {
- el.find('a').on('click', function (e) {
- e.stopPropagation()
- })
- })
-
- scope.requestTagging = function (e) {
- e.preventDefault()
- e.stopPropagation()
- scope.$emit('taggingRequested')
- }
- }
- }
- })
diff --git a/src/browser/main/filters/from-now.js b/src/browser/main/filters/from-now.js
deleted file mode 100644
index d9686cad..00000000
--- a/src/browser/main/filters/from-now.js
+++ /dev/null
@@ -1,7 +0,0 @@
-/* global angular moment */
-angular.module('codexen')
- .filter('fromNow', function () {
- return function (input) {
- return moment(input).fromNow()
- }
- })
diff --git a/src/browser/main/filters/marked.js b/src/browser/main/filters/marked.js
deleted file mode 100644
index 40b2c311..00000000
--- a/src/browser/main/filters/marked.js
+++ /dev/null
@@ -1,19 +0,0 @@
-/* global angular marked*/
-angular.module('codexen')
- .filter('marked', function () {
- marked.setOptions({
- renderer: new marked.Renderer(),
- gfm: true,
- tables: true,
- breaks: false,
- pedantic: false,
- sanitize: true,
- smartLists: true,
- smartypants: false
- })
-
- return function (input) {
- if (!angular.isString(input)) input = ''
- return marked(input)
- }
- })
diff --git a/src/browser/main/filters/search-snippets.js b/src/browser/main/filters/search-snippets.js
deleted file mode 100644
index 6899a456..00000000
--- a/src/browser/main/filters/search-snippets.js
+++ /dev/null
@@ -1,17 +0,0 @@
-/* global angular */
-angular.module('codexen')
- .filter('searchSnippets', function ($filter) {
- return function (input, needle) {
- if (!angular.isString(needle) || !angular.isArray(input)) return angular.copy(input)
- if (needle.match(/#(.+)|tag:(.+)/)) {
- var name = needle.match(/#(.+)/) ? needle.match(/#(.+)/)[1] : needle.match(/tag:(.+)/)[1]
-
- return input.filter(function (snippet) {
- return snippet.Tags.some(function (tag) {
- return tag.name.match(new RegExp('^'+name))
- })
- })
- }
- else return $filter('filter')(input, needle)
- }
- })
diff --git a/src/browser/main/index.inject.html b/src/browser/main/index.inject.html
deleted file mode 100644
index 00a03de0..00000000
--- a/src/browser/main/index.inject.html
+++ /dev/null
@@ -1,41 +0,0 @@
-
-
-
-
- CodeXen App
-
-
-
-
-
-
-
- Codexen!
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/browser/main/services/Recipe.js b/src/browser/main/services/Recipe.js
deleted file mode 100644
index d60ac2d9..00000000
--- a/src/browser/main/services/Recipe.js
+++ /dev/null
@@ -1,52 +0,0 @@
-/* global angular */
-angular.module('codexen')
- .factory('Recipe', function ($http, $auth, apiUrl) {
- var findByUser = function (user) {
- var url = apiUrl + 'blueprints/search'
-
- return $http.get(url, {
- params: {
- user: user
- }
- })
- }
-
- var findMine = function (params) {
- var url = apiUrl + 'blueprints/my'
-
- return $http.get(url, {params: params})
- }
-
- var create = function (params) {
- var url = apiUrl + 'blueprints/create'
-
- return $http.post(url, params)
- }
-
- var show = function (id, params) {
- var url = apiUrl + 'blueprints/id/' + id
-
- return $http.get(url, {params: params})
- }
-
- var update = function (id, params) {
- var url = apiUrl + 'blueprints/id/' + id
-
- return $http.put(url, params)
- }
-
- var destroy = function (id) {
- var url = apiUrl + 'blueprints/id/' + id
-
- return $http.delete(url)
- }
-
- return {
- findByUser: findByUser,
- findMine: findMine,
- create: create,
- show: show,
- delete: destroy,
- update: update
- }
- })
diff --git a/src/browser/main/services/Settings.js b/src/browser/main/services/Settings.js
deleted file mode 100644
index bed4a943..00000000
--- a/src/browser/main/services/Settings.js
+++ /dev/null
@@ -1,13 +0,0 @@
-/* global angular */
-angular.module('codexen')
- .factory('Settings', function ($http, apiUrl) {
- var changePassword = function (params) {
- var url = apiUrl + 'settings/change_password'
-
- return $http.post(url, params)
- }
-
- return {
- changePassword: changePassword
- }
- })
diff --git a/src/browser/main/services/Tag.js b/src/browser/main/services/Tag.js
deleted file mode 100644
index 5b25fa93..00000000
--- a/src/browser/main/services/Tag.js
+++ /dev/null
@@ -1,17 +0,0 @@
-/* global angular */
-angular.module('codexen')
- .factory('Tag', function ($http, apiUrl) {
- var findByName = function (tagName) {
- var url = apiUrl + 'tags/search'
-
- return $http.get(url, {
- params: {
- name: tagName
- }
- })
- }
-
- return {
- findByName: findByName
- }
- })
diff --git a/src/browser/main/services/User.js b/src/browser/main/services/User.js
deleted file mode 100644
index 52e1c816..00000000
--- a/src/browser/main/services/User.js
+++ /dev/null
@@ -1,16 +0,0 @@
-/* global angular */
-angular.module('codexen')
- .factory('User', function ($http, apiUrl, $rootScope, $state) {
- $rootScope.$on('userSignOut', function () {
- $state.go('auth.signin')
- })
-
- var me = function () {
- var url = apiUrl + 'auth/user'
- return $http.get(url)
- }
-
- return {
- me: me
- }
- })
diff --git a/src/browser/main/styles/directives/ui-select.styl b/src/browser/main/styles/directives/ui-select.styl
deleted file mode 100644
index 96a688f5..00000000
--- a/src/browser/main/styles/directives/ui-select.styl
+++ /dev/null
@@ -1,232 +0,0 @@
-/*!
- * ui-select
- * http://github.com/angular-ui/ui-select
- * Version: 0.11.2 - 2015-03-17T04:08:46.478Z
- * License: MIT
- */
-
-
-/* Style when highlighting a search. */
-.ui-select-highlight
- font-weight: bold
-
-
-.ui-select-offscreen
- clip: rect(0 0 0 0) !important
- width: 1px !important
- height: 1px !important
- border: 0 !important
- margin: 0 !important
- padding: 0 !important
- overflow: hidden !important
- position: absolute !important
- outline: 0 !important
- left: 0px !important
- top: 0px !important
-
-
-/* Select2 theme */
-
-/* Mark invalid Select2 */
-.ng-dirty.ng-invalid > a.select2-choice
- border-color: #D44950
-
-
-.select2-result-single
- padding-left: 0
-
-
-.select2-locked > .select2-search-choice-close
- display:none
-
-
-.select-locked > .ui-select-match-close
- display:none
-
-
-body > .select2-container.open
- z-index: 9999 /* The z-index Select2 applies to the select2-drop */
-
-
-/* Selectize theme */
-
-/* Helper class to show styles when focus */
-.selectize-input.selectize-focus
- border-color: #007FBB !important
-
-
-/* Fix input width for Selectize theme */
-.selectize-control > .selectize-input > input
- width: 100%
-
-
-/* Fix dropdown width for Selectize theme */
-.selectize-control > .selectize-dropdown
- width: 100%
-
-
-/* Mark invalid Selectize */
-.ng-dirty.ng-invalid > div.selectize-input
- border-color: #D44950
-
-
-
-/* Bootstrap theme */
-
-/* Helper class to show styles when focus */
-.btn-default-focus
- color: #333
- background-color: #EBEBEB
- border-color: #ADADAD
- text-decoration: none
- outline: 5px auto -webkit-focus-ring-color
- outline-offset: -2px
- box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(102, 175, 233, 0.6)
-
-
-.ui-select-bootstrap .ui-select-toggle
- position: relative
- border-radius $input-border-radius
- .ui-select-placeholder
- color $textColor
-
-
-.ui-select-bootstrap .ui-select-toggle > .caret
- position: absolute
- height: 10px
- top: 50%
- right: 10px
- margin-top: -2px
-
-
-/* Fix Bootstrap dropdown position when inside a input-group */
-.input-group > .ui-select-bootstrap.dropdown
- /* Instead of relative */
- position: static
-
-
-.input-group > .ui-select-bootstrap > input.ui-select-search.form-control
- border-radius: $input-border-radius
- border-top-right-radius: 0
- border-bottom-right-radius: 0
-
-
-.ui-select-bootstrap > .ui-select-match > .btn
- /* Instead of center because of .btn */
- text-align: left !important
- padding-right: 25px
- border-radius $input-border-radius
- border solid 1px $input-border
-
-
-.ui-select-bootstrap > .ui-select-match > .caret
- position: absolute
- top: 45%
- right: 15px
-
-
-/* See Scrollable Menu with Bootstrap 3 http://stackoverflow.com/questions/19227496 */
-.ui-select-bootstrap > .ui-select-choices
- width: 100%
- height: auto
- max-height: 200px
- overflow-x: hidden
- margin-top: -1px
-
-
-body > .ui-select-bootstrap.open
- z-index: 1000 /* Standard Bootstrap dropdown z-index */
-
-
-.ui-select-multiple.ui-select-bootstrap
- height: auto
- padding: 3px 3px 0 10px
-
-
-.ui-select-multiple.ui-select-bootstrap.open
- border-color $input-border-focus
- outline 0
- box-shadow inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 8px rgba(red($input-border-focus), green($input-border-focus), blue($input-border-focus), .6)
-
-
-.ui-select-multiple.ui-select-bootstrap input.ui-select-search
- background-color: transparent !important /* To prevent double background when disabled */
- border: none
- outline: none
- height: 1.666666em
- margin-bottom: 3px
-
-
-.ui-select-multiple.ui-select-bootstrap .ui-select-match .close
- font-size: 1.6em
- line-height: 0.75
-
-
-.ui-select-multiple.ui-select-bootstrap .ui-select-match-item
- outline: 0
- margin: 0 3px 3px 0
-
-
-.ui-select-multiple .ui-select-match-item
- position: relative
-
-
-.ui-select-multiple .ui-select-match-item.dropping-before:before
- content: ""
- position: absolute
- top: 0
- right: 100%
- height: 100%
- margin-right: 2px
- border-left: 1px solid #428bca
-
-
-.ui-select-multiple .ui-select-match-item.dropping-after:after
- content: ""
- position: absolute
- top: 0
- left: 100%
- height: 100%
- margin-left: 2px
- border-right: 1px solid #428bca
-
-
-.ui-select-bootstrap .ui-select-choices-row>a
- display: block
- padding: 3px 20px
- clear: both
- font-weight: 400
- line-height: 1.42857143
- color: $dropdown-link-color
- white-space: nowrap
-
-
-.ui-select-bootstrap .ui-select-choices-row>a:hover, .ui-select-bootstrap .ui-select-choices-row>a:focus
- text-decoration: none
- color: $dropdown-link-hover-color
- background-color: $dropdown-link-hover-bg
-
-
-.ui-select-bootstrap .ui-select-choices-row.active>a
- color: $dropdown-link-hover-color
- text-decoration: none
- outline: 0
- background-color: $dropdown-link-hover-bg
-
-
-.ui-select-bootstrap .ui-select-choices-row.disabled>a,
-.ui-select-bootstrap .ui-select-choices-row.active.disabled>a
- color: #777
- cursor: not-allowed
- background-color: #fff
-
-
-/* fix hide/show angular animation */
-.ui-select-match.ng-hide-add,
-.ui-select-search.ng-hide-add
- display: none !important
-
-
-/* Mark invalid Bootstrap */
-.ui-select-bootstrap.ng-dirty.ng-invalid > button.btn.ui-select-match
- border-color: #D44950
diff --git a/src/browser/main/styles/modals/expand-recipe-modal.styl b/src/browser/main/styles/modals/expand-recipe-modal.styl
deleted file mode 100644
index 922114c4..00000000
--- a/src/browser/main/styles/modals/expand-recipe-modal.styl
+++ /dev/null
@@ -1,9 +0,0 @@
-.expand-recipe-modal
- .expand-editor
- .editor-pane
- height 500px
- .ace_editor
- height 500px
- .preview-pane
- height 500px
- overflow-y auto
diff --git a/src/browser/main/styles/modals/new-snippet-editor.styl b/src/browser/main/styles/modals/new-snippet-editor.styl
deleted file mode 100644
index c7ac15f8..00000000
--- a/src/browser/main/styles/modals/new-snippet-editor.styl
+++ /dev/null
@@ -1,4 +0,0 @@
-.new-snippet-modal
-
- .ace_editor
- height: 200px
diff --git a/src/browser/main/styles/modals/select-snippet-modal.styl b/src/browser/main/styles/modals/select-snippet-modal.styl
deleted file mode 100644
index 4054f19b..00000000
--- a/src/browser/main/styles/modals/select-snippet-modal.styl
+++ /dev/null
@@ -1,17 +0,0 @@
-.select-snippet-modal
- .snippet-list
- list-style none
- padding 0
- li
- padding 10px
- border solid 1px $baseBorderColor
- background-color $backgroundColorHighlight
- border-radius 5px
- margin-bottom 5px
- cursor pointer
- &:hover
- background-color $backgroundColorSelected
- .ace_editor
- height 150px
- .call-sign
- color $textColorHighlight
diff --git a/src/browser/main/styles/states/auth.styl b/src/browser/main/styles/states/auth.styl
deleted file mode 100644
index 13546720..00000000
--- a/src/browser/main/styles/states/auth.styl
+++ /dev/null
@@ -1,7 +0,0 @@
-.auth-state
- .panel
- margin-top 50px
- h1
- margin 15px 0
- .auth-control
- margin 10px 0
diff --git a/src/browser/main/styles/states/home.styl b/src/browser/main/styles/states/home.styl
deleted file mode 100644
index 80209e29..00000000
--- a/src/browser/main/styles/states/home.styl
+++ /dev/null
@@ -1,8 +0,0 @@
-.home-state
- padding 10px
- p
- margin 5px auto 15px
- ol
- margin 35px auto
- li
- margin-bottom 25px
diff --git a/src/browser/main/styles/states/settings.styl b/src/browser/main/styles/states/settings.styl
deleted file mode 100644
index 156ee4fa..00000000
--- a/src/browser/main/styles/states/settings.styl
+++ /dev/null
@@ -1,8 +0,0 @@
-.settings-state
- .panel
- margin-top 15px
- h1
- margin 30px 0
- .section
- h4
- margin-bottom 15px
diff --git a/src/browser/main/styles/states/snippets.styl b/src/browser/main/styles/states/snippets.styl
deleted file mode 100644
index e0e5635a..00000000
--- a/src/browser/main/styles/states/snippets.styl
+++ /dev/null
@@ -1,132 +0,0 @@
-$left-pane-width= 275px
-
-
-$pane-border-color= $border-color
-$snippet-list-border-color= $border-color
-$snippet-list-item-hover-bg= #EEE
-$snippet-list-active-color= white
-$snippet-list-active-bg= $brand-primary
-
-.snippets-list-state
- position: absolute
- top:0
- left:0
- right:0
- bottom:0
- .left-pane
- border-right 1px solid $baseBorderColor
- position: absolute
- top: 0
- bottom: 0
- left: 0
- width: $left-pane-width
- overflow:hidden
- .snippet-search
- position: absolute
- top: 0
- height: 50px
- left: 0
- right: 0
- border-right 1px solid $baseBorderColor
- padding: 7px 5px
-
- .snippet-list
- position: absolute
- top: 50px
- bottom: 0
- left: 0
- right: 0
- overflow-x: hidden
- overflow-y: auto
- list-style: none
- padding: 0
- li
- cursor: pointer
- padding: 5px
- border-right 1px solid $baseBorderColor
- border-bottom 1px solid $baseBorderColor
- &:nth-child(even)
- background-color $baseBackgroundColor
- &:nth-child(odd)
- background-color lighten($baseBackgroundColor, 2%)
- h4
- margin: 0
-
- &:hover
- background-color: $backgroundColorSelected
-
- p
- margin:0
-
- p.call-sign
- font-size:0.8em
-
- p.created-at
- font-size:0.8em
- opacity: 0.8
-
- &.active
- color: $snippet-list-active-color
- background-color: $snippet-list-active-bg
- a
- color: white
-
-
-
-
-
- .right-pane
- position: absolute
- top: 0
- bottom: 0
- left: $left-pane-width
- right: 0
- overflow-x: hidden
- overflow-y: auto
- background-color lighten($baseBackgroundColor, 2%)
-
-
-
-.snippets-detail-state
- position absolute
- top 0
- width 100%
- bottom 0
- overflow hidden
- .detail-header
- position absolute
- top 0
- width 100%
- background-color lighten($baseBackgroundColor, 5%)
- padding 5px 10px
- height 50px
- border-bottom solid 1px $baseBorderColor
- .detail-header-title
- color $textColorHighlight
- line-height 40px
- font-size 1.2em
- small
- font-size: 0.6em
- color $textColor
-
-
- .detail-header-control
- padding 3px
-
- .detail-body
- position absolute
- top 50px
- width 100%
- bottom 0
- padding 5px 10px
- overflow-y auto
- .ace_editor
- min-height 300px
- border solid 1px $border-color
- border-radius 5px
- margin-bottom 5px
-
-.tags
- word-break: break-all
- a
- margin: 0 2px
diff --git a/src/browser/main/tpls/directives/snippet-view.html b/src/browser/main/tpls/directives/snippet-view.html
deleted file mode 100644
index c8cfb83b..00000000
--- a/src/browser/main/tpls/directives/snippet-view.html
+++ /dev/null
@@ -1,14 +0,0 @@
-
diff --git a/src/browser/main/tpls/modals/delete-recipe-modal.html b/src/browser/main/tpls/modals/delete-recipe-modal.html
deleted file mode 100644
index 67e98b20..00000000
--- a/src/browser/main/tpls/modals/delete-recipe-modal.html
+++ /dev/null
@@ -1,19 +0,0 @@
-
-
-
-
-
- Are you sure to delete it?
-
-
- Snippets of this recipe will not be removed.
-
-
-
-
-
diff --git a/src/browser/main/tpls/modals/delete-snippet-modal.tpl.html b/src/browser/main/tpls/modals/delete-snippet-modal.tpl.html
deleted file mode 100644
index a2079525..00000000
--- a/src/browser/main/tpls/modals/delete-snippet-modal.tpl.html
+++ /dev/null
@@ -1,16 +0,0 @@
-
-
-
-
-
- Are you sure to delete it?
-
-
-
-
-
diff --git a/src/browser/main/tpls/modals/edit-recipe-modal.html b/src/browser/main/tpls/modals/edit-recipe-modal.html
deleted file mode 100644
index c7fc3211..00000000
--- a/src/browser/main/tpls/modals/edit-recipe-modal.html
+++ /dev/null
@@ -1,60 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
- Markdown
-
-
-
-
-
-
- Preview
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/browser/main/tpls/modals/edit-snippet-modal.tpl.html b/src/browser/main/tpls/modals/edit-snippet-modal.tpl.html
deleted file mode 100644
index e337c9f2..00000000
--- a/src/browser/main/tpls/modals/edit-snippet-modal.tpl.html
+++ /dev/null
@@ -1,49 +0,0 @@
-
diff --git a/src/browser/main/tpls/modals/expand-recipe-modal.html b/src/browser/main/tpls/modals/expand-recipe-modal.html
deleted file mode 100644
index e2d64a31..00000000
--- a/src/browser/main/tpls/modals/expand-recipe-modal.html
+++ /dev/null
@@ -1,37 +0,0 @@
-
diff --git a/src/browser/main/tpls/modals/new-recipe-modal.html b/src/browser/main/tpls/modals/new-recipe-modal.html
deleted file mode 100644
index c7fc3211..00000000
--- a/src/browser/main/tpls/modals/new-recipe-modal.html
+++ /dev/null
@@ -1,60 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
- Markdown
-
-
-
-
-
-
- Preview
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/browser/main/tpls/modals/new-snippet-modal.tpl.html b/src/browser/main/tpls/modals/new-snippet-modal.tpl.html
deleted file mode 100644
index 367c2b1f..00000000
--- a/src/browser/main/tpls/modals/new-snippet-modal.tpl.html
+++ /dev/null
@@ -1,49 +0,0 @@
-
diff --git a/src/browser/main/tpls/modals/select-snippet-modal.html b/src/browser/main/tpls/modals/select-snippet-modal.html
deleted file mode 100644
index 2fa0c419..00000000
--- a/src/browser/main/tpls/modals/select-snippet-modal.html
+++ /dev/null
@@ -1,25 +0,0 @@
-
diff --git a/src/browser/main/tpls/modals/sign-out-modal.html b/src/browser/main/tpls/modals/sign-out-modal.html
deleted file mode 100644
index db967182..00000000
--- a/src/browser/main/tpls/modals/sign-out-modal.html
+++ /dev/null
@@ -1,16 +0,0 @@
-
-
-
-
-
- Are you sure to sign out?
-
-
-
-
-
diff --git a/src/browser/main/tpls/states/auth.register.tpl.html b/src/browser/main/tpls/states/auth.register.tpl.html
deleted file mode 100644
index f34b2f37..00000000
--- a/src/browser/main/tpls/states/auth.register.tpl.html
+++ /dev/null
@@ -1,54 +0,0 @@
-
-
diff --git a/src/browser/main/tpls/states/auth.signin.tpl.html b/src/browser/main/tpls/states/auth.signin.tpl.html
deleted file mode 100644
index 3cd9ada6..00000000
--- a/src/browser/main/tpls/states/auth.signin.tpl.html
+++ /dev/null
@@ -1,18 +0,0 @@
-
diff --git a/src/browser/main/tpls/states/auth.tpl.html b/src/browser/main/tpls/states/auth.tpl.html
deleted file mode 100644
index 439fd2e4..00000000
--- a/src/browser/main/tpls/states/auth.tpl.html
+++ /dev/null
@@ -1,19 +0,0 @@
-
-
-
-
-
-
-
Authentication
-
-
-
-
-
-
-
-
-
-
diff --git a/src/browser/main/tpls/states/recipes.detail.html b/src/browser/main/tpls/states/recipes.detail.html
deleted file mode 100644
index cafc6c44..00000000
--- a/src/browser/main/tpls/states/recipes.detail.html
+++ /dev/null
@@ -1,33 +0,0 @@
-
diff --git a/src/browser/main/tpls/states/recipes.list.tpl.html b/src/browser/main/tpls/states/recipes.list.tpl.html
deleted file mode 100644
index a799929b..00000000
--- a/src/browser/main/tpls/states/recipes.list.tpl.html
+++ /dev/null
@@ -1,62 +0,0 @@
-
-
-
-
-
-
- -
-
- Loading
-
-
-
- -
-
- Empty List
-
-
-
-
- -
-
- Sign In to access
-
- Sign In
-
-
- -
-
-
-
-
-
-
-
-
- No snippet selected.
-
-
-
-
-
-
diff --git a/src/browser/main/tpls/states/settings.tpl.html b/src/browser/main/tpls/states/settings.tpl.html
deleted file mode 100644
index febf471d..00000000
--- a/src/browser/main/tpls/states/settings.tpl.html
+++ /dev/null
@@ -1,33 +0,0 @@
-
-
-
-
Settings
-
- Some settings...
-
-
-
-
-
-
diff --git a/src/browser/main/tpls/states/snippets.detail.tpl.html b/src/browser/main/tpls/states/snippets.detail.tpl.html
deleted file mode 100644
index d696031d..00000000
--- a/src/browser/main/tpls/states/snippets.detail.tpl.html
+++ /dev/null
@@ -1,41 +0,0 @@
-
diff --git a/src/browser/main/tpls/states/snippets.list.tpl.html b/src/browser/main/tpls/states/snippets.list.tpl.html
deleted file mode 100644
index eed329bc..00000000
--- a/src/browser/main/tpls/states/snippets.list.tpl.html
+++ /dev/null
@@ -1,64 +0,0 @@
-
-
-
-
-
-
- -
-
- Loading
-
-
-
- -
-
- Empty List
-
-
-
-
- -
-
- Sign In to access
-
- Sign In
-
-
- -
-
-
-
-
-
-
-
-
- No snippet selected.
-
-
-
-
-
-
diff --git a/src/browser/popup/index.html b/src/browser/popup/index.html
deleted file mode 100644
index ed7f3c2c..00000000
--- a/src/browser/popup/index.html
+++ /dev/null
@@ -1,66 +0,0 @@
-
-
-
-
- CodeXen App
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/browser/popup/index.inject.html b/src/browser/popup/index.inject.html
deleted file mode 100644
index 89a28e8b..00000000
--- a/src/browser/popup/index.inject.html
+++ /dev/null
@@ -1,56 +0,0 @@
-
-
-
-
- CodeXen App
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/browser/popup/popup.js b/src/browser/popup/popup.js
deleted file mode 100644
index 76a52fd5..00000000
--- a/src/browser/popup/popup.js
+++ /dev/null
@@ -1,192 +0,0 @@
-/* global angular */
-
-var remote = require('remote')
-var ipc = require('ipc')
-
-var resultList = document.getElementById('result-list')
-
-angular.module('codexen.popup', [
- 'codexen.shared',
- 'ui.ace',
- 'satellizer',
- 'cfp.hotkeys'
-])
-.constant('appName', 'popup')
-.controller('PopUpController', function ($scope, Snippet, $auth, $window, hotkeys, $document, $filter) {
- // Setup Events
- remote.getCurrentWindow().on('focus', function () {
- if (!$auth.isAuthenticated()) return hidePopUp()
- $scope.$apply(focusSearchInput)
- loadSnippets()
- })
-
- hotkeys.bindTo($scope)
- .add('down', function (e) {
- nextSnippet()
- e.preventDefault()
- })
- .add('up', function (e) {
- priorSnippet()
- e.preventDefault()
- })
- .add('right', function (e) {
- e.preventDefault()
- })
- .add('left', function (e) {
- e.preventDefault()
- })
- .add('esc', function (e) {
- hidePopUp()
- })
- .add('shift+tab', function (e) {
- e.preventDefault()
- })
- .add('tab', function (e) {
- e.preventDefault()
- })
- .add('enter', function (e) {
- writeCode($scope.selectedItem.content)
- e.preventDefault()
- })
-
- $scope.aceLoaded = function (editor) {
- editor.commands.addCommand({
- name: 'escape',
- bindKey: {win: 'esc', mac: 'esc'},
- exec: function (editor) {
- editor.blur()
- $scope.$apply()
- },
- readOnly: true
- })
- }
-
- $scope.$on('nextSnippetRequested', function (e) {
- e.stopPropagation()
- nextSnippet()
- })
-
- $scope.$on('priorSnippetRequested', function (e) {
- e.stopPropagation()
- priorSnippet()
- })
-
- $scope.$on('snippetSubmitted', function (e) {
- if ($scope.filteredSnippets.length > 0) ipc.send('writeCode', $scope.selectedItem.content)
- else console.log('\x07')
- e.stopPropagation()
- })
-
- // Init Data
- $scope.snippets = []
-
- Snippet.findMine()
- .success(function (data) {
- $scope.snippets = data
- filterList()
- })
-
- // Result Item control
- $scope.selectIndex = 0
-
- $scope.selectSnippet = selectSnippet
- $scope.filterList = filterList
- $scope.writeCode = writeCode
- $scope.focusSearchInput = focusSearchInput
-
- // Search Filter
- function loadSnippets () {
- Snippet.findMine()
- .success(function (data) {
- $scope.snippets = data
- filterList()
- })
- }
-
- function filterList (needle) {
- $scope.filteredSnippets = $filter('filter')($scope.snippets, needle)
- firstSnippet()
- }
-
- function selectSnippet (index) {
- if (index !== undefined) $scope.selectIndex = index
- $scope.selectedItem = $scope.filteredSnippets[$scope.selectIndex]
- }
-
- function firstSnippet () {
- $scope.selectIndex = 0
- selectSnippet($scope.selectIndex)
- }
-
- function priorSnippet () {
- if ($scope.selectIndex > 0) $scope.selectIndex -= 1
-
- if (resultList.children[$scope.selectIndex].offsetTop < resultList.scrollTop) {
- resultList.scrollTop -= 33
- }
-
- selectSnippet()
- }
-
- function nextSnippet () {
- if ($scope.selectIndex < $scope.filteredSnippets.length - 1) {
- $scope.selectIndex += 1
- }
-
- if (resultList.clientHeight - 33 < resultList.children[$scope.selectIndex].offsetTop - resultList.scrollTop) {
- resultList.scrollTop += 33
- }
-
- selectSnippet()
- }
-
- function writeCode (code) {
- ipc.send('writeCode', code)
- }
-
- // Focusing Search Input
- function focusSearchInput () {
- document.getElementById('search-input').focus()
- }
-
- function hidePopUp () {
- ipc.send('hidePopUp')
- }
-
-})
-.directive('searchInput', function () {
- return {
- restrict: 'A',
- link: function (scope, el, attr) {
- el.on('keydown', function (e) {
- // Down key => Focus on Result list
- if (e.keyCode === 40) {
- scope.$emit('nextSnippetRequested')
- // e.preventDefault()
- }
-
- // Up key => Focus on Result list
- if (e.keyCode === 38) {
- scope.$emit('priorSnippetRequested')
- // e.preventDefault()
- }
-
- // Up key => Focus on Result list
- if (e.keyCode === 13) {
- scope.$emit('snippetSubmitted')
- }
-
- // Esc key => Dismiss popup
- if (e.keyCode === 27) {
- ipc.send('hidePopUp')
- e.preventDefault()
- }
-
- // TODO: Tab key => Auto complete
- if (e.keyCode === 9) {
- e.preventDefault()
- }
- })
- }
- }
-})
diff --git a/src/browser/popup/services/snippet.js b/src/browser/popup/services/snippet.js
deleted file mode 100644
index d28dfed6..00000000
--- a/src/browser/popup/services/snippet.js
+++ /dev/null
@@ -1,62 +0,0 @@
-/* global angular */
-angular.module('codexen.popup')
- .constant('apiUrl', 'http://codexen-server-dev.elasticbeanstalk.com/')
- .config(function ($authProvider, $httpProvider, apiUrl) {
- $authProvider.baseUrl = apiUrl
-
- $httpProvider.defaults.useXDomain = true
- delete $httpProvider.defaults.headers.common['X-Requested-With']
- })
-
-
-angular.module('codexen.popup')
- .factory('Snippet', function ($http, $auth, apiUrl) {
- var findByUser = function (user) {
- var url = apiUrl + 'snippets/search'
-
- return $http.get(url, {
- params: {
- user: user
- }
- })
- }
-
- var findMine = function (params) {
- var url = apiUrl + 'snippets/my'
-
- return $http.get(url, {params: params})
- }
-
- var create = function (params) {
- var url = apiUrl + 'snippets/create'
-
- return $http.post(url, params)
- }
-
- var show = function (id, params) {
- var url = apiUrl + 'snippets/id/' + id
-
- return $http.get(url, {params: params})
- }
-
- var update = function (id, params) {
- var url = apiUrl + 'snippets/id/' + id
-
- return $http.put(url, params)
- }
-
- var destroy = function (id) {
- var url = apiUrl + 'snippets/id/' + id
-
- return $http.delete(url)
- }
-
- return {
- findByUser: findByUser,
- findMine: findMine,
- create: create,
- show: show,
- delete: destroy,
- update: update
- }
- })
diff --git a/src/browser/popup/styles/_popup.styl b/src/browser/popup/styles/_popup.styl
deleted file mode 100644
index 87f2338b..00000000
--- a/src/browser/popup/styles/_popup.styl
+++ /dev/null
@@ -1,60 +0,0 @@
-.popup-body
- .search-block
- padding: 5px
- height:44px
- position:absolute
- top: 0
- width: 100%
-
- .result-block
- position:absolute
- top: 44px
- bottom: 0
- width: 100%
- overflow: hidden
- .left-pane
- margin: 0
- position: absolute
- left: 0
- top: 0
- bottom: 0
- width: 40%
- overflow-y: auto
- overflow-x: hidden
- .result-list
- list-style:none
- padding: 0
- border-right: 1px solid $baseBorderColor
- li
- white-space nowrap
- &:nth-child(even)
- background-color $baseBackgroundColor
- &:nth-child(odd)
- background-color lighten($baseBackgroundColor, 2%)
- &.active
- color: $textColorSelected
- background-color: $btnPrimary
- a
- display:block
- padding: 5px 10px
- border-bottom 1px solid $baseBorderColor
-
- .right-pane
- position: absolute
- left: 40%
- top: 0
- bottom: 0
- width: 60%
- overflow-y: auto
- overflow-x: hidden
- .result-detail-control
- position: absolute
- top: 0
- width: 100%
- height: 34px
-
- .result-detail-content
- position: absolute
- top: 34px
- bottom: 0
- width: 100%
diff --git a/src/browser/popup/styles/app.css b/src/browser/popup/styles/app.css
deleted file mode 100644
index 7721a28d..00000000
--- a/src/browser/popup/styles/app.css
+++ /dev/null
@@ -1,68 +0,0 @@
-.popup-body .search-block {
- padding: 5px;
- height: 44px;
- position: absolute;
- top: 0;
- width: 100%;
-}
-.popup-body .result-block {
- position: absolute;
- top: 44px;
- bottom: 0;
- width: 100%;
- overflow: hidden;
-}
-.popup-body .result-block .left-pane {
- margin: 0;
- position: absolute;
- left: 0;
- top: 0;
- bottom: 0;
- width: 40%;
- overflow-y: auto;
- overflow-x: hidden;
-}
-.popup-body .result-block .result-list {
- list-style: none;
- padding: 0;
- border-right: 1px solid #001a20;
-}
-.popup-body .result-block .result-list li {
- white-space: nowrap;
-}
-.popup-body .result-block .result-list li:nth-child(even) {
- background-color: #002b36;
-}
-.popup-body .result-block .result-list li:nth-child(odd) {
- background-color: #00323f;
-}
-.popup-body .result-block .result-list li.active {
- color: #fff;
- background-color: #088cff;
-}
-.popup-body .result-block .result-list li a {
- display: block;
- padding: 5px 10px;
- border-bottom: 1px solid #001a20;
-}
-.popup-body .result-block .right-pane {
- position: absolute;
- left: 40%;
- top: 0;
- bottom: 0;
- width: 60%;
- overflow-y: auto;
- overflow-x: hidden;
-}
-.popup-body .result-block .result-detail-control {
- position: absolute;
- top: 0;
- width: 100%;
- height: 34px;
-}
-.popup-body .result-block .result-detail-content {
- position: absolute;
- top: 34px;
- bottom: 0;
- width: 100%;
-}
diff --git a/src/browser/popup/styles/app.styl b/src/browser/popup/styles/app.styl
deleted file mode 100644
index 090d691f..00000000
--- a/src/browser/popup/styles/app.styl
+++ /dev/null
@@ -1,4 +0,0 @@
-@import '../../shared/styles/_vars'
-@import '../../shared/styles/mixins/*'
-
-@import '_popup'
diff --git a/src/browser/shared/config/ace.js b/src/browser/shared/config/ace.js
deleted file mode 100644
index fff0e713..00000000
--- a/src/browser/shared/config/ace.js
+++ /dev/null
@@ -1,3 +0,0 @@
-/* global angular */
-angular.module('codexen.shared')
- .constant('aceModes', ['ABAP', 'ABC', 'ActionScript', 'ADA', 'Apache_Conf', 'AsciiDoc', 'Assembly_x86', 'AutoHotKey', 'BatchFile', 'C9Search', 'C_Cpp', 'Cirru', 'Clojure', 'Cobol', 'coffee', 'ColdFusion', 'CSharp', 'CSS', 'Curly', 'D', 'Dart', 'Diff', 'Dockerfile', 'Dot', 'Dummy', 'DummySyntax', 'Eiffel', 'EJS', 'Elixir', 'Elm', 'Erlang', 'Forth', 'FTL', 'Gcode', 'Gherkin', 'Gitignore', 'Glsl', 'golang', 'Groovy', 'HAML', 'Handlebars', 'Haskell', 'haXe', 'HTML', 'HTML_Ruby', 'INI', 'Io', 'Jack', 'Jade', 'Java', 'JavaScript', 'JSON', 'JSONiq', 'JSP', 'JSX', 'Julia', 'LaTeX', 'Lean', 'LESS', 'Liquid', 'Lisp', 'LiveScript', 'LogiQL', 'LSL', 'Lua', 'LuaPage', 'Lucene', 'Makefile', 'Markdown', 'Mask', 'MATLAB', 'MEL', 'MUSHCode', 'MySQL', 'Nix', 'ObjectiveC', 'OCaml', 'Pascal', 'Perl', 'pgSQL', 'PHP', 'Powershell', 'Praat', 'Prolog', 'Properties', 'Protobuf', 'Python', 'R', 'RDoc', 'RHTML', 'Ruby', 'Rust', 'SASS', 'SCAD', 'Scala', 'Scheme', 'SCSS', 'SH', 'SJS', 'Smarty', 'snippets', 'Soy_Template', 'Space', 'SQL', 'SQLServer', 'Stylus', 'SVG', 'Tcl', 'Tex', 'Text', 'Textile', 'Toml', 'Twig', 'Typescript', 'Vala', 'VBScript', 'Velocity', 'Verilog', 'VHDL', 'XML', 'XQuery', 'YAML', 'Django'])
diff --git a/src/browser/shared/config/env.js b/src/browser/shared/config/env.js
deleted file mode 100644
index 51fe6bc9..00000000
--- a/src/browser/shared/config/env.js
+++ /dev/null
@@ -1,4 +0,0 @@
-/* global angular */
-angular.module('codexen.shared')
- // .constant('apiUrl', 'http://localhost:8000/')
- .constant('apiUrl', 'http://codexen-server-dev.elasticbeanstalk.com/')
diff --git a/src/browser/shared/config/satellizer.js b/src/browser/shared/config/satellizer.js
deleted file mode 100644
index ca15816a..00000000
--- a/src/browser/shared/config/satellizer.js
+++ /dev/null
@@ -1,8 +0,0 @@
-/* global angular */
-angular.module('codexen.shared')
- .config(function ($authProvider, $httpProvider, apiUrl) {
- $authProvider.baseUrl = apiUrl
-
- $httpProvider.defaults.useXDomain = true
- delete $httpProvider.defaults.headers.common['X-Requested-With']
- })
diff --git a/src/browser/shared/directives/ui-ace.js b/src/browser/shared/directives/ui-ace.js
deleted file mode 100644
index 72f49e9e..00000000
--- a/src/browser/shared/directives/ui-ace.js
+++ /dev/null
@@ -1,386 +0,0 @@
-/* global angular */
-'use strict'
-
-/**
- * Binds a ACE Editor widget
- */
-angular.module('ui.ace', [])
- .constant('uiAceConfig', {})
- .directive('uiAce', ['uiAceConfig', function (uiAceConfig) {
- if (angular.isUndefined(window.ace)) {
- throw new Error('ui-ace need ace to work... (o rly?)')
- }
-
- /**
- * Sets editor options such as the wrapping mode or the syntax checker.
- *
- * The supported options are:
- *
- *
- * - showGutter
- * - useWrapMode
- * - onLoad
- * - theme
- * - mode
- *
- *
- * @param acee
- * @param session ACE editor session
- * @param {object} opts Options to be set
- */
- var setOptions = function (acee, session, opts) {
- // sets the ace worker path, if running from concatenated
- // or minified source
- if (angular.isDefined(opts.workerPath)) {
- var config = window.ace.require('ace/config')
- config.set('workerPath', opts.workerPath)
- }
- // ace requires loading
- if (angular.isDefined(opts.require)) {
- opts.require.forEach(function (n) {
- window.ace.require(n)
- })
- }
- // Boolean options
- if (angular.isDefined(opts.showGutter)) {
- acee.renderer.setShowGutter(opts.showGutter)
- }
- if (angular.isDefined(opts.useWrapMode)) {
- session.setUseWrapMode(opts.useWrapMode)
- }
- if (angular.isDefined(opts.showInvisibles)) {
- acee.renderer.setShowInvisibles(opts.showInvisibles)
- }
- if (angular.isDefined(opts.showIndentGuides)) {
- acee.renderer.setDisplayIndentGuides(opts.showIndentGuides)
- }
- if (angular.isDefined(opts.useSoftTabs)) {
- session.setUseSoftTabs(opts.useSoftTabs)
- }
- if (angular.isDefined(opts.showPrintMargin)) {
- acee.setShowPrintMargin(opts.showPrintMargin)
- }
- if (angular.isDefined(opts.maxLines)) {
- if (opts.maxLines < 0) opts.maxLines = Infinity
- acee.setOptions({
- maxLines: opts.maxLines
- })
- }
-
- // commands
- if (angular.isDefined(opts.disableSearch) && opts.disableSearch) {
- acee.commands.addCommands([
- {
- name: 'unfind',
- bindKey: {
- win: 'Ctrl-F',
- mac: 'Command-F'
- },
- exec: function () {
- return false
- },
- readOnly: true
- }
- ])
- }
-
- // Basic options
- if (angular.isString(opts.theme)) {
- acee.setTheme('ace/theme/' + opts.theme)
- }
- if (angular.isString(opts.mode)) {
- session.setMode('ace/mode/' + opts.mode)
- }
- // Advanced options
- if (angular.isDefined(opts.firstLineNumber)) {
- if (angular.isNumber(opts.firstLineNumber)) {
- session.setOption('firstLineNumber', opts.firstLineNumber)
- } else if (angular.isFunction(opts.firstLineNumber)) {
- session.setOption('firstLineNumber', opts.firstLineNumber())
- }
- }
-
- // advanced options
- var key, obj
- if (angular.isDefined(opts.advanced)) {
- for (key in opts.advanced) {
- // create a javascript object with the key and value
- obj = { name: key, value: opts.advanced[key] }
- // try to assign the option to the ace editor
- acee.setOption(obj.name, obj.value)
- }
- }
-
- // advanced options for the renderer
- if (angular.isDefined(opts.rendererOptions)) {
- for (key in opts.rendererOptions) {
- // create a javascript object with the key and value
- obj = { name: key, value: opts.rendererOptions[key] }
- // try to assign the option to the ace editor
- acee.renderer.setOption(obj.name, obj.value)
- }
- }
-
- // onLoad callbacks
- angular.forEach(opts.callbacks, function (cb) {
- if (angular.isFunction(cb)) {
- cb(acee)
- }
- })
- }
-
- return {
- restrict: 'EA',
- require: '?ngModel',
- link: function (scope, elm, attrs, ngModel) {
- /**
- * Corresponds the uiAceConfig ACE configuration.
- * @type object
- */
- var options = uiAceConfig.ace || {}
-
- /**
- * uiAceConfig merged with user options via json in attribute or data binding
- * @type object
- */
- var opts = angular.extend({}, options, scope.$eval(attrs.uiAce))
-
- /**
- * ACE editor
- * @type object
- */
- var acee = window.ace.edit(elm[0])
- acee.$blockScrolling = Infinity
-
- /**
- * ACE editor session.
- * @type object
- * @see [EditSession]{@link http://ace.c9.io/#nav=api&api=edit_session}
- */
- var session = acee.getSession()
-
- /**
- * Reference to a change listener created by the listener factory.
- * @function
- * @see listenerFactory.onChange
- */
- var onChangeListener
-
- /**
- * Reference to a blur listener created by the listener factory.
- * @function
- * @see listenerFactory.onBlur
- */
- var onBlurListener
-
- /**
- * Calls a callback by checking its existing. The argument list
- * is variable and thus this function is relying on the arguments
- * object.
- * @throws {Error} If the callback isn't a function
- */
- var executeUserCallback = function () {
- /**
- * The callback function grabbed from the array-like arguments
- * object. The first argument should always be the callback.
- *
- * @see [arguments]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions_and_function_scope/arguments}
- * @type {*}
- */
- var callback = arguments[0]
-
- /**
- * Arguments to be passed to the callback. These are taken
- * from the array-like arguments object. The first argument
- * is stripped because that should be the callback function.
- *
- * @see [arguments]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions_and_function_scope/arguments}
- * @type {Array}
- */
- var args = Array.prototype.slice.call(arguments, 1)
-
- if (angular.isDefined(callback)) {
- scope.$evalAsync(function () {
- if (angular.isFunction(callback)) {
- callback(args)
- } else {
- throw new Error('ui-ace use a function as callback.')
- }
- })
- }
- }
-
- /**
- * Listener factory. Until now only change listeners can be created.
- * @type object
- */
- var listenerFactory = {
- /**
- * Creates a change listener which propagates the change event
- * and the editor session to the callback from the user option
- * onChange. It might be exchanged during runtime, if this
- * happens the old listener will be unbound.
- *
- * @param callback callback function defined in the user options
- * @see onChangeListener
- */
- onChange: function (callback) {
- return function (e) {
- var newValue = session.getValue()
-
- if (ngModel && newValue !== ngModel.$viewValue &&
- // HACK make sure to only trigger the apply outside of the
- // digest loop 'cause ACE is actually using this callback
- // for any text transformation !
- !scope.$$phase && !scope.$root.$$phase) {
- scope.$evalAsync(function () {
- ngModel.$setViewValue(newValue)
- })
- }
-
- executeUserCallback(callback, e, acee)
- }
- },
- /**
- * Creates a blur listener which propagates the editor session
- * to the callback from the user option onBlur. It might be
- * exchanged during runtime, if this happens the old listener
- * will be unbound.
- *
- * @param callback callback function defined in the user options
- * @see onBlurListener
- */
- onBlur: function (callback) {
- return function () {
- executeUserCallback(callback, acee)
- }
- }
- }
-
- attrs.$observe('readonly', function (value) {
- acee.setReadOnly(!!value || value === '')
- })
-
- // Value Blind
- if (ngModel) {
- ngModel.$formatters.push(function (value) {
- if (angular.isUndefined(value) || value === null) {
- return ''
- } else if (angular.isObject(value) || angular.isArray(value)) {
- throw new Error('ui-ace cannot use an object or an array as a model')
- }
- return value
- })
-
- ngModel.$render = function () {
- session.setValue(ngModel.$viewValue)
- }
- }
-
- // Listen for option updates
- var updateOptions = function (current, previous) {
- if (current === previous) return
- opts = angular.extend({}, options, scope.$eval(attrs.uiAce))
-
- opts.callbacks = [ opts.onLoad ]
- if (opts.onLoad !== options.onLoad) {
- // also call the global onLoad handler
- opts.callbacks.unshift(options.onLoad)
- }
-
- // EVENTS
-
- // unbind old change listener
- session.removeListener('change', onChangeListener)
-
- // bind new change listener
- onChangeListener = listenerFactory.onChange(opts.onChange)
- session.on('change', onChangeListener)
-
- // unbind old blur listener
- // session.removeListener('blur', onBlurListener)
- acee.removeListener('blur', onBlurListener)
-
- // bind new blur listener
- onBlurListener = listenerFactory.onBlur(opts.onBlur)
- acee.on('blur', onBlurListener)
-
- setOptions(acee, session, opts)
- }
-
- scope.$watch(attrs.uiAce, updateOptions, /* deep watch */ true)
-
- // set the options here, even if we try to watch later, if this
- // line is missing things go wrong (and the tests will also fail)
- updateOptions(options)
-
- elm.on('$destroy', function () {
- acee.session.$stopWorker()
- acee.destroy()
- })
-
- scope.$watch(function () {
- return [elm[0].offsetWidth, elm[0].offsetHeight]
- }, function () {
- acee.resize()
- acee.renderer.updateFull()
- }, true)
-
- scope.Infinity = -1
-
- scope.focus = function () {
- acee.focus()
- }
-
- scope.addCommand = acee.commands.addCommand
-
- elm.on('click', function () {
- acee.focus()
- })
-
- scope.$on('insertRequested', function (e, req) {
- var cursor = acee.selection.getCursor()
- var str = ''
- if (cursor.column > 0) str += '\n\n'
-
- switch (req) {
- case 'h1':
- acee.insert(str + '# some heading\n\n')
- break
- case 'ul':
- acee.insert(str + '- item1\n- item2\n- item3')
- break
- case 'ol':
- acee.insert(str + '1. item1\n2. item2\n3. item3')
- break
- case 'a':
- acee.insert(str + '[example.com](http://example.com)')
- break
- case 'table':
- acee.insert(str +
- 'First Header | Second Header\n' +
- '------------- | -------------\n' +
- 'Content Cell | Content Cell\n' +
- 'Content Cell | Content Cell\n')
- }
-
- scope.$evalAsync(function () {
- ngModel.$setViewValue(session.getValue())
- })
- })
-
- scope.$on('insertSnippetRequested', function (e, snippet) {
- var cursor = acee.selection.getCursor()
- var str = ''
- if (cursor.column > 0) str += '\n\n'
-
- acee.insert(str + '```\n' + snippet.content + '\n```\n> [snippet#' + snippet.id + '](#/snippets/' + snippet.id + ')\n\n')
-
- scope.$evalAsync(function () {
- ngModel.$setViewValue(session.getValue())
- })
- })
-
- }
- }
- }])
diff --git a/src/browser/shared/services/Snippet.js b/src/browser/shared/services/Snippet.js
deleted file mode 100644
index 218473c2..00000000
--- a/src/browser/shared/services/Snippet.js
+++ /dev/null
@@ -1,52 +0,0 @@
-/* global angular */
-angular.module('codexen.shared')
- .factory('Snippet', function ($http, $auth, apiUrl) {
- var findByUser = function (user) {
- var url = apiUrl + 'snippets/search'
-
- return $http.get(url, {
- params: {
- user: user
- }
- })
- }
-
- var findMine = function (params) {
- var url = apiUrl + 'snippets/my'
-
- return $http.get(url, {params: params})
- }
-
- var create = function (params) {
- var url = apiUrl + 'snippets/create'
-
- return $http.post(url, params)
- }
-
- var show = function (id, params) {
- var url = apiUrl + 'snippets/id/' + id
-
- return $http.get(url, {params: params})
- }
-
- var update = function (id, params) {
- var url = apiUrl + 'snippets/id/' + id
-
- return $http.put(url, params)
- }
-
- var destroy = function (id) {
- var url = apiUrl + 'snippets/id/' + id
-
- return $http.delete(url)
- }
-
- return {
- findByUser: findByUser,
- findMine: findMine,
- create: create,
- show: show,
- delete: destroy,
- update: update
- }
- })
diff --git a/src/browser/shared/shared.js b/src/browser/shared/shared.js
deleted file mode 100644
index 5fa067c9..00000000
--- a/src/browser/shared/shared.js
+++ /dev/null
@@ -1,3 +0,0 @@
-angular.module('codexen.shared', [
- 'satellizer'
-])
diff --git a/src/browser/shared/styles/_index.styl b/src/browser/shared/styles/_index.styl
deleted file mode 100644
index 14aee701..00000000
--- a/src/browser/shared/styles/_index.styl
+++ /dev/null
@@ -1,24 +0,0 @@
-html
- overflow: hidden
- height: 100%
-
-body
- height: 100%
- overflow: auto
- font-family: "Lato", sans-serif
- color $textColor
- background-color: $appBackgroundColor
-
-label
- font-family: "Lato", sans-serif
- color $textColor
-
-h1, h2, h3, h4, h5
- color $textColorHighlight
- margin 0
-
-textarea
- resize: vertical
-
-hr
- border-color $baseBorderColor
diff --git a/src/browser/shared/styles/_shared.styl b/src/browser/shared/styles/_shared.styl
deleted file mode 100644
index ecac897d..00000000
--- a/src/browser/shared/styles/_shared.styl
+++ /dev/null
@@ -1,50 +0,0 @@
-.alert
- margin: 5px 0
-
-input.form-control, textarea.form-control, input.inline-form-control
- &::-webkit-input-placeholder
- color $textColor
- &:-moz-placeholder /* Firefox 18- */
- color $textColor
- &::-moz-placeholder /* Firefox 19+ */
- color $textColor
- &:-ms-input-placeholder
- color $textColor
-
-
-.inline-form-control
- @extend .form-control
- width: auto
- display: inline-block
-
-.btn.btn-default
- border-style solid
- border-width 1px
- btn-color($btn-default-color, $btn-default-bg, $btn-default-border)
-.btn.btn-primary
- btn-color($btn-primary-color, $btn-primary-bg, $btn-primary-border)
-.btn.btn-info
- btn-color($btn-info-color, $btn-info-bg, $btn-info-border)
-.btn.btn-success
- btn-color($btn-success-color, $btn-success-bg, $btn-success-border)
-.btn.btn-danger
- btn-color($btn-danger-color, $btn-danger-bg, $btn-danger-border)
-.btn.btn-warning
- btn-color($btn-warning-color, $btn-warning-bg, $btn-warning-border)
-
-textarea.form-control, .ace_editor
- border-radius $input-border-radius
-
-.ace_editor
- border solid 1px $input-border
- box-shadow inset 0 1px 1px rgba(0, 0, 0, .075)
- font-family: 'Lucida Grande'
-
-.ace_editor.ace_focus
- controlGlow()
-
-.modal-content
- background-color $bg
-
-.jumbotron
- padding 48px 10px
diff --git a/src/browser/shared/styles/_vars.styl b/src/browser/shared/styles/_vars.styl
deleted file mode 100644
index ce0e2591..00000000
--- a/src/browser/shared/styles/_vars.styl
+++ /dev/null
@@ -1,99 +0,0 @@
-// Basic Vars(MUST BE CAMELCASED ATOM VARS)
-$textColor= #99B2B8
-$textColorHighlight= #D5DFE2
-$textColorSelected = #FFFFFF
-
-$textColorInfo= #6494ED
-$textColorSuccess= #73C990
-$textColorWarning= #E2C08D
-$textColorError= #FF6347
-
-$backgroundColorHighlight= #003B4A
-$backgroundColorSelected= #004B5F
-$appBackgroundColor= #001F27
-
-$baseBackgroundColor= #002B36
-$baseBorderColor= #001A20
-
-$inputBackgroundColor= #00222B
-$inputBorderColor= #001A20
-
-$buttonBackgroundColor= #004355
-$buttonBackgroundColorHover= #004B5F
-$buttonBackgroundColorSelected= #52DCFF
-$buttonBorderColor= $baseBorderColor
-
-$block= #00222B
-
-//buttons
-$btnPrimary= #088CFF
-$btnInfo= #5BDEFF
-$btnSuccess= #22BD89
-$btnWarning= #CD8737
-$btnError= #DA2828
-
-
-// Bootstrap Overrides(MUST BE BUILT WITH BASIC VALUE ONLY)
-$brand-primary= $btnPrimary
-$brand-info= $btnInfo
-$brand-success= $btnSuccess
-$brand-warning= $btnWarning
-$brand-danger= $btnError
-
-$btn-default-bg= $buttonBackgroundColor
-$btn-default-color= $textColor
-$btn-default-border= $baseBorderColor
-
-$link-color= $textColorHighlight
-
-$nav-link-active-link-hover-bg= $backgroundColorHighlight
-$nav-pills-active-link-hover-color= $textColorHighlight
-$nav-link-hover-bg= $backgroundColorHighlight
-
-$input-bg= $backgroundColorHighlight
-$input-border= $baseBorderColor
-$input-border-focus= $buttonBackgroundColorSelected
-$input-color= $textColorSelected
-
-$dropdown-bg= $baseBackgroundColor
-$dropdown-border= $baseBorderColor
-$dropdown-link-color= $textColor
-$dropdown-link-hover-bg= $backgroundColorSelected
-$dropdown-link-hover-color= $textColorSelected
-
-$modal-content-bg= $baseBackgroundColor
-$modal-content-border-color= $modal-header-border-color= $modal-footer-border-color= $baseBorderColor
-
-$jumbotron-bg= $backgroundColorHighlight
-
-$alert-danger-bg= $textColorError
-$alert-danger-border= dark($alert-danger-bg) ? darken($alert-danger-bg, 5%) : lighten($alert-danger-bg, 5%)
-$alert-danger-text= $textColorSelected
-
-$alert-info-bg= $textColorInfo
-$alert-info-border= dark($alert-info-bg) ? darken($alert-info-bg, 5%) : lighten($alert-info-bg, 5%)
-$alert-info-text= $textColorSelected
-
-$alert-success-bg= $textColorSuccess
-$alert-success-border= dark($alert-success-bg) ? darken($alert-success-bg, 5%) : lighten($alert-success-bg, 5%)
-$alert-success-text= $textColorSelected
-
-$alert-warning-bg= $textColorWarning
-$alert-warning-border= dark($alert-warning-bg) ? darken($alert-warning-bg, 5%) : lighten($alert-warning-bg, 5%)
-$alert-warning-text= $textColorSelected
-
-$panel-bg= $baseBackgroundColor
-$panel-default-border= $baseBorderColor
-
-
-$nav-tabs-border-color= $baseBorderColor
-
-$nav-tabs-link-hover-border-color= $baseBorderColor
-$nav-tabs-active-link-hover-bg= transparent $backgroundColorSelected
-$nav-tabs-active-link-hover-color= $textColorSelected
-$nav-tabs-active-link-hover-border-color= $baseBorderColor
-
-$nav-tabs-justified-link-border-color= $baseBorderColor
-$nav-tabs-justified-active-link-border-color= $baseBorderColor
-
-$table-border-color= $baseBorderColor
diff --git a/src/browser/shared/styles/bootstrap.css b/src/browser/shared/styles/bootstrap.css
deleted file mode 100644
index e90d2ea8..00000000
--- a/src/browser/shared/styles/bootstrap.css
+++ /dev/null
@@ -1,5639 +0,0 @@
-.clearfix:before,
-.dl-horizontal dd:before,
-.container:before,
-.container-fluid:before,
-.row:before,
-.form-horizontal .form-group:before,
-.btn-toolbar:before,
-.btn-group-vertical > .btn-group:before,
-.nav:before,
-.navbar:before,
-.navbar-header:before,
-.navbar-collapse:before,
-.panel-body:before,
-.modal-footer:before,
-.clearfix:after,
-.dl-horizontal dd:after,
-.container:after,
-.container-fluid:after,
-.row:after,
-.form-horizontal .form-group:after,
-.btn-toolbar:after,
-.btn-group-vertical > .btn-group:after,
-.nav:after,
-.navbar:after,
-.navbar-header:after,
-.navbar-collapse:after,
-.panel-body:after,
-.modal-footer:after {
- content: " ";
- display: table;
-}
-.clearfix:after,
-.dl-horizontal dd:after,
-.container:after,
-.container-fluid:after,
-.row:after,
-.form-horizontal .form-group:after,
-.btn-toolbar:after,
-.btn-group-vertical > .btn-group:after,
-.nav:after,
-.navbar:after,
-.navbar-header:after,
-.navbar-collapse:after,
-.panel-body:after,
-.modal-footer:after {
- clear: both;
-}
-.center-block {
- display: block;
- margin-left: auto;
- margin-right: auto;
-}
-.pull-right {
- float: right !important;
-}
-.pull-left {
- float: left !important;
-}
-.hide {
- display: none !important;
-}
-.show {
- display: block !important;
-}
-.invisible {
- visibility: hidden;
-}
-.text-hide {
- font: 0/0 a;
- color: transparent;
- text-shadow: none;
- background-color: transparent;
- border: 0;
-}
-.hidden {
- display: none !important;
-}
-.affix {
- position: fixed;
-}
-@-ms-viewport {
- width: device-width;
-}
-.visible-xs,
-.visible-sm,
-.visible-md,
-.visible-lg {
- display: none !important;
-}
-.visible-xs-block,
-.visible-xs-inline,
-.visible-xs-inline-block,
-.visible-sm-block,
-.visible-sm-inline,
-.visible-sm-inline-block,
-.visible-md-block,
-.visible-md-inline,
-.visible-md-inline-block,
-.visible-lg-block,
-.visible-lg-inline,
-.visible-lg-inline-block {
- display: none !important;
-}
-@media (max-width: 767px) {
- .visible-xs {
- display: block !important;
- }
- table.visible-xs {
- display: table;
- }
- tr.visible-xs {
- display: table-row !important;
- }
- th.visible-xs,
- td.visible-xs {
- display: table-cell !important;
- }
-}
-@media (max-width: 767px) {
- .visible-xs-block {
- display: block !important;
- }
-}
-@media (max-width: 767px) {
- .visible-xs-inline {
- display: inline !important;
- }
-}
-@media (max-width: 767px) {
- .visible-xs-inline-block {
- display: inline-block !important;
- }
-}
-@media (min-width: 768px) and (max-width: 991px) {
- .visible-sm {
- display: block !important;
- }
- table.visible-sm {
- display: table;
- }
- tr.visible-sm {
- display: table-row !important;
- }
- th.visible-sm,
- td.visible-sm {
- display: table-cell !important;
- }
-}
-@media (min-width: 768px) and (max-width: 991px) {
- .visible-sm-block {
- display: block !important;
- }
-}
-@media (min-width: 768px) and (max-width: 991px) {
- .visible-sm-inline {
- display: inline !important;
- }
-}
-@media (min-width: 768px) and (max-width: 991px) {
- .visible-sm-inline-block {
- display: inline-block !important;
- }
-}
-@media (min-width: 992px) and (max-width: 1199px) {
- .visible-md {
- display: block !important;
- }
- table.visible-md {
- display: table;
- }
- tr.visible-md {
- display: table-row !important;
- }
- th.visible-md,
- td.visible-md {
- display: table-cell !important;
- }
-}
-@media (min-width: 992px) and (max-width: 1199px) {
- .visible-md-block {
- display: block !important;
- }
-}
-@media (min-width: 992px) and (max-width: 1199px) {
- .visible-md-inline {
- display: inline !important;
- }
-}
-@media (min-width: 992px) and (max-width: 1199px) {
- .visible-md-inline-block {
- display: inline-block !important;
- }
-}
-@media (min-width: 1200px) {
- .visible-lg {
- display: block !important;
- }
- table.visible-lg {
- display: table;
- }
- tr.visible-lg {
- display: table-row !important;
- }
- th.visible-lg,
- td.visible-lg {
- display: table-cell !important;
- }
-}
-@media (min-width: 1200px) {
- .visible-lg-block {
- display: block !important;
- }
-}
-@media (min-width: 1200px) {
- .visible-lg-inline {
- display: inline !important;
- }
-}
-@media (min-width: 1200px) {
- .visible-lg-inline-block {
- display: inline-block !important;
- }
-}
-@media (max-width: 767px) {
- .hidden-xs {
- display: none !important;
- }
-}
-@media (min-width: 768px) and (max-width: 991px) {
- .hidden-sm {
- display: none !important;
- }
-}
-@media (min-width: 992px) and (max-width: 1199px) {
- .hidden-md {
- display: none !important;
- }
-}
-@media (min-width: 1200px) {
- .hidden-lg {
- display: none !important;
- }
-}
-.visible-print {
- display: none !important;
-}
-@media print {
- .visible-print {
- display: block !important;
- }
- table.visible-print {
- display: table;
- }
- tr.visible-print {
- display: table-row !important;
- }
- th.visible-print,
- td.visible-print {
- display: table-cell !important;
- }
-}
-.visible-print-block {
- display: none !important;
-}
-@media print {
- .visible-print-block {
- display: block !important;
- }
-}
-.visible-print-inline {
- display: none !important;
-}
-@media print {
- .visible-print-inline {
- display: inline !important;
- }
-}
-.visible-print-inline-block {
- display: none !important;
-}
-@media print {
- .visible-print-inline-block {
- display: inline-block !important;
- }
-}
-@media print {
- .hidden-print {
- display: none !important;
- }
-}
-/*! normalize.css v3.0.2 | MIT License | git.io/normalize */
-html {
- font-family: sans-serif;
- -ms-text-size-adjust: 100%;
- -webkit-text-size-adjust: 100%;
-}
-body {
- margin: 0;
-}
-article,
-aside,
-details,
-figcaption,
-figure,
-footer,
-header,
-hgroup,
-main,
-menu,
-nav,
-section,
-summary {
- display: block;
-}
-audio,
-canvas,
-progress,
-video {
- display: inline-block;
- vertical-align: baseline;
-}
-audio:not([controls]) {
- display: none;
- height: 0;
-}
-[hidden],
-template {
- display: none;
-}
-a {
- background-color: transparent;
-}
-a:active,
-a:hover {
- outline: 0;
-}
-abbr[title] {
- border-bottom: 1px dotted;
-}
-b,
-strong {
- font-weight: bold;
-}
-dfn {
- font-style: italic;
-}
-h1 {
- font-size: 2em;
- margin: 0.67em 0;
-}
-mark {
- background: #ff0;
- color: #000;
-}
-small {
- font-size: 80%;
-}
-sub,
-sup {
- font-size: 75%;
- line-height: 0;
- position: relative;
- vertical-align: baseline;
-}
-sup {
- top: -0.5em;
-}
-sub {
- bottom: -0.25em;
-}
-img {
- border: 0;
-}
-svg:not(:root) {
- overflow: hidden;
-}
-figure {
- margin: 1em 40px;
-}
-hr {
- box-sizing: content-box;
- height: 0;
-}
-pre {
- overflow: auto;
-}
-code,
-kbd,
-pre,
-samp {
- font-family: monospace, monospace;
- font-size: 1em;
-}
-button,
-input,
-optgroup,
-select,
-textarea {
- color: inherit;
- font: inherit;
- margin: 0;
-}
-button {
- overflow: visible;
-}
-button,
-select {
- text-transform: none;
-}
-button,
-html input[type="button"],
-input[type="reset"],
-input[type="submit"] {
- -webkit-appearance: button;
- cursor: pointer;
-}
-button[disabled],
-html input[disabled] {
- cursor: default;
-}
-button::-moz-focus-inner,
-input::-moz-focus-inner {
- border: 0;
- padding: 0;
-}
-input {
- line-height: normal;
-}
-input[type="checkbox"],
-input[type="radio"] {
- box-sizing: border-box;
- padding: 0;
-}
-input[type="number"]::-webkit-inner-spin-button,
-input[type="number"]::-webkit-outer-spin-button {
- height: auto;
-}
-input[type="search"] {
- -webkit-appearance: textfield;
- box-sizing: content-box;
-}
-input[type="search"]::-webkit-search-cancel-button,
-input[type="search"]::-webkit-search-decoration {
- -webkit-appearance: none;
-}
-fieldset {
- border: 1px solid #c0c0c0;
- margin: 0 2px;
- padding: 0.35em 0.625em 0.75em;
-}
-legend {
- border: 0;
- padding: 0;
-}
-textarea {
- overflow: auto;
-}
-optgroup {
- font-weight: bold;
-}
-table {
- border-collapse: collapse;
- border-spacing: 0;
-}
-td,
-th {
- padding: 0;
-}
-/* Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */
-@media print {
- *,
- *:before,
- *:after {
- background: transparent !important;
- color: #000 !important;
- box-shadow: none !important;
- text-shadow: none !important;
- }
- a,
- a:visited {
- text-decoration: underline;
- }
- a[href]:after {
- content: " (" attr(href) ")";
- }
- abbr[title]:after {
- content: " (" attr(title) ")";
- }
- a[href^="#"]:after,
- a[href^="javascript:"]:after {
- content: "";
- }
- pre,
- blockquote {
- border: 1px solid #999;
- page-break-inside: avoid;
- }
- thead {
- display: table-header-group;
- }
- tr,
- img {
- page-break-inside: avoid;
- }
- img {
- max-width: 100% !important;
- }
- p,
- h2,
- h3 {
- orphans: 3;
- widows: 3;
- }
- h2,
- h3 {
- page-break-after: avoid;
- }
- select {
- background: #fff !important;
- }
- .navbar {
- display: none;
- }
- .btn > .caret,
- .dropup > .btn > .caret {
- border-top-color: #000 !important;
- }
- .label {
- border: 1px solid #000;
- }
- .table {
- border-collapse: collapse !important;
- }
- .table td,
- .table th {
- background-color: #fff !important;
- }
- .table-bordered th,
- .table-bordered td {
- border: 1px solid #ddd !important;
- }
-}
-* {
- box-sizing: border-box;
-}
-*:before,
-*:after {
- box-sizing: border-box;
-}
-html {
- font-size: 10px;
- -webkit-tap-highlight-color: rgba(0,0,0,0);
-}
-body {
- font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
- font-size: 14px;
- line-height: 1.428571429;
- color: #333;
- background-color: #fff;
-}
-input,
-button,
-select,
-textarea {
- font-family: inherit;
- font-size: inherit;
- line-height: inherit;
-}
-a {
- color: #d5dfe2;
- text-decoration: none;
-}
-a:hover,
-a:focus {
- color: #aec1c7;
- text-decoration: underline;
-}
-a:focus {
- outline: thin dotted;
- outline: 5px auto -webkit-focus-ring-color;
- outline-offset: -2px;
-}
-figure {
- margin: 0;
-}
-img {
- vertical-align: middle;
-}
-.img-responsive,
-.thumbnail > img,
-.thumbnail a > img {
- display: block;
- max-width: 100%;
- height: auto;
-}
-.img-rounded {
- border-radius: 6px;
-}
-.img-thumbnail {
- padding: 4px;
- line-height: 1.428571429;
- background-color: #fff;
- border: 1px solid #ddd;
- border-radius: 4px;
- -webkit-transition: all 0.2s ease-in-out;
- transition: all 0.2s ease-in-out;
- display: inline-block;
- max-width: 100%;
- height: auto;
-}
-.img-circle {
- border-radius: 50%;
-}
-hr {
- margin-top: 20px;
- margin-bottom: 20px;
- border: 0;
- border-top: 1px solid #eee;
-}
-.sr-only {
- position: absolute;
- width: 1px;
- height: 1px;
- margin: -1px;
- padding: 0;
- overflow: hidden;
- clip: rect(0, 0, 0, 0);
- border: 0;
-}
-.sr-only-focusable:active,
-.sr-only-focusable:focus {
- position: static;
- width: auto;
- height: auto;
- margin: 0;
- overflow: visible;
- clip: auto;
-}
-[role="button"] {
- cursor: pointer;
-}
-h1,
-h2,
-h3,
-h4,
-h5,
-h6,
-.h1,
-.h2,
-.h3,
-.h4,
-.h5,
-.h6 {
- font-family: inherit;
- font-weight: 500;
- line-height: 1.1;
- color: inherit;
-}
-h1 small,
-h2 small,
-h3 small,
-h4 small,
-h5 small,
-h6 small,
-.h1 small,
-.h2 small,
-.h3 small,
-.h4 small,
-.h5 small,
-.h6 small,
-h1 .small,
-h2 .small,
-h3 .small,
-h4 .small,
-h5 .small,
-h6 .small,
-.h1 .small,
-.h2 .small,
-.h3 .small,
-.h4 .small,
-.h5 .small,
-.h6 .small {
- font-weight: normal;
- line-height: 1;
- color: #777;
-}
-h1,
-.h1,
-h2,
-.h2,
-h3,
-.h3 {
- margin-top: 20px;
- margin-bottom: 10px;
-}
-h1 small,
-.h1 small,
-h2 small,
-.h2 small,
-h3 small,
-.h3 small,
-h1 .small,
-.h1 .small,
-h2 .small,
-.h2 .small,
-h3 .small,
-.h3 .small {
- font-size: 65%;
-}
-h4,
-.h4,
-h5,
-.h5,
-h6,
-.h6 {
- margin-top: 10px;
- margin-bottom: 10px;
-}
-h4 small,
-.h4 small,
-h5 small,
-.h5 small,
-h6 small,
-.h6 small,
-h4 .small,
-.h4 .small,
-h5 .small,
-.h5 .small,
-h6 .small,
-.h6 .small {
- font-size: 75%;
-}
-h1,
-.h1 {
- font-size: 36px;
-}
-h2,
-.h2 {
- font-size: 30px;
-}
-h3,
-.h3 {
- font-size: 24px;
-}
-h4,
-.h4 {
- font-size: 18px;
-}
-h5,
-.h5 {
- font-size: 14px;
-}
-h6,
-.h6 {
- font-size: 12px;
-}
-p {
- margin: 0 0 10px;
-}
-.lead {
- margin-bottom: 20px;
- font-size: 16px;
- font-weight: 300;
- line-height: 1.4;
-}
-@media (min-width: 768px) {
- .lead {
- font-size: 21px;
- }
-}
-small,
-.small {
- font-size: 85%;
-}
-mark,
-.mark {
- background-color: #fcf8e3;
- padding: 0.2em;
-}
-.text-left {
- text-align: left;
-}
-.text-right {
- text-align: right;
-}
-.text-center {
- text-align: center;
-}
-.text-justify {
- text-align: justify;
-}
-.text-nowrap {
- white-space: nowrap;
-}
-.text-lowercase {
- text-transform: lowercase;
-}
-.text-uppercase {
- text-transform: uppercase;
-}
-.text-capitalize {
- text-transform: capitalize;
-}
-.text-muted {
- color: #777;
-}
-.text-primary {
- color: #088cff;
-}
-a.text-primary:hover {
- color: #007eed;
-}
-.text-success {
- color: #3c763d;
-}
-a.text-success:hover {
- color: #366a37;
-}
-.text-info {
- color: #31708f;
-}
-a.text-info:hover {
- color: #2c6581;
-}
-.text-warning {
- color: #8a6d3b;
-}
-a.text-warning:hover {
- color: #7c6235;
-}
-.text-danger {
- color: #a94442;
-}
-a.text-danger:hover {
- color: #983d3b;
-}
-.bg-primary {
- color: #fff;
- background-color: #088cff;
-}
-a.bg-primary:hover {
- background-color: #007eed;
-}
-.bg-success {
- background-color: #dff0d8;
-}
-a.bg-success:hover {
- background-color: #c4e3b7;
-}
-.bg-info {
- background-color: #d9edf7;
-}
-a.bg-info:hover {
- background-color: #b3dbef;
-}
-.bg-warning {
- background-color: #fcf8e3;
-}
-a.bg-warning:hover {
- background-color: #f7edb8;
-}
-.bg-danger {
- background-color: #f2dede;
-}
-a.bg-danger:hover {
- background-color: #e5bdbd;
-}
-.page-header {
- padding-bottom: 9px;
- margin: 40px 0 20px;
- border-bottom: 1px solid #eee;
-}
-ul,
-ol {
- margin-top: 0;
- margin-bottom: 10px;
-}
-ul ul,
-ol ul,
-ul ol,
-ol ol {
- margin-bottom: 0;
-}
-.list-inline,
-.list-unstyled {
- padding-left: 0;
- list-style: none;
-}
-.list-inline {
- margin-left: -5px;
-}
-.list-inline > li {
- display: inline-block;
- padding-left: 5px;
- padding-right: 5px;
-}
-dl {
- margin-top: 0;
- margin-bottom: 20px;
-}
-dt,
-dd {
- line-height: 1.428571429;
-}
-dt {
- font-weight: bold;
-}
-dd {
- margin-left: 0;
-}
-@media (min-width: 768px) {
- .dl-horizontal dt {
- float: left;
- width: 160px;
- clear: left;
- text-align: right;
- text-overflow: ellipsis;
- overflow: hidden;
- white-space: nowrap;
- }
- .dl-horizontal dd {
- margin-left: 180px;
- }
-}
-abbr[title],
-abbr[data-original-title] {
- cursor: help;
- border-bottom: 1px dotted #777;
-}
-.initialism {
- font-size: 90%;
- text-transform: uppercase;
-}
-blockquote {
- padding: 10px 20px;
- margin: 0 0 20px;
- font-size: 17.5px;
- border-left: 5px solid #eee;
-}
-blockquote p:last-child,
-blockquote ul:last-child,
-blockquote ol:last-child {
- margin-bottom: 0;
-}
-blockquote footer,
-blockquote small,
-blockquote .small {
- display: block;
- font-size: 80%;
- line-height: 1.428571429;
- color: #777;
-}
-blockquote footer:before,
-blockquote small:before,
-blockquote .small:before {
- content: '\2014 \00A0';
-}
-.blockquote-reverse,
-blockquote.pull-right {
- padding-right: 15px;
- padding-left: 0;
- border-right: 5px solid #eee;
- border-left: 0;
- text-align: right;
-}
-.blockquote-reverse footer:before,
-blockquote.pull-right footer:before,
-.blockquote-reverse small:before,
-blockquote.pull-right small:before,
-.blockquote-reverse .small:before,
-blockquote.pull-right .small:before {
- content: '';
-}
-.blockquote-reverse footer:after,
-blockquote.pull-right footer:after,
-.blockquote-reverse small:after,
-blockquote.pull-right small:after,
-.blockquote-reverse .small:after,
-blockquote.pull-right .small:after {
- content: '\00A0 \2014';
-}
-address {
- margin-bottom: 20px;
- font-style: normal;
- line-height: 1.428571429;
-}
-.container {
- margin-right: auto;
- margin-left: auto;
- padding-left: 15px;
- padding-right: 15px;
-}
-@media (min-width: 768px) {
- .container {
- width: 750px;
- }
-}
-@media (min-width: 992px) {
- .container {
- width: 970px;
- }
-}
-@media (min-width: 1200px) {
- .container {
- width: 1170px;
- }
-}
-.container-fluid {
- margin-right: auto;
- margin-left: auto;
- padding-left: 15px;
- padding-right: 15px;
-}
-.row {
- margin-left: -15px;
- margin-right: -15px;
-}
-.col-xs-1,
-.col-sm-1,
-.col-md-1,
-.col-lg-1,
-.col-xs-2,
-.col-sm-2,
-.col-md-2,
-.col-lg-2,
-.col-xs-3,
-.col-sm-3,
-.col-md-3,
-.col-lg-3,
-.col-xs-4,
-.col-sm-4,
-.col-md-4,
-.col-lg-4,
-.col-xs-5,
-.col-sm-5,
-.col-md-5,
-.col-lg-5,
-.col-xs-6,
-.col-sm-6,
-.col-md-6,
-.col-lg-6,
-.col-xs-7,
-.col-sm-7,
-.col-md-7,
-.col-lg-7,
-.col-xs-8,
-.col-sm-8,
-.col-md-8,
-.col-lg-8,
-.col-xs-9,
-.col-sm-9,
-.col-md-9,
-.col-lg-9,
-.col-xs-10,
-.col-sm-10,
-.col-md-10,
-.col-lg-10,
-.col-xs-11,
-.col-sm-11,
-.col-md-11,
-.col-lg-11,
-.col-xs-12,
-.col-sm-12,
-.col-md-12,
-.col-lg-12 {
- position: relative;
- min-height: 1px;
- padding-left: 15px;
- padding-right: 15px;
-}
-.col-xs-1,
-.col-xs-2,
-.col-xs-3,
-.col-xs-4,
-.col-xs-5,
-.col-xs-6,
-.col-xs-7,
-.col-xs-8,
-.col-xs-9,
-.col-xs-10,
-.col-xs-11,
-.col-xs-12 {
- float: left;
-}
-.col-xs-12 {
- width: 100%;
-}
-.col-xs-11 {
- width: 91.66666666666666%;
-}
-.col-xs-10 {
- width: 83.33333333333334%;
-}
-.col-xs-9 {
- width: 75%;
-}
-.col-xs-8 {
- width: 66.66666666666666%;
-}
-.col-xs-7 {
- width: 58.333333333333336%;
-}
-.col-xs-6 {
- width: 50%;
-}
-.col-xs-5 {
- width: 41.66666666666667%;
-}
-.col-xs-4 {
- width: 33.33333333333333%;
-}
-.col-xs-3 {
- width: 25%;
-}
-.col-xs-2 {
- width: 16.666666666666664%;
-}
-.col-xs-1 {
- width: 8.333333333333332%;
-}
-.col-xs-pull-12 {
- right: 100%;
-}
-.col-xs-pull-11 {
- right: 91.66666666666666%;
-}
-.col-xs-pull-10 {
- right: 83.33333333333334%;
-}
-.col-xs-pull-9 {
- right: 75%;
-}
-.col-xs-pull-8 {
- right: 66.66666666666666%;
-}
-.col-xs-pull-7 {
- right: 58.333333333333336%;
-}
-.col-xs-pull-6 {
- right: 50%;
-}
-.col-xs-pull-5 {
- right: 41.66666666666667%;
-}
-.col-xs-pull-4 {
- right: 33.33333333333333%;
-}
-.col-xs-pull-3 {
- right: 25%;
-}
-.col-xs-pull-2 {
- right: 16.666666666666664%;
-}
-.col-xs-pull-1 {
- right: 8.333333333333332%;
-}
-.col-xs-pull-0 {
- right: auto;
-}
-.col-xs-push-12 {
- left: 100%;
-}
-.col-xs-push-11 {
- left: 91.66666666666666%;
-}
-.col-xs-push-10 {
- left: 83.33333333333334%;
-}
-.col-xs-push-9 {
- left: 75%;
-}
-.col-xs-push-8 {
- left: 66.66666666666666%;
-}
-.col-xs-push-7 {
- left: 58.333333333333336%;
-}
-.col-xs-push-6 {
- left: 50%;
-}
-.col-xs-push-5 {
- left: 41.66666666666667%;
-}
-.col-xs-push-4 {
- left: 33.33333333333333%;
-}
-.col-xs-push-3 {
- left: 25%;
-}
-.col-xs-push-2 {
- left: 16.666666666666664%;
-}
-.col-xs-push-1 {
- left: 8.333333333333332%;
-}
-.col-xs-push-0 {
- left: auto;
-}
-.col-xs-offset-12 {
- margin-left: 100%;
-}
-.col-xs-offset-11 {
- margin-left: 91.66666666666666%;
-}
-.col-xs-offset-10 {
- margin-left: 83.33333333333334%;
-}
-.col-xs-offset-9 {
- margin-left: 75%;
-}
-.col-xs-offset-8 {
- margin-left: 66.66666666666666%;
-}
-.col-xs-offset-7 {
- margin-left: 58.333333333333336%;
-}
-.col-xs-offset-6 {
- margin-left: 50%;
-}
-.col-xs-offset-5 {
- margin-left: 41.66666666666667%;
-}
-.col-xs-offset-4 {
- margin-left: 33.33333333333333%;
-}
-.col-xs-offset-3 {
- margin-left: 25%;
-}
-.col-xs-offset-2 {
- margin-left: 16.666666666666664%;
-}
-.col-xs-offset-1 {
- margin-left: 8.333333333333332%;
-}
-.col-xs-offset-0 {
- margin-left: 0;
-}
-@media (min-width: 768px) {
- .col-sm-1,
- .col-sm-2,
- .col-sm-3,
- .col-sm-4,
- .col-sm-5,
- .col-sm-6,
- .col-sm-7,
- .col-sm-8,
- .col-sm-9,
- .col-sm-10,
- .col-sm-11,
- .col-sm-12 {
- float: left;
- }
- .col-sm-12 {
- width: 100%;
- }
- .col-sm-11 {
- width: 91.66666666666666%;
- }
- .col-sm-10 {
- width: 83.33333333333334%;
- }
- .col-sm-9 {
- width: 75%;
- }
- .col-sm-8 {
- width: 66.66666666666666%;
- }
- .col-sm-7 {
- width: 58.333333333333336%;
- }
- .col-sm-6 {
- width: 50%;
- }
- .col-sm-5 {
- width: 41.66666666666667%;
- }
- .col-sm-4 {
- width: 33.33333333333333%;
- }
- .col-sm-3 {
- width: 25%;
- }
- .col-sm-2 {
- width: 16.666666666666664%;
- }
- .col-sm-1 {
- width: 8.333333333333332%;
- }
- .col-sm-pull-12 {
- right: 100%;
- }
- .col-sm-pull-11 {
- right: 91.66666666666666%;
- }
- .col-sm-pull-10 {
- right: 83.33333333333334%;
- }
- .col-sm-pull-9 {
- right: 75%;
- }
- .col-sm-pull-8 {
- right: 66.66666666666666%;
- }
- .col-sm-pull-7 {
- right: 58.333333333333336%;
- }
- .col-sm-pull-6 {
- right: 50%;
- }
- .col-sm-pull-5 {
- right: 41.66666666666667%;
- }
- .col-sm-pull-4 {
- right: 33.33333333333333%;
- }
- .col-sm-pull-3 {
- right: 25%;
- }
- .col-sm-pull-2 {
- right: 16.666666666666664%;
- }
- .col-sm-pull-1 {
- right: 8.333333333333332%;
- }
- .col-sm-pull-0 {
- right: auto;
- }
- .col-sm-push-12 {
- left: 100%;
- }
- .col-sm-push-11 {
- left: 91.66666666666666%;
- }
- .col-sm-push-10 {
- left: 83.33333333333334%;
- }
- .col-sm-push-9 {
- left: 75%;
- }
- .col-sm-push-8 {
- left: 66.66666666666666%;
- }
- .col-sm-push-7 {
- left: 58.333333333333336%;
- }
- .col-sm-push-6 {
- left: 50%;
- }
- .col-sm-push-5 {
- left: 41.66666666666667%;
- }
- .col-sm-push-4 {
- left: 33.33333333333333%;
- }
- .col-sm-push-3 {
- left: 25%;
- }
- .col-sm-push-2 {
- left: 16.666666666666664%;
- }
- .col-sm-push-1 {
- left: 8.333333333333332%;
- }
- .col-sm-push-0 {
- left: auto;
- }
- .col-sm-offset-12 {
- margin-left: 100%;
- }
- .col-sm-offset-11 {
- margin-left: 91.66666666666666%;
- }
- .col-sm-offset-10 {
- margin-left: 83.33333333333334%;
- }
- .col-sm-offset-9 {
- margin-left: 75%;
- }
- .col-sm-offset-8 {
- margin-left: 66.66666666666666%;
- }
- .col-sm-offset-7 {
- margin-left: 58.333333333333336%;
- }
- .col-sm-offset-6 {
- margin-left: 50%;
- }
- .col-sm-offset-5 {
- margin-left: 41.66666666666667%;
- }
- .col-sm-offset-4 {
- margin-left: 33.33333333333333%;
- }
- .col-sm-offset-3 {
- margin-left: 25%;
- }
- .col-sm-offset-2 {
- margin-left: 16.666666666666664%;
- }
- .col-sm-offset-1 {
- margin-left: 8.333333333333332%;
- }
- .col-sm-offset-0 {
- margin-left: 0;
- }
-}
-@media (min-width: 992px) {
- .col-md-1,
- .col-md-2,
- .col-md-3,
- .col-md-4,
- .col-md-5,
- .col-md-6,
- .col-md-7,
- .col-md-8,
- .col-md-9,
- .col-md-10,
- .col-md-11,
- .col-md-12 {
- float: left;
- }
- .col-md-12 {
- width: 100%;
- }
- .col-md-11 {
- width: 91.66666666666666%;
- }
- .col-md-10 {
- width: 83.33333333333334%;
- }
- .col-md-9 {
- width: 75%;
- }
- .col-md-8 {
- width: 66.66666666666666%;
- }
- .col-md-7 {
- width: 58.333333333333336%;
- }
- .col-md-6 {
- width: 50%;
- }
- .col-md-5 {
- width: 41.66666666666667%;
- }
- .col-md-4 {
- width: 33.33333333333333%;
- }
- .col-md-3 {
- width: 25%;
- }
- .col-md-2 {
- width: 16.666666666666664%;
- }
- .col-md-1 {
- width: 8.333333333333332%;
- }
- .col-md-pull-12 {
- right: 100%;
- }
- .col-md-pull-11 {
- right: 91.66666666666666%;
- }
- .col-md-pull-10 {
- right: 83.33333333333334%;
- }
- .col-md-pull-9 {
- right: 75%;
- }
- .col-md-pull-8 {
- right: 66.66666666666666%;
- }
- .col-md-pull-7 {
- right: 58.333333333333336%;
- }
- .col-md-pull-6 {
- right: 50%;
- }
- .col-md-pull-5 {
- right: 41.66666666666667%;
- }
- .col-md-pull-4 {
- right: 33.33333333333333%;
- }
- .col-md-pull-3 {
- right: 25%;
- }
- .col-md-pull-2 {
- right: 16.666666666666664%;
- }
- .col-md-pull-1 {
- right: 8.333333333333332%;
- }
- .col-md-pull-0 {
- right: auto;
- }
- .col-md-push-12 {
- left: 100%;
- }
- .col-md-push-11 {
- left: 91.66666666666666%;
- }
- .col-md-push-10 {
- left: 83.33333333333334%;
- }
- .col-md-push-9 {
- left: 75%;
- }
- .col-md-push-8 {
- left: 66.66666666666666%;
- }
- .col-md-push-7 {
- left: 58.333333333333336%;
- }
- .col-md-push-6 {
- left: 50%;
- }
- .col-md-push-5 {
- left: 41.66666666666667%;
- }
- .col-md-push-4 {
- left: 33.33333333333333%;
- }
- .col-md-push-3 {
- left: 25%;
- }
- .col-md-push-2 {
- left: 16.666666666666664%;
- }
- .col-md-push-1 {
- left: 8.333333333333332%;
- }
- .col-md-push-0 {
- left: auto;
- }
- .col-md-offset-12 {
- margin-left: 100%;
- }
- .col-md-offset-11 {
- margin-left: 91.66666666666666%;
- }
- .col-md-offset-10 {
- margin-left: 83.33333333333334%;
- }
- .col-md-offset-9 {
- margin-left: 75%;
- }
- .col-md-offset-8 {
- margin-left: 66.66666666666666%;
- }
- .col-md-offset-7 {
- margin-left: 58.333333333333336%;
- }
- .col-md-offset-6 {
- margin-left: 50%;
- }
- .col-md-offset-5 {
- margin-left: 41.66666666666667%;
- }
- .col-md-offset-4 {
- margin-left: 33.33333333333333%;
- }
- .col-md-offset-3 {
- margin-left: 25%;
- }
- .col-md-offset-2 {
- margin-left: 16.666666666666664%;
- }
- .col-md-offset-1 {
- margin-left: 8.333333333333332%;
- }
- .col-md-offset-0 {
- margin-left: 0;
- }
-}
-@media (min-width: 1200px) {
- .col-lg-1,
- .col-lg-2,
- .col-lg-3,
- .col-lg-4,
- .col-lg-5,
- .col-lg-6,
- .col-lg-7,
- .col-lg-8,
- .col-lg-9,
- .col-lg-10,
- .col-lg-11,
- .col-lg-12 {
- float: left;
- }
- .col-lg-12 {
- width: 100%;
- }
- .col-lg-11 {
- width: 91.66666666666666%;
- }
- .col-lg-10 {
- width: 83.33333333333334%;
- }
- .col-lg-9 {
- width: 75%;
- }
- .col-lg-8 {
- width: 66.66666666666666%;
- }
- .col-lg-7 {
- width: 58.333333333333336%;
- }
- .col-lg-6 {
- width: 50%;
- }
- .col-lg-5 {
- width: 41.66666666666667%;
- }
- .col-lg-4 {
- width: 33.33333333333333%;
- }
- .col-lg-3 {
- width: 25%;
- }
- .col-lg-2 {
- width: 16.666666666666664%;
- }
- .col-lg-1 {
- width: 8.333333333333332%;
- }
- .col-lg-pull-12 {
- right: 100%;
- }
- .col-lg-pull-11 {
- right: 91.66666666666666%;
- }
- .col-lg-pull-10 {
- right: 83.33333333333334%;
- }
- .col-lg-pull-9 {
- right: 75%;
- }
- .col-lg-pull-8 {
- right: 66.66666666666666%;
- }
- .col-lg-pull-7 {
- right: 58.333333333333336%;
- }
- .col-lg-pull-6 {
- right: 50%;
- }
- .col-lg-pull-5 {
- right: 41.66666666666667%;
- }
- .col-lg-pull-4 {
- right: 33.33333333333333%;
- }
- .col-lg-pull-3 {
- right: 25%;
- }
- .col-lg-pull-2 {
- right: 16.666666666666664%;
- }
- .col-lg-pull-1 {
- right: 8.333333333333332%;
- }
- .col-lg-pull-0 {
- right: auto;
- }
- .col-lg-push-12 {
- left: 100%;
- }
- .col-lg-push-11 {
- left: 91.66666666666666%;
- }
- .col-lg-push-10 {
- left: 83.33333333333334%;
- }
- .col-lg-push-9 {
- left: 75%;
- }
- .col-lg-push-8 {
- left: 66.66666666666666%;
- }
- .col-lg-push-7 {
- left: 58.333333333333336%;
- }
- .col-lg-push-6 {
- left: 50%;
- }
- .col-lg-push-5 {
- left: 41.66666666666667%;
- }
- .col-lg-push-4 {
- left: 33.33333333333333%;
- }
- .col-lg-push-3 {
- left: 25%;
- }
- .col-lg-push-2 {
- left: 16.666666666666664%;
- }
- .col-lg-push-1 {
- left: 8.333333333333332%;
- }
- .col-lg-push-0 {
- left: auto;
- }
- .col-lg-offset-12 {
- margin-left: 100%;
- }
- .col-lg-offset-11 {
- margin-left: 91.66666666666666%;
- }
- .col-lg-offset-10 {
- margin-left: 83.33333333333334%;
- }
- .col-lg-offset-9 {
- margin-left: 75%;
- }
- .col-lg-offset-8 {
- margin-left: 66.66666666666666%;
- }
- .col-lg-offset-7 {
- margin-left: 58.333333333333336%;
- }
- .col-lg-offset-6 {
- margin-left: 50%;
- }
- .col-lg-offset-5 {
- margin-left: 41.66666666666667%;
- }
- .col-lg-offset-4 {
- margin-left: 33.33333333333333%;
- }
- .col-lg-offset-3 {
- margin-left: 25%;
- }
- .col-lg-offset-2 {
- margin-left: 16.666666666666664%;
- }
- .col-lg-offset-1 {
- margin-left: 8.333333333333332%;
- }
- .col-lg-offset-0 {
- margin-left: 0;
- }
-}
-table {
- background-color: transparent;
-}
-caption {
- padding-top: 8px;
- padding-bottom: 8px;
- color: #777;
- text-align: left;
-}
-th {
- text-align: left;
-}
-.table {
- width: 100%;
- max-width: 100%;
- margin-bottom: 20px;
-}
-.table > thead > tr > th,
-.table > tbody > tr > th,
-.table > tfoot > tr > th,
-.table > thead > tr > td,
-.table > tbody > tr > td,
-.table > tfoot > tr > td {
- padding: 8px;
- line-height: 1.428571429;
- vertical-align: top;
- border-top: 1px solid #001a20;
-}
-.table > thead > tr > th {
- vertical-align: bottom;
- border-bottom: 2px solid #001a20;
-}
-.table > caption + thead > tr:first-child > th,
-.table > colgroup + thead > tr:first-child > th,
-.table > thead:first-child > tr:first-child > th,
-.table > caption + thead > tr:first-child > td,
-.table > colgroup + thead > tr:first-child > td,
-.table > thead:first-child > tr:first-child > td {
- border-top: 0;
-}
-.table > tbody + tbody {
- border-top: 2px solid #001a20;
-}
-.table .table {
- background-color: #fff;
-}
-.table-condensed > thead > tr > th,
-.table-condensed > tbody > tr > th,
-.table-condensed > tfoot > tr > th,
-.table-condensed > thead > tr > td,
-.table-condensed > tbody > tr > td,
-.table-condensed > tfoot > tr > td {
- padding: 5px;
-}
-.table-bordered {
- border: 1px solid #001a20;
-}
-.table-bordered > thead > tr > th,
-.table-bordered > tbody > tr > th,
-.table-bordered > tfoot > tr > th,
-.table-bordered > thead > tr > td,
-.table-bordered > tbody > tr > td,
-.table-bordered > tfoot > tr > td {
- border: 1px solid #001a20;
-}
-.table-bordered > thead > tr > th,
-.table-bordered > thead > tr > td {
- border-bottom-width: 2px;
-}
-.table-striped > tbody > tr:nth-of-type(odd) {
- background-color: #f9f9f9;
-}
-.table-hover > tbody > tr:hover {
- background-color: #f5f5f5;
-}
-table col[class*="col-"] {
- position: static;
- float: none;
- display: table-column;
-}
-table td[class*="col-"],
-table th[class*="col-"] {
- position: static;
- float: none;
- display: table-cell;
-}
-.table > thead > tr > td.active,
-.table > tbody > tr > td.active,
-.table > tfoot > tr > td.active,
-.table > thead > tr > th.active,
-.table > tbody > tr > th.active,
-.table > tfoot > tr > th.active,
-.table > thead > tr.active > td,
-.table > tbody > tr.active > td,
-.table > tfoot > tr.active > td,
-.table > thead > tr.active > th,
-.table > tbody > tr.active > th,
-.table > tfoot > tr.active > th {
- background-color: #f5f5f5;
-}
-.table-hover > tbody > tr > td.active:hover,
-.table-hover > tbody > tr > th.active:hover,
-.table-hover > tbody > tr.active:hover > td,
-.table-hover > tbody > tr:hover > .active,
-.table-hover > tbody > tr.active:hover > th {
- background-color: #e9e9e9;
-}
-.table > thead > tr > td.success,
-.table > tbody > tr > td.success,
-.table > tfoot > tr > td.success,
-.table > thead > tr > th.success,
-.table > tbody > tr > th.success,
-.table > tfoot > tr > th.success,
-.table > thead > tr.success > td,
-.table > tbody > tr.success > td,
-.table > tfoot > tr.success > td,
-.table > thead > tr.success > th,
-.table > tbody > tr.success > th,
-.table > tfoot > tr.success > th {
- background-color: #dff0d8;
-}
-.table-hover > tbody > tr > td.success:hover,
-.table-hover > tbody > tr > th.success:hover,
-.table-hover > tbody > tr.success:hover > td,
-.table-hover > tbody > tr:hover > .success,
-.table-hover > tbody > tr.success:hover > th {
- background-color: #d1eac8;
-}
-.table > thead > tr > td.info,
-.table > tbody > tr > td.info,
-.table > tfoot > tr > td.info,
-.table > thead > tr > th.info,
-.table > tbody > tr > th.info,
-.table > tfoot > tr > th.info,
-.table > thead > tr.info > td,
-.table > tbody > tr.info > td,
-.table > tfoot > tr.info > td,
-.table > thead > tr.info > th,
-.table > tbody > tr.info > th,
-.table > tfoot > tr.info > th {
- background-color: #d9edf7;
-}
-.table-hover > tbody > tr > td.info:hover,
-.table-hover > tbody > tr > th.info:hover,
-.table-hover > tbody > tr.info:hover > td,
-.table-hover > tbody > tr:hover > .info,
-.table-hover > tbody > tr.info:hover > th {
- background-color: #c6e4f3;
-}
-.table > thead > tr > td.warning,
-.table > tbody > tr > td.warning,
-.table > tfoot > tr > td.warning,
-.table > thead > tr > th.warning,
-.table > tbody > tr > th.warning,
-.table > tfoot > tr > th.warning,
-.table > thead > tr.warning > td,
-.table > tbody > tr.warning > td,
-.table > tfoot > tr.warning > td,
-.table > thead > tr.warning > th,
-.table > tbody > tr.warning > th,
-.table > tfoot > tr.warning > th {
- background-color: #fcf8e3;
-}
-.table-hover > tbody > tr > td.warning:hover,
-.table-hover > tbody > tr > th.warning:hover,
-.table-hover > tbody > tr.warning:hover > td,
-.table-hover > tbody > tr:hover > .warning,
-.table-hover > tbody > tr.warning:hover > th {
- background-color: #faf3cd;
-}
-.table > thead > tr > td.danger,
-.table > tbody > tr > td.danger,
-.table > tfoot > tr > td.danger,
-.table > thead > tr > th.danger,
-.table > tbody > tr > th.danger,
-.table > tfoot > tr > th.danger,
-.table > thead > tr.danger > td,
-.table > tbody > tr.danger > td,
-.table > tfoot > tr.danger > td,
-.table > thead > tr.danger > th,
-.table > tbody > tr.danger > th,
-.table > tfoot > tr.danger > th {
- background-color: #f2dede;
-}
-.table-hover > tbody > tr > td.danger:hover,
-.table-hover > tbody > tr > th.danger:hover,
-.table-hover > tbody > tr.danger:hover > td,
-.table-hover > tbody > tr:hover > .danger,
-.table-hover > tbody > tr.danger:hover > th {
- background-color: #ebcdcd;
-}
-.table-responsive {
- overflow-x: auto;
- min-height: 0.01%;
-}
-@media screen and (max-width: 767px) {
- .table-responsive {
- width: 100%;
- margin-bottom: 15px;
- overflow-y: hidden;
- -ms-overflow-style: -ms-autohiding-scrollbar;
- border: 1px solid #001a20;
- }
- .table-responsive > .table {
- margin-bottom: 0;
- }
- .table-responsive > .table > thead > tr > th,
- .table-responsive > .table > tbody > tr > th,
- .table-responsive > .table > tfoot > tr > th,
- .table-responsive > .table > thead > tr > td,
- .table-responsive > .table > tbody > tr > td,
- .table-responsive > .table > tfoot > tr > td {
- white-space: nowrap;
- }
- .table-responsive > .table-bordered {
- border: 0;
- }
- .table-responsive > .table-bordered > thead > tr > th:first-child,
- .table-responsive > .table-bordered > tbody > tr > th:first-child,
- .table-responsive > .table-bordered > tfoot > tr > th:first-child,
- .table-responsive > .table-bordered > thead > tr > td:first-child,
- .table-responsive > .table-bordered > tbody > tr > td:first-child,
- .table-responsive > .table-bordered > tfoot > tr > td:first-child {
- border-left: 0;
- }
- .table-responsive > .table-bordered > thead > tr > th:last-child,
- .table-responsive > .table-bordered > tbody > tr > th:last-child,
- .table-responsive > .table-bordered > tfoot > tr > th:last-child,
- .table-responsive > .table-bordered > thead > tr > td:last-child,
- .table-responsive > .table-bordered > tbody > tr > td:last-child,
- .table-responsive > .table-bordered > tfoot > tr > td:last-child {
- border-right: 0;
- }
- .table-responsive > .table-bordered > tbody > tr:last-child > th,
- .table-responsive > .table-bordered > tfoot > tr:last-child > th,
- .table-responsive > .table-bordered > tbody > tr:last-child > td,
- .table-responsive > .table-bordered > tfoot > tr:last-child > td {
- border-bottom: 0;
- }
-}
-fieldset {
- padding: 0;
- margin: 0;
- border: 0;
- min-width: 0;
-}
-legend {
- display: block;
- width: 100%;
- padding: 0;
- margin-bottom: 20px;
- font-size: 21px;
- line-height: inherit;
- color: #333;
- border: 0;
- border-bottom: 1px solid #e5e5e5;
-}
-label {
- display: inline-block;
- max-width: 100%;
- margin-bottom: 5px;
- font-weight: bold;
-}
-input[type="search"] {
- box-sizing: border-box;
-}
-input[type="radio"],
-input[type="checkbox"] {
- margin: 4px 0 0;
- margin-top: 1px \9;
- line-height: normal;
-}
-input[type="file"] {
- display: block;
-}
-input[type="range"] {
- display: block;
- width: 100%;
-}
-select[multiple],
-select[size] {
- height: auto;
-}
-input[type="file"]:focus,
-input[type="radio"]:focus,
-input[type="checkbox"]:focus {
- outline: thin dotted;
- outline: 5px auto -webkit-focus-ring-color;
- outline-offset: -2px;
-}
-output {
- display: block;
- padding-top: 7px;
- font-size: 14px;
- line-height: 1.428571429;
- color: #fff;
-}
-.form-control,
-.inline-form-control {
- display: block;
- width: 100%;
- height: 34px;
- padding: 6px 12px;
- font-size: 14px;
- line-height: 1.428571429;
- color: #fff;
- background-color: #003b4a;
- background-image: none;
- border: 1px solid #001a20;
- border-radius: 4px;
- box-shadow: inset 0 1px 1px rgba(0,0,0,0.075);
- -webkit-transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s;
- transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s;
-}
-.form-control:focus,
-.inline-form-control:focus {
- border-color: #52dcff;
- outline: 0;
- box-shadow: inset 0 1px 1px rgba(0,0,0,0.075), 0 0 8px rgba(82,220,255,0.6);
-}
-.form-control::-moz-placeholder,
-.inline-form-control::-moz-placeholder {
- color: #999;
- opacity: 1;
-}
-.form-control:-ms-input-placeholder,
-.inline-form-control:-ms-input-placeholder {
- color: #999;
-}
-.form-control::-webkit-input-placeholder,
-.inline-form-control::-webkit-input-placeholder {
- color: #999;
-}
-.form-control[disabled],
-.inline-form-control[disabled],
-.form-control[readonly],
-.inline-form-control[readonly],
-fieldset[disabled] .form-control,
-fieldset[disabled] .inline-form-control {
- background-color: #eee;
- opacity: 1;
-}
-.form-control[disabled],
-.inline-form-control[disabled],
-fieldset[disabled] .form-control,
-fieldset[disabled] .inline-form-control {
- cursor: not-allowed;
-}
-textarea.form-control,
-textarea.inline-form-control {
- height: auto;
-}
-input[type="search"] {
- -webkit-appearance: none;
-}
-@media screen and (-webkit-min-device-pixel-ratio: 0) {
- input[type="date"],
- input[type="time"],
- input[type="datetime-local"],
- input[type="month"] {
- line-height: 34px;
- }
- input[type="date"].input-sm,
- input[type="time"].input-sm,
- input[type="datetime-local"].input-sm,
- input[type="month"].input-sm,
- .input-group-sm input[type="date"],
- .input-group-sm input[type="time"],
- .input-group-sm input[type="datetime-local"],
- .input-group-sm input[type="month"] {
- line-height: 30px;
- }
- input[type="date"].input-lg,
- input[type="time"].input-lg,
- input[type="datetime-local"].input-lg,
- input[type="month"].input-lg,
- .input-group-lg input[type="date"],
- .input-group-lg input[type="time"],
- .input-group-lg input[type="datetime-local"],
- .input-group-lg input[type="month"] {
- line-height: 46px;
- }
-}
-.form-group {
- margin-bottom: 15px;
-}
-.radio,
-.checkbox {
- position: relative;
- display: block;
- margin-top: 10px;
- margin-bottom: 10px;
-}
-.radio label,
-.checkbox label {
- min-height: 20px;
- padding-left: 20px;
- margin-bottom: 0;
- font-weight: normal;
- cursor: pointer;
-}
-.radio input[type="radio"],
-.radio-inline input[type="radio"],
-.checkbox input[type="checkbox"],
-.checkbox-inline input[type="checkbox"] {
- position: absolute;
- margin-left: -20px;
- margin-top: 4px \9;
-}
-.radio + .radio,
-.checkbox + .checkbox {
- margin-top: -5px;
-}
-.radio-inline,
-.checkbox-inline {
- position: relative;
- display: inline-block;
- padding-left: 20px;
- margin-bottom: 0;
- vertical-align: middle;
- font-weight: normal;
- cursor: pointer;
-}
-.radio-inline + .radio-inline,
-.checkbox-inline + .checkbox-inline {
- margin-top: 0;
- margin-left: 10px;
-}
-input[type="radio"][disabled],
-input[type="checkbox"][disabled],
-input[type="radio"].disabled,
-input[type="checkbox"].disabled,
-fieldset[disabled] input[type="radio"],
-fieldset[disabled] input[type="checkbox"] {
- cursor: not-allowed;
-}
-.radio-inline.disabled,
-.checkbox-inline.disabled,
-fieldset[disabled] .radio-inline,
-fieldset[disabled] .checkbox-inline {
- cursor: not-allowed;
-}
-.radio.disabled label,
-.checkbox.disabled label,
-fieldset[disabled] .radio label,
-fieldset[disabled] .checkbox label {
- cursor: not-allowed;
-}
-.form-control-static {
- padding-top: 7px;
- padding-bottom: 7px;
- margin-bottom: 0;
- min-height: 34px;
-}
-.form-control-static.input-lg,
-.form-control-static.input-sm {
- padding-left: 0;
- padding-right: 0;
-}
-.input-sm,
-.form-horizontal .form-group-sm .form-control,
-.input-group-sm > .form-control,
-.input-group-sm > .input-group-addon,
-.input-group-sm > .input-group-btn > .btn {
- height: 30px;
- padding: 5px 10px;
- font-size: 12px;
- line-height: 1.5;
- border-radius: 3px;
-}
-select.input-sm,
-select.form-horizontal .form-group-sm .form-control,
-select.input-group-sm > .form-control,
-select.input-group-sm > .input-group-addon,
-select.input-group-sm > .input-group-btn > .btn {
- height: 30px;
- line-height: 30px;
-}
-textarea.input-sm,
-textarea.form-horizontal .form-group-sm .form-control,
-textarea.input-group-sm > .form-control,
-textarea.input-group-sm > .input-group-addon,
-textarea.input-group-sm > .input-group-btn > .btn,
-select[multiple].input-sm,
-select[multiple].form-horizontal .form-group-sm .form-control,
-select[multiple].input-group-sm > .form-control,
-select[multiple].input-group-sm > .input-group-addon,
-select[multiple].input-group-sm > .input-group-btn > .btn {
- height: auto;
-}
-.form-group-sm .form-control {
- height: 30px;
- padding: 5px 10px;
- font-size: 12px;
- line-height: 1.5;
- border-radius: 3px;
-}
-select.form-group-sm .form-control {
- height: 30px;
- line-height: 30px;
-}
-textarea.form-group-sm .form-control,
-select[multiple].form-group-sm .form-control {
- height: auto;
-}
-.form-group-sm .form-control-static {
- height: 30px;
- padding: 5px 10px;
- font-size: 12px;
- line-height: 1.5;
- min-height: 32px;
-}
-.input-lg,
-.input-group-lg > .form-control,
-.input-group-lg > .input-group-addon,
-.input-group-lg > .input-group-btn > .btn {
- height: 46px;
- padding: 10px 16px;
- font-size: 18px;
- line-height: 1.3333333;
- border-radius: 6px;
-}
-select.input-lg,
-select.input-group-lg > .form-control,
-select.input-group-lg > .input-group-addon,
-select.input-group-lg > .input-group-btn > .btn {
- height: 46px;
- line-height: 46px;
-}
-textarea.input-lg,
-textarea.input-group-lg > .form-control,
-textarea.input-group-lg > .input-group-addon,
-textarea.input-group-lg > .input-group-btn > .btn,
-select[multiple].input-lg,
-select[multiple].input-group-lg > .form-control,
-select[multiple].input-group-lg > .input-group-addon,
-select[multiple].input-group-lg > .input-group-btn > .btn {
- height: auto;
-}
-.form-group-lg .form-control {
- height: 46px;
- padding: 10px 16px;
- font-size: 18px;
- line-height: 1.3333333;
- border-radius: 6px;
-}
-select.form-group-lg .form-control {
- height: 46px;
- line-height: 46px;
-}
-textarea.form-group-lg .form-control,
-select[multiple].form-group-lg .form-control {
- height: auto;
-}
-.form-group-lg .form-control-static {
- height: 46px;
- padding: 10px 16px;
- font-size: 18px;
- line-height: 1.3333333;
- min-height: 38px;
-}
-.has-feedback {
- position: relative;
-}
-.has-feedback .form-control {
- padding-right: 42.5px;
-}
-.form-control-feedback {
- position: absolute;
- top: 0;
- right: 0;
- z-index: 2;
- display: block;
- width: 34px;
- height: 34px;
- line-height: 34px;
- text-align: center;
- pointer-events: none;
-}
-.input-lg + .form-control-feedback {
- width: 46px;
- height: 46px;
- line-height: 46px;
-}
-.input-sm + .form-control-feedback {
- width: 30px;
- height: 30px;
- line-height: 30px;
-}
-.has-success .help-block,
-.has-success .control-label,
-.has-success .radio,
-.has-success .checkbox,
-.has-success .radio-inline,
-.has-success .checkbox-inline,
-.has-success.radio label,
-.has-success.checkbox label,
-.has-success.radio-inline label,
-.has-success.checkbox-inline label {
- color: #3c763d;
-}
-.has-success .form-control {
- border-color: #3c763d;
- box-shadow: inset 0 1px 1px rgba(0,0,0,0.075);
-}
-.has-success .form-control:focus {
- border-color: #366a37;
- box-shadow: inset 0 1px 1px rgba(0,0,0,0.075), 0 0 6px #52a254;
-}
-.has-success .input-group-addon {
- color: #3c763d;
- border-color: #3c763d;
- background-color: #dff0d8;
-}
-.has-success .form-control-feedback {
- color: #3c763d;
-}
-.has-warning .help-block,
-.has-warning .control-label,
-.has-warning .radio,
-.has-warning .checkbox,
-.has-warning .radio-inline,
-.has-warning .checkbox-inline,
-.has-warning.radio label,
-.has-warning.checkbox label,
-.has-warning.radio-inline label,
-.has-warning.checkbox-inline label {
- color: #8a6d3b;
-}
-.has-warning .form-control {
- border-color: #8a6d3b;
- box-shadow: inset 0 1px 1px rgba(0,0,0,0.075);
-}
-.has-warning .form-control:focus {
- border-color: #7c6235;
- box-shadow: inset 0 1px 1px rgba(0,0,0,0.075), 0 0 6px #b48f50;
-}
-.has-warning .input-group-addon {
- color: #8a6d3b;
- border-color: #8a6d3b;
- background-color: #fcf8e3;
-}
-.has-warning .form-control-feedback {
- color: #8a6d3b;
-}
-.has-error .help-block,
-.has-error .control-label,
-.has-error .radio,
-.has-error .checkbox,
-.has-error .radio-inline,
-.has-error .checkbox-inline,
-.has-error.radio label,
-.has-error.checkbox label,
-.has-error.radio-inline label,
-.has-error.checkbox-inline label {
- color: #a94442;
-}
-.has-error .form-control {
- border-color: #a94442;
- box-shadow: inset 0 1px 1px rgba(0,0,0,0.075);
-}
-.has-error .form-control:focus {
- border-color: #983d3b;
- box-shadow: inset 0 1px 1px rgba(0,0,0,0.075), 0 0 6px #c16361;
-}
-.has-error .input-group-addon {
- color: #a94442;
- border-color: #a94442;
- background-color: #f2dede;
-}
-.has-error .form-control-feedback {
- color: #a94442;
-}
-.has-feedback label ~ .form-control-feedback {
- top: 25px;
-}
-.has-feedback label.sr-only ~ .form-control-feedback {
- top: 0;
-}
-.help-block {
- display: block;
- margin-top: 5px;
- margin-bottom: 10px;
- color: #666;
-}
-@media (min-width: 768px) {
- .form-inline .form-group,
- .navbar-form .form-group {
- display: inline-block;
- margin-bottom: 0;
- vertical-align: middle;
- }
- .form-inline .form-control,
- .navbar-form .form-control {
- display: inline-block;
- width: auto;
- vertical-align: middle;
- }
- .form-inline .form-control-static,
- .navbar-form .form-control-static {
- display: inline-block;
- }
- .form-inline .input-group,
- .navbar-form .input-group {
- display: inline-table;
- vertical-align: middle;
- }
- .form-inline .input-group .input-group-addon,
- .navbar-form .input-group .input-group-addon,
- .form-inline .input-group .input-group-btn,
- .navbar-form .input-group .input-group-btn,
- .form-inline .input-group .form-control,
- .navbar-form .input-group .form-control {
- width: auto;
- }
- .form-inline .input-group > .form-control,
- .navbar-form .input-group > .form-control {
- width: 100%;
- }
- .form-inline .control-label,
- .navbar-form .control-label {
- margin-bottom: 0;
- vertical-align: middle;
- }
- .form-inline .radio,
- .navbar-form .radio,
- .form-inline .checkbox,
- .navbar-form .checkbox {
- display: inline-block;
- margin-top: 0;
- margin-bottom: 0;
- vertical-align: middle;
- }
- .form-inline .radio label,
- .navbar-form .radio label,
- .form-inline .checkbox label,
- .navbar-form .checkbox label {
- padding-left: 0;
- }
- .form-inline .radio input[type="radio"],
- .navbar-form .radio input[type="radio"],
- .form-inline .checkbox input[type="checkbox"],
- .navbar-form .checkbox input[type="checkbox"] {
- position: relative;
- margin-left: 0;
- }
- .form-inline .has-feedback .form-control-feedback,
- .navbar-form .has-feedback .form-control-feedback {
- top: 0;
- }
-}
-.form-horizontal .radio,
-.form-horizontal .checkbox,
-.form-horizontal .radio-inline,
-.form-horizontal .checkbox-inline {
- margin-top: 0;
- margin-bottom: 0;
- padding-top: 7px;
-}
-.form-horizontal .radio,
-.form-horizontal .checkbox {
- min-height: 27px;
-}
-.form-horizontal .form-group {
- margin-left: -15px;
- margin-right: -15px;
-}
-@media (min-width: 768px) {
- .form-horizontal .control-label {
- text-align: right;
- margin-bottom: 0;
- padding-top: 7px;
- }
-}
-.form-horizontal .has-feedback .form-control-feedback {
- right: 15px;
-}
-@media (min-width: 768px) {
- .form-horizontal .form-group-lg .control-label {
- padding-top: 14.333333px;
- }
-}
-@media (min-width: 768px) {
- .form-horizontal .form-group-sm .control-label {
- padding-top: 6px;
- }
-}
-.btn {
- display: inline-block;
- margin-bottom: 0;
- font-weight: normal;
- text-align: center;
- vertical-align: middle;
- -ms-touch-action: manipulation;
- touch-action: manipulation;
- cursor: pointer;
- background-image: none;
- border: 1px solid transparent;
- white-space: nowrap;
- padding: 6px 12px;
- font-size: 14px;
- line-height: 1.428571429;
- border-radius: 4px;
- -webkit-user-select: none;
- -moz-user-select: none;
- -ms-user-select: none;
- user-select: none;
-}
-.btn:focus,
-.btn:active:focus,
-.btn.active:focus,
-.btn.focus,
-.btn:active.focus,
-.btn.active.focus {
- outline: thin dotted;
- outline: 5px auto -webkit-focus-ring-color;
- outline-offset: -2px;
-}
-.btn:hover,
-.btn:focus,
-.btn.focus {
- color: #99b2b8;
- text-decoration: none;
-}
-.btn:active,
-.btn.active {
- outline: 0;
- background-image: none;
- box-shadow: inset 0 3px 5px rgba(0,0,0,0.125);
-}
-.btn.disabled,
-.btn[disabled],
-fieldset[disabled] .btn {
- cursor: not-allowed;
- pointer-events: none;
- opacity: 0.65;
- filter: alpha(opacity=65);
- box-shadow: none;
-}
-.btn-default {
- color: #99b2b8;
- background-color: #004355;
- border-color: #001a20;
-}
-.btn-default:hover,
-.btn-default:focus,
-.btn-default.focus,
-.btn-default:active,
-.btn-default.active,
-.open > .dropdown-toggle.btn-default {
- color: #99b2b8;
- background-color: #003c4d;
- border-color: #00171c;
-}
-.btn-default:active,
-.btn-default.active,
-.open > .dropdown-toggle.btn-default {
- background-image: none;
-}
-.btn-default.disabled,
-.btn-default[disabled],
-fieldset[disabled] .btn-default,
-.btn-default.disabled:hover,
-.btn-default[disabled]:hover,
-fieldset[disabled] .btn-default:hover,
-.btn-default.disabled:focus,
-.btn-default[disabled]:focus,
-fieldset[disabled] .btn-default:focus,
-.btn-default.disabled.focus,
-.btn-default[disabled].focus,
-fieldset[disabled] .btn-default.focus,
-.btn-default.disabled:active,
-.btn-default[disabled]:active,
-fieldset[disabled] .btn-default:active,
-.btn-default.disabled.active,
-.btn-default[disabled].active,
-fieldset[disabled] .btn-default.active {
- background-color: #004355;
- border-color: #001a20;
-}
-.btn-default .badge {
- color: #004355;
- background-color: #99b2b8;
-}
-.btn-primary {
- color: #fff;
- background-color: #088cff;
- border-color: #0086fa;
-}
-.btn-primary:hover,
-.btn-primary:focus,
-.btn-primary.focus,
-.btn-primary:active,
-.btn-primary.active,
-.open > .dropdown-toggle.btn-primary {
- color: #fff;
- background-color: #007eed;
- border-color: #0076dc;
-}
-.btn-primary:active,
-.btn-primary.active,
-.open > .dropdown-toggle.btn-primary {
- background-image: none;
-}
-.btn-primary.disabled,
-.btn-primary[disabled],
-fieldset[disabled] .btn-primary,
-.btn-primary.disabled:hover,
-.btn-primary[disabled]:hover,
-fieldset[disabled] .btn-primary:hover,
-.btn-primary.disabled:focus,
-.btn-primary[disabled]:focus,
-fieldset[disabled] .btn-primary:focus,
-.btn-primary.disabled.focus,
-.btn-primary[disabled].focus,
-fieldset[disabled] .btn-primary.focus,
-.btn-primary.disabled:active,
-.btn-primary[disabled]:active,
-fieldset[disabled] .btn-primary:active,
-.btn-primary.disabled.active,
-.btn-primary[disabled].active,
-fieldset[disabled] .btn-primary.active {
- background-color: #088cff;
- border-color: #0086fa;
-}
-.btn-primary .badge {
- color: #088cff;
- background-color: #fff;
-}
-.btn-success {
- color: #fff;
- background-color: #22bd89;
- border-color: #20b482;
-}
-.btn-success:hover,
-.btn-success:focus,
-.btn-success.focus,
-.btn-success:active,
-.btn-success.active,
-.open > .dropdown-toggle.btn-success {
- color: #fff;
- background-color: #1faa7b;
- border-color: #1c9e72;
-}
-.btn-success:active,
-.btn-success.active,
-.open > .dropdown-toggle.btn-success {
- background-image: none;
-}
-.btn-success.disabled,
-.btn-success[disabled],
-fieldset[disabled] .btn-success,
-.btn-success.disabled:hover,
-.btn-success[disabled]:hover,
-fieldset[disabled] .btn-success:hover,
-.btn-success.disabled:focus,
-.btn-success[disabled]:focus,
-fieldset[disabled] .btn-success:focus,
-.btn-success.disabled.focus,
-.btn-success[disabled].focus,
-fieldset[disabled] .btn-success.focus,
-.btn-success.disabled:active,
-.btn-success[disabled]:active,
-fieldset[disabled] .btn-success:active,
-.btn-success.disabled.active,
-.btn-success[disabled].active,
-fieldset[disabled] .btn-success.active {
- background-color: #22bd89;
- border-color: #20b482;
-}
-.btn-success .badge {
- color: #22bd89;
- background-color: #fff;
-}
-.btn-info {
- color: #fff;
- background-color: #5bdeff;
- border-color: #4adbff;
-}
-.btn-info:hover,
-.btn-info:focus,
-.btn-info.focus,
-.btn-info:active,
-.btn-info.active,
-.open > .dropdown-toggle.btn-info {
- color: #fff;
- background-color: #38d7ff;
- border-color: #23d3ff;
-}
-.btn-info:active,
-.btn-info.active,
-.open > .dropdown-toggle.btn-info {
- background-image: none;
-}
-.btn-info.disabled,
-.btn-info[disabled],
-fieldset[disabled] .btn-info,
-.btn-info.disabled:hover,
-.btn-info[disabled]:hover,
-fieldset[disabled] .btn-info:hover,
-.btn-info.disabled:focus,
-.btn-info[disabled]:focus,
-fieldset[disabled] .btn-info:focus,
-.btn-info.disabled.focus,
-.btn-info[disabled].focus,
-fieldset[disabled] .btn-info.focus,
-.btn-info.disabled:active,
-.btn-info[disabled]:active,
-fieldset[disabled] .btn-info:active,
-.btn-info.disabled.active,
-.btn-info[disabled].active,
-fieldset[disabled] .btn-info.active {
- background-color: #5bdeff;
- border-color: #4adbff;
-}
-.btn-info .badge {
- color: #5bdeff;
- background-color: #fff;
-}
-.btn-warning {
- color: #fff;
- background-color: #cd8737;
- border-color: #c68031;
-}
-.btn-warning:hover,
-.btn-warning:focus,
-.btn-warning.focus,
-.btn-warning:active,
-.btn-warning.active,
-.open > .dropdown-toggle.btn-warning {
- color: #fff;
- background-color: #bb7a2f;
- border-color: #ae712b;
-}
-.btn-warning:active,
-.btn-warning.active,
-.open > .dropdown-toggle.btn-warning {
- background-image: none;
-}
-.btn-warning.disabled,
-.btn-warning[disabled],
-fieldset[disabled] .btn-warning,
-.btn-warning.disabled:hover,
-.btn-warning[disabled]:hover,
-fieldset[disabled] .btn-warning:hover,
-.btn-warning.disabled:focus,
-.btn-warning[disabled]:focus,
-fieldset[disabled] .btn-warning:focus,
-.btn-warning.disabled.focus,
-.btn-warning[disabled].focus,
-fieldset[disabled] .btn-warning.focus,
-.btn-warning.disabled:active,
-.btn-warning[disabled]:active,
-fieldset[disabled] .btn-warning:active,
-.btn-warning.disabled.active,
-.btn-warning[disabled].active,
-fieldset[disabled] .btn-warning.active {
- background-color: #cd8737;
- border-color: #c68031;
-}
-.btn-warning .badge {
- color: #cd8737;
- background-color: #fff;
-}
-.btn-danger {
- color: #fff;
- background-color: #da2828;
- border-color: #d12424;
-}
-.btn-danger:hover,
-.btn-danger:focus,
-.btn-danger.focus,
-.btn-danger:active,
-.btn-danger.active,
-.open > .dropdown-toggle.btn-danger {
- color: #fff;
- background-color: #c62222;
- border-color: #b82020;
-}
-.btn-danger:active,
-.btn-danger.active,
-.open > .dropdown-toggle.btn-danger {
- background-image: none;
-}
-.btn-danger.disabled,
-.btn-danger[disabled],
-fieldset[disabled] .btn-danger,
-.btn-danger.disabled:hover,
-.btn-danger[disabled]:hover,
-fieldset[disabled] .btn-danger:hover,
-.btn-danger.disabled:focus,
-.btn-danger[disabled]:focus,
-fieldset[disabled] .btn-danger:focus,
-.btn-danger.disabled.focus,
-.btn-danger[disabled].focus,
-fieldset[disabled] .btn-danger.focus,
-.btn-danger.disabled:active,
-.btn-danger[disabled]:active,
-fieldset[disabled] .btn-danger:active,
-.btn-danger.disabled.active,
-.btn-danger[disabled].active,
-fieldset[disabled] .btn-danger.active {
- background-color: #da2828;
- border-color: #d12424;
-}
-.btn-danger .badge {
- color: #da2828;
- background-color: #fff;
-}
-.btn-link {
- color: #d5dfe2;
- font-weight: normal;
- border-radius: 0;
-}
-.btn-link,
-.btn-link:active,
-.btn-link.active,
-.btn-link[disabled],
-fieldset[disabled] .btn-link {
- background-color: transparent;
- box-shadow: none;
-}
-.btn-link,
-.btn-link:hover,
-.btn-link:focus,
-.btn-link:active {
- border-color: transparent;
-}
-.btn-link:hover,
-.btn-link:focus {
- color: #aec1c7;
- text-decoration: underline;
- background-color: transparent;
-}
-.btn-link[disabled]:hover,
-fieldset[disabled] .btn-link:hover,
-.btn-link[disabled]:focus,
-fieldset[disabled] .btn-link:focus {
- color: #777;
- text-decoration: none;
-}
-.btn-lg,
-.btn-group-lg > .btn {
- padding: 10px 16px;
- font-size: 18px;
- line-height: 1.3333333;
- border-radius: 6px;
-}
-.btn-sm,
-.btn-group-sm > .btn {
- padding: 5px 10px;
- font-size: 12px;
- line-height: 1.5;
- border-radius: 3px;
-}
-.btn-xs,
-.btn-group-xs > .btn {
- padding: 1px 5px;
- font-size: 12px;
- line-height: 1.5;
- border-radius: 3px;
-}
-.btn-block {
- display: block;
- width: 100%;
-}
-.btn-block + .btn-block {
- margin-top: 5px;
-}
-input[type="submit"].btn-block,
-input[type="reset"].btn-block,
-input[type="button"].btn-block {
- width: 100%;
-}
-.fade {
- opacity: 0;
- -webkit-transition: opacity 0.15s linear;
- transition: opacity 0.15s linear;
-}
-.fade.in {
- opacity: 1;
-}
-.collapse {
- display: none;
-}
-.collapse.in {
- display: block;
-}
-tr.collapse.in {
- display: table-row;
-}
-tbody.collapse.in {
- display: table-row-group;
-}
-.collapsing {
- position: relative;
- height: 0;
- overflow: hidden;
- -webkit-transition-property: height, visibility;
- transition-property: height, visibility;
- -webkit-transition-duration: 0.35s;
- transition-duration: 0.35s;
- -webkit-transition-timing-function: ease;
- transition-timing-function: ease;
-}
-.caret {
- display: inline-block;
- width: 0;
- height: 0;
- margin-left: 2px;
- vertical-align: middle;
- border-top: 4px dashed;
- border-right: 4px solid transparent;
- border-left: 4px solid transparent;
-}
-.dropup,
-.dropdown {
- position: relative;
-}
-.dropdown-toggle:focus {
- outline: 0;
-}
-.dropdown-menu {
- position: absolute;
- top: 100%;
- left: 0;
- z-index: 1000;
- display: none;
- float: left;
- min-width: 160px;
- padding: 5px 0;
- margin: 2px 0 0;
- list-style: none;
- font-size: 14px;
- text-align: left;
- background-color: #002b36;
- border: 1px solid #ccc;
- border: 1px solid #001a20;
- border-radius: 4px;
- box-shadow: 0 6px 12px rgba(0,0,0,0.175);
- background-clip: padding-box;
-}
-.dropdown-menu.pull-right {
- right: 0;
- left: auto;
-}
-.dropdown-menu .divider {
- height: 1px;
- margin: 9px 0;
- overflow: hidden;
- background-color: #e5e5e5;
-}
-.dropdown-menu > li > a {
- display: block;
- padding: 3px 20px;
- clear: both;
- font-weight: normal;
- line-height: 1.428571429;
- color: #99b2b8;
- white-space: nowrap;
-}
-.dropdown-menu > li > a:hover,
-.dropdown-menu > li > a:focus {
- text-decoration: none;
- color: #fff;
- background-color: #004b5f;
-}
-.dropdown-menu > .active > a,
-.dropdown-menu > .active > a:hover,
-.dropdown-menu > .active > a:focus {
- color: #fff;
- text-decoration: none;
- outline: 0;
- background-color: #088cff;
-}
-.dropdown-menu > .disabled > a,
-.dropdown-menu > .disabled > a:hover,
-.dropdown-menu > .disabled > a:focus {
- color: #777;
-}
-.dropdown-menu > .disabled > a:hover,
-.dropdown-menu > .disabled > a:focus {
- text-decoration: none;
- background-color: transparent;
- background-image: none;
- filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
- cursor: not-allowed;
-}
-.open > .dropdown-menu {
- display: block;
-}
-.open > a {
- outline: 0;
-}
-.dropdown-menu-right {
- left: auto;
- right: 0;
-}
-.dropdown-menu-left {
- left: 0;
- right: auto;
-}
-.dropdown-header {
- display: block;
- padding: 3px 20px;
- font-size: 12px;
- line-height: 1.428571429;
- color: #777;
- white-space: nowrap;
-}
-.dropdown-backdrop {
- position: fixed;
- left: 0;
- right: 0;
- bottom: 0;
- top: 0;
- z-index: 990;
-}
-.pull-right > .dropdown-menu {
- right: 0;
- left: auto;
-}
-.dropup .caret,
-.navbar-fixed-bottom .dropdown .caret {
- border-top: 0;
- border-bottom: 4px solid;
- content: "";
-}
-.dropup .dropdown-menu,
-.navbar-fixed-bottom .dropdown .dropdown-menu {
- top: auto;
- bottom: 100%;
- margin-bottom: 2px;
-}
-@media (min-width: 768px) {
- .navbar-right .dropdown-menu {
- right: 0;
- left: auto;
- }
- .navbar-right .dropdown-menu-left {
- right: auto;
- left: 0;
- }
-}
-.btn-group,
-.btn-group-vertical {
- position: relative;
- display: inline-block;
- vertical-align: middle;
-}
-.btn-group > .btn,
-.btn-group-vertical > .btn {
- position: relative;
- float: left;
-}
-.btn-group > .btn:hover,
-.btn-group-vertical > .btn:hover,
-.btn-group > .btn:focus,
-.btn-group-vertical > .btn:focus,
-.btn-group > .btn:active,
-.btn-group-vertical > .btn:active,
-.btn-group > .btn.active,
-.btn-group-vertical > .btn.active {
- z-index: 2;
-}
-.btn-group .btn + .btn,
-.btn-group .btn + .btn-group,
-.btn-group .btn-group + .btn,
-.btn-group .btn-group + .btn-group {
- margin-left: -1px;
-}
-.btn-toolbar {
- margin-left: -5px;
-}
-.btn-toolbar .btn-group,
-.btn-toolbar .input-group {
- float: left;
-}
-.btn-toolbar > .btn,
-.btn-toolbar > .btn-group,
-.btn-toolbar > .input-group {
- margin-left: 5px;
-}
-.btn-group > .btn:not(:first-child):not(:last-child):not(.dropdown-toggle) {
- border-radius: 0;
-}
-.btn-group > .btn:first-child {
- margin-left: 0;
-}
-.btn-group > .btn:first-child:not(:last-child):not(.dropdown-toggle) {
- border-bottom-right-radius: 0;
- border-top-right-radius: 0;
-}
-.btn-group > .btn:last-child:not(:first-child),
-.btn-group > .dropdown-toggle:not(:first-child) {
- border-bottom-left-radius: 0;
- border-top-left-radius: 0;
-}
-.btn-group > .btn-group {
- float: left;
-}
-.btn-group > .btn-group:not(:first-child):not(:last-child) > .btn {
- border-radius: 0;
-}
-.btn-group > .btn-group:first-child:not(:last-child) > .btn:last-child,
-.btn-group > .btn-group:first-child:not(:last-child) > .dropdown-toggle {
- border-bottom-right-radius: 0;
- border-top-right-radius: 0;
-}
-.btn-group > .btn-group:last-child:not(:first-child) > .btn:first-child {
- border-bottom-left-radius: 0;
- border-top-left-radius: 0;
-}
-.btn-group .dropdown-toggle:active,
-.btn-group.open .dropdown-toggle {
- outline: 0;
-}
-.btn-group > .btn + .dropdown-toggle {
- padding-left: 8px;
- padding-right: 8px;
-}
-.btn-group > .btn-lg + .dropdown-toggle {
- padding-left: 12px;
- padding-right: 12px;
-}
-.btn-group.open .dropdown-toggle {
- box-shadow: inset 0 3px 5px rgba(0,0,0,0.125);
-}
-.btn-group.open .dropdown-toggle.btn-link {
- box-shadow: none;
-}
-.btn .caret {
- margin-left: 0;
-}
-.btn-lg .caret {
- border-width: 5px 5px 0;
- border-bottom-width: 0;
-}
-.dropup .btn-lg .caret {
- border-width: 0 5px 5px;
-}
-.btn-group-vertical > .btn,
-.btn-group-vertical > .btn-group,
-.btn-group-vertical > .btn-group > .btn {
- display: block;
- float: none;
- width: 100%;
- max-width: 100%;
-}
-.btn-group-vertical > .btn-group > .btn {
- float: none;
-}
-.btn-group-vertical > .btn + .btn,
-.btn-group-vertical > .btn + .btn-group,
-.btn-group-vertical > .btn-group + .btn,
-.btn-group-vertical > .btn-group + .btn-group {
- margin-top: -1px;
- margin-left: 0;
-}
-.btn-group-vertical > .btn:not(:first-child):not(:last-child) {
- border-radius: 0;
-}
-.btn-group-vertical > .btn:first-child:not(:last-child) {
- border-top-right-radius: 4px;
- border-bottom-right-radius: 0;
- border-bottom-left-radius: 0;
-}
-.btn-group-vertical > .btn:last-child:not(:first-child) {
- border-bottom-left-radius: 4px;
- border-top-right-radius: 0;
- border-top-left-radius: 0;
-}
-.btn-group-vertical > .btn-group:not(:first-child):not(:last-child) > .btn {
- border-radius: 0;
-}
-.btn-group-vertical > .btn-group:first-child:not(:last-child) > .btn:last-child,
-.btn-group-vertical > .btn-group:first-child:not(:last-child) > .dropdown-toggle {
- border-bottom-right-radius: 0;
- border-bottom-left-radius: 0;
-}
-.btn-group-vertical > .btn-group:last-child:not(:first-child) > .btn:first-child {
- border-top-right-radius: 0;
- border-top-left-radius: 0;
-}
-.btn-group-justified {
- display: table;
- width: 100%;
- table-layout: fixed;
- border-collapse: separate;
-}
-.btn-group-justified > .btn,
-.btn-group-justified > .btn-group {
- float: none;
- display: table-cell;
- width: 1%;
-}
-.btn-group-justified > .btn-group .btn {
- width: 100%;
-}
-.btn-group-justified > .btn-group .dropdown-menu {
- left: auto;
-}
-[data-toggle="buttons"] > .btn input[type="radio"],
-[data-toggle="buttons"] > .btn-group > .btn input[type="radio"],
-[data-toggle="buttons"] > .btn input[type="checkbox"],
-[data-toggle="buttons"] > .btn-group > .btn input[type="checkbox"] {
- position: absolute;
- clip: rect(0, 0, 0, 0);
- pointer-events: none;
-}
-.input-group {
- position: relative;
- display: table;
- border-collapse: separate;
-}
-.input-group[class*="col-"] {
- float: none;
- padding-left: 0;
- padding-right: 0;
-}
-.input-group .form-control {
- position: relative;
- z-index: 2;
- float: left;
- width: 100%;
- margin-bottom: 0;
-}
-.input-group-addon,
-.input-group-btn,
-.input-group .form-control {
- display: table-cell;
-}
-.input-group-addon:not(:first-child):not(:last-child),
-.input-group-btn:not(:first-child):not(:last-child),
-.input-group .form-control:not(:first-child):not(:last-child) {
- border-radius: 0;
-}
-.input-group-addon,
-.input-group-btn {
- width: 1%;
- white-space: nowrap;
- vertical-align: middle;
-}
-.input-group-addon {
- padding: 6px 12px;
- font-size: 14px;
- font-weight: normal;
- line-height: 1;
- color: #fff;
- text-align: center;
- background-color: #eee;
- border: 1px solid #001a20;
- border-radius: 4px;
-}
-.input-group-addon.input-sm {
- padding: 5px 10px;
- font-size: 12px;
- border-radius: 3px;
-}
-.input-group-addon.input-lg {
- padding: 10px 16px;
- font-size: 18px;
- border-radius: 6px;
-}
-.input-group-addon input[type="radio"],
-.input-group-addon input[type="checkbox"] {
- margin-top: 0;
-}
-.input-group .form-control:first-child,
-.input-group-addon:first-child,
-.input-group-btn:first-child > .btn,
-.input-group-btn:first-child > .btn-group > .btn,
-.input-group-btn:first-child > .dropdown-toggle,
-.input-group-btn:last-child > .btn:not(:last-child):not(.dropdown-toggle),
-.input-group-btn:last-child > .btn-group:not(:last-child) > .btn {
- border-bottom-right-radius: 0;
- border-top-right-radius: 0;
-}
-.input-group-addon:first-child {
- border-right: 0;
-}
-.input-group .form-control:last-child,
-.input-group-addon:last-child,
-.input-group-btn:last-child > .btn,
-.input-group-btn:last-child > .btn-group > .btn,
-.input-group-btn:last-child > .dropdown-toggle,
-.input-group-btn:first-child > .btn:not(:first-child),
-.input-group-btn:first-child > .btn-group:not(:first-child) > .btn {
- border-bottom-left-radius: 0;
- border-top-left-radius: 0;
-}
-.input-group-addon:last-child {
- border-left: 0;
-}
-.input-group-btn {
- position: relative;
- font-size: 0;
- white-space: nowrap;
-}
-.input-group-btn > .btn {
- position: relative;
-}
-.input-group-btn > .btn + .btn {
- margin-left: -1px;
-}
-.input-group-btn > .btn:hover,
-.input-group-btn > .btn:focus,
-.input-group-btn > .btn:active {
- z-index: 2;
-}
-.input-group-btn:first-child > .btn,
-.input-group-btn:first-child > .btn-group {
- margin-right: -1px;
-}
-.input-group-btn:last-child > .btn,
-.input-group-btn:last-child > .btn-group {
- margin-left: -1px;
-}
-.nav {
- margin-bottom: 0;
- padding-left: 0;
- list-style: none;
-}
-.nav > li {
- position: relative;
- display: block;
-}
-.nav > li > a {
- position: relative;
- display: block;
- padding: 10px 15px;
-}
-.nav > li > a:hover,
-.nav > li > a:focus {
- text-decoration: none;
- background-color: #003b4a;
-}
-.nav > li.disabled > a {
- color: #777;
-}
-.nav > li.disabled > a:hover,
-.nav > li.disabled > a:focus {
- color: #777;
- text-decoration: none;
- background-color: transparent;
- cursor: not-allowed;
-}
-.nav .open > a,
-.nav .open > a:hover,
-.nav .open > a:focus {
- background-color: #003b4a;
- border-color: #d5dfe2;
-}
-.nav .nav-divider {
- height: 1px;
- margin: 9px 0;
- overflow: hidden;
- background-color: #e5e5e5;
-}
-.nav > li > a > img {
- max-width: none;
-}
-.nav-tabs {
- border-bottom: 1px solid #001a20;
-}
-.nav-tabs > li {
- float: left;
- margin-bottom: -1px;
-}
-.nav-tabs > li > a {
- margin-right: 2px;
- line-height: 1.428571429;
- border: 1px solid transparent;
- border-radius: 4px 4px 0 0;
-}
-.nav-tabs > li > a:hover {
- border-color: #001a20 #001a20 #001a20;
-}
-.nav-tabs > li.active > a,
-.nav-tabs > li.active > a:hover,
-.nav-tabs > li.active > a:focus {
- color: #fff;
- background-color: transparent #004b5f;
- border: 1px solid #001a20;
- border-bottom-color: transparent;
- cursor: default;
-}
-.nav-pills > li {
- float: left;
-}
-.nav-pills > li > a {
- border-radius: 4px;
-}
-.nav-pills > li + li {
- margin-left: 2px;
-}
-.nav-pills > li.active > a,
-.nav-pills > li.active > a:hover,
-.nav-pills > li.active > a:focus {
- color: #d5dfe2;
- background-color: #088cff;
-}
-.nav-stacked > li {
- float: none;
-}
-.nav-stacked > li + li {
- margin-top: 2px;
- margin-left: 0;
-}
-.nav-justified,
-.nav-tabs.nav-justified {
- width: 100%;
-}
-.nav-justified > li,
-.nav-tabs.nav-justified > li {
- float: none;
-}
-.nav-justified > li > a,
-.nav-tabs.nav-justified > li > a {
- text-align: center;
- margin-bottom: 5px;
-}
-.nav-justified > .dropdown .dropdown-menu,
-.nav-tabs.nav-justified > .dropdown .dropdown-menu {
- top: auto;
- left: auto;
-}
-@media (min-width: 768px) {
- .nav-justified > li,
- .nav-tabs.nav-justified > li {
- display: table-cell;
- width: 1%;
- }
- .nav-justified > li > a,
- .nav-tabs.nav-justified > li > a {
- margin-bottom: 0;
- }
-}
-.nav-tabs-justified,
-.nav-tabs.nav-justified {
- border-bottom: 0;
-}
-.nav-tabs-justified > li > a,
-.nav-tabs.nav-justified > li > a {
- margin-right: 0;
- border-radius: 4px;
-}
-.nav-tabs-justified > .active > a,
-.nav-tabs.nav-justified > .active > a,
-.nav-tabs-justified > .active > a:hover,
-.nav-tabs.nav-justified > .active > a:hover,
-.nav-tabs-justified > .active > a:focus,
-.nav-tabs.nav-justified > .active > a:focus {
- border: 1px solid #001a20;
-}
-@media (min-width: 768px) {
- .nav-tabs-justified > li > a,
- .nav-tabs.nav-justified > li > a {
- border-bottom: 1px solid #001a20;
- border-radius: 4px 4px 0 0;
- }
- .nav-tabs-justified > .active > a,
- .nav-tabs.nav-justified > .active > a,
- .nav-tabs-justified > .active > a:hover,
- .nav-tabs.nav-justified > .active > a:hover,
- .nav-tabs-justified > .active > a:focus,
- .nav-tabs.nav-justified > .active > a:focus {
- border-bottom-color: #001a20;
- }
-}
-.tab-content > .tab-pane {
- display: none;
-}
-.tab-content > .active {
- display: block;
-}
-.nav-tabs .dropdown-menu {
- margin-top: -1px;
- border-top-right-radius: 0;
- border-top-left-radius: 0;
-}
-.navbar {
- position: relative;
- min-height: 50px;
- margin-bottom: 20px;
- border: 1px solid transparent;
-}
-@media (min-width: 768px) {
- .navbar {
- border-radius: 4px;
- }
-}
-@media (min-width: 768px) {
- .navbar-header {
- float: left;
- }
-}
-.navbar-collapse {
- overflow-x: visible;
- padding-right: 15px;
- padding-left: 15px;
- border-top: 1px solid transparent;
- box-shadow: inset 0 1px 0 rgba(255,255,255,0.1);
- -webkit-overflow-scrolling: touch;
-}
-.navbar-collapse.in {
- overflow-y: auto;
-}
-@media (min-width: 768px) {
- .navbar-collapse {
- width: auto;
- border-top: 0;
- box-shadow: none;
- }
- .navbar-collapse.collapse {
- display: block !important;
- height: auto !important;
- padding-bottom: 0;
- overflow: visible !important;
- }
- .navbar-collapse.in {
- overflow-y: visible;
- }
- .navbar-fixed-top .navbar-collapse,
- .navbar-static-top .navbar-collapse,
- .navbar-fixed-bottom .navbar-collapse {
- padding-left: 0;
- padding-right: 0;
- }
-}
-.navbar-fixed-top .navbar-collapse,
-.navbar-fixed-bottom .navbar-collapse {
- max-height: 340px;
-}
-@media (max-device-width: 480px) and (orientation: landscape) {
- .navbar-fixed-top .navbar-collapse,
- .navbar-fixed-bottom .navbar-collapse {
- max-height: 200px;
- }
-}
-.container > .navbar-header,
-.container-fluid > .navbar-header,
-.container > .navbar-collapse,
-.container-fluid > .navbar-collapse {
- margin-right: -15px;
- margin-left: -15px;
-}
-@media (min-width: 768px) {
- .container > .navbar-header,
- .container-fluid > .navbar-header,
- .container > .navbar-collapse,
- .container-fluid > .navbar-collapse {
- margin-right: 0;
- margin-left: 0;
- }
-}
-.navbar-static-top {
- z-index: 1000;
- border-width: 0 0 1px;
-}
-@media (min-width: 768px) {
- .navbar-static-top {
- border-radius: 0;
- }
-}
-.navbar-fixed-top,
-.navbar-fixed-bottom {
- position: fixed;
- right: 0;
- left: 0;
- z-index: 1030;
-}
-@media (min-width: 768px) {
- .navbar-fixed-top,
- .navbar-fixed-bottom {
- border-radius: 0;
- }
-}
-.navbar-fixed-top {
- top: 0;
- border-width: 0 0 1px;
-}
-.navbar-fixed-bottom {
- bottom: 0;
- margin-bottom: 0;
- border-width: 1px 0 0;
-}
-.navbar-brand {
- float: left;
- padding: 15px 15px;
- font-size: 18px;
- line-height: 20px;
- height: 50px;
-}
-.navbar-brand:hover,
-.navbar-brand:focus {
- text-decoration: none;
-}
-.navbar-brand > img {
- display: block;
-}
-@media (min-width: 768px) {
- .navbar > .container .navbar-brand,
- .navbar > .container-fluid .navbar-brand {
- margin-left: -15px;
- }
-}
-.navbar-toggle {
- position: relative;
- float: right;
- margin-right: 15px;
- padding: 9px 10px;
- margin-top: 8px;
- margin-bottom: 8px;
- background-color: transparent;
- background-image: none;
- border: 1px solid transparent;
- border-radius: 4px;
-}
-.navbar-toggle:focus {
- outline: 0;
-}
-.navbar-toggle .icon-bar {
- display: block;
- width: 22px;
- height: 2px;
- border-radius: 1px;
-}
-.navbar-toggle .icon-bar + .icon-bar {
- margin-top: 4px;
-}
-@media (min-width: 768px) {
- .navbar-toggle {
- display: none;
- }
-}
-.navbar-nav {
- margin: 7.5px -15px;
-}
-.navbar-nav > li > a {
- padding-top: 10px;
- padding-bottom: 10px;
- line-height: 20px;
-}
-@media (max-width: 767px) {
- .navbar-nav .open .dropdown-menu {
- position: static;
- float: none;
- width: auto;
- margin-top: 0;
- background-color: transparent;
- border: 0;
- box-shadow: none;
- }
- .navbar-nav .open .dropdown-menu > li > a,
- .navbar-nav .open .dropdown-menu .dropdown-header {
- padding: 5px 15px 5px 25px;
- }
- .navbar-nav .open .dropdown-menu > li > a {
- line-height: 20px;
- }
- .navbar-nav .open .dropdown-menu > li > a:hover,
- .navbar-nav .open .dropdown-menu > li > a:focus {
- background-image: none;
- }
-}
-@media (min-width: 768px) {
- .navbar-nav {
- float: left;
- margin: 0;
- }
- .navbar-nav > li {
- float: left;
- }
- .navbar-nav > li > a {
- padding-top: 15px;
- padding-bottom: 15px;
- }
-}
-.navbar-form {
- margin-left: -15px;
- margin-right: -15px;
- padding: 10px 15px;
- border-top: 1px solid transparent;
- border-bottom: 1px solid transparent;
- box-shadow: inset 0 1px 0 rgba(255,255,255,0.1), 0 1px 0 rgba(255,255,255,0.1);
- margin-top: 8px;
- margin-bottom: 8px;
-}
-@media (max-width: 767px) {
- .navbar-form .form-group {
- margin-bottom: 5px;
- }
- .navbar-form .form-group:last-child {
- margin-bottom: 0;
- }
-}
-@media (min-width: 768px) {
- .navbar-form {
- width: auto;
- border: 0;
- margin-left: 0;
- margin-right: 0;
- padding-top: 0;
- padding-bottom: 0;
- box-shadow: none;
- }
-}
-.navbar-nav > li > .dropdown-menu {
- margin-top: 0;
- border-top-right-radius: 0;
- border-top-left-radius: 0;
-}
-.navbar-fixed-bottom .navbar-nav > li > .dropdown-menu {
- margin-bottom: 0;
- border-top-right-radius: 4px;
- border-top-left-radius: 4px;
- border-bottom-right-radius: 0;
- border-bottom-left-radius: 0;
-}
-.navbar-btn {
- margin-top: 8px;
- margin-bottom: 8px;
-}
-.navbar-btn.btn-sm {
- margin-top: 10px;
- margin-bottom: 10px;
-}
-.navbar-btn.btn-xs {
- margin-top: 14px;
- margin-bottom: 14px;
-}
-.navbar-text {
- margin-top: 15px;
- margin-bottom: 15px;
-}
-@media (min-width: 768px) {
- .navbar-text {
- float: left;
- margin-left: 15px;
- margin-right: 15px;
- }
-}
-@media (min-width: 768px) {
- .navbar-left {
- float: left !important;
- }
- .navbar-right {
- float: right !important;
- margin-right: -15px;
- }
- .navbar-right ~ .navbar-right {
- margin-right: 0;
- }
-}
-.navbar-default {
- background-color: #f8f8f8;
- border-color: #e8e8e8;
-}
-.navbar-default .navbar-brand {
- color: #777;
-}
-.navbar-default .navbar-brand:hover,
-.navbar-default .navbar-brand:focus {
- color: #6b6b6b;
- background-color: transparent;
-}
-.navbar-default .navbar-text {
- color: #777;
-}
-.navbar-default .navbar-nav > li > a {
- color: #777;
-}
-.navbar-default .navbar-nav > li > a:hover,
-.navbar-default .navbar-nav > li > a:focus {
- color: #333;
- background-color: transparent;
-}
-.navbar-default .navbar-nav > .active > a,
-.navbar-default .navbar-nav > .active > a:hover,
-.navbar-default .navbar-nav > .active > a:focus {
- color: #555;
- background-color: #e8e8e8;
-}
-.navbar-default .navbar-nav > .disabled > a,
-.navbar-default .navbar-nav > .disabled > a:hover,
-.navbar-default .navbar-nav > .disabled > a:focus {
- color: #ccc;
- background-color: transparent;
-}
-.navbar-default .navbar-toggle {
- border-color: #ddd;
-}
-.navbar-default .navbar-toggle:hover,
-.navbar-default .navbar-toggle:focus {
- background-color: #ddd;
-}
-.navbar-default .navbar-toggle .icon-bar {
- background-color: #888;
-}
-.navbar-default .navbar-collapse,
-.navbar-default .navbar-form {
- border-color: #e8e8e8;
-}
-.navbar-default .navbar-nav > .open > a,
-.navbar-default .navbar-nav > .open > a:hover,
-.navbar-default .navbar-nav > .open > a:focus {
- background-color: #e8e8e8;
- color: #555;
-}
-@media (max-width: 767px) {
- .navbar-default .navbar-nav .open .dropdown-menu > li > a {
- color: #777;
- }
- .navbar-default .navbar-nav .open .dropdown-menu > li > a:hover,
- .navbar-default .navbar-nav .open .dropdown-menu > li > a:focus {
- color: #333;
- background-color: transparent;
- }
- .navbar-default .navbar-nav .open .dropdown-menu > .active > a,
- .navbar-default .navbar-nav .open .dropdown-menu > .active > a:hover,
- .navbar-default .navbar-nav .open .dropdown-menu > .active > a:focus {
- color: #555;
- background-color: #e8e8e8;
- }
- .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a,
- .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:hover,
- .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:focus {
- color: #ccc;
- background-color: transparent;
- }
-}
-.navbar-default .navbar-link {
- color: #777;
-}
-.navbar-default .navbar-link:hover {
- color: #333;
-}
-.navbar-default .btn-link {
- color: #777;
-}
-.navbar-default .btn-link:hover,
-.navbar-default .btn-link:focus {
- color: #333;
-}
-.navbar-default .btn-link[disabled]:hover,
-fieldset[disabled] .navbar-default .btn-link:hover,
-.navbar-default .btn-link[disabled]:focus,
-fieldset[disabled] .navbar-default .btn-link:focus {
- color: #ccc;
-}
-.navbar-inverse {
- background-color: #222;
- border-color: #1f1f1f;
-}
-.navbar-inverse .navbar-brand {
- color: #8b8b8b;
-}
-.navbar-inverse .navbar-brand:hover,
-.navbar-inverse .navbar-brand:focus {
- color: #fff;
- background-color: transparent;
-}
-.navbar-inverse .navbar-text {
- color: #8b8b8b;
-}
-.navbar-inverse .navbar-nav > li > a {
- color: #8b8b8b;
-}
-.navbar-inverse .navbar-nav > li > a:hover,
-.navbar-inverse .navbar-nav > li > a:focus {
- color: #fff;
- background-color: transparent;
-}
-.navbar-inverse .navbar-nav > .active > a,
-.navbar-inverse .navbar-nav > .active > a:hover,
-.navbar-inverse .navbar-nav > .active > a:focus {
- color: #fff;
- background-color: #1f1f1f;
-}
-.navbar-inverse .navbar-nav > .disabled > a,
-.navbar-inverse .navbar-nav > .disabled > a:hover,
-.navbar-inverse .navbar-nav > .disabled > a:focus {
- color: #444;
- background-color: transparent;
-}
-.navbar-inverse .navbar-toggle {
- border-color: #333;
-}
-.navbar-inverse .navbar-toggle:hover,
-.navbar-inverse .navbar-toggle:focus {
- background-color: #333;
-}
-.navbar-inverse .navbar-toggle .icon-bar {
- background-color: #fff;
-}
-.navbar-inverse .navbar-collapse,
-.navbar-inverse .navbar-form {
- border-color: #202020;
-}
-.navbar-inverse .navbar-nav > .open > a,
-.navbar-inverse .navbar-nav > .open > a:hover,
-.navbar-inverse .navbar-nav > .open > a:focus {
- background-color: #1f1f1f;
- color: #fff;
-}
-@media (max-width: 767px) {
- .navbar-inverse .navbar-nav .open .dropdown-menu > .dropdown-header {
- border-color: #1f1f1f;
- }
- .navbar-inverse .navbar-nav .open .dropdown-menu .divider {
- background-color: #1f1f1f;
- }
- .navbar-inverse .navbar-nav .open .dropdown-menu > li > a {
- color: #8b8b8b;
- }
- .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:hover,
- .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:focus {
- color: #fff;
- background-color: transparent;
- }
- .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a,
- .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:hover,
- .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:focus {
- color: #fff;
- background-color: #1f1f1f;
- }
- .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a,
- .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:hover,
- .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:focus {
- color: #444;
- background-color: transparent;
- }
-}
-.navbar-inverse .navbar-link {
- color: #8b8b8b;
-}
-.navbar-inverse .navbar-link:hover {
- color: #fff;
-}
-.navbar-inverse .btn-link {
- color: #8b8b8b;
-}
-.navbar-inverse .btn-link:hover,
-.navbar-inverse .btn-link:focus {
- color: #fff;
-}
-.navbar-inverse .btn-link[disabled]:hover,
-fieldset[disabled] .navbar-inverse .btn-link:hover,
-.navbar-inverse .btn-link[disabled]:focus,
-fieldset[disabled] .navbar-inverse .btn-link:focus {
- color: #444;
-}
-.label {
- display: inline;
- padding: 0.2em 0.6em 0.3em;
- font-size: 75%;
- font-weight: bold;
- line-height: 1;
- color: #fff;
- text-align: center;
- white-space: nowrap;
- vertical-align: baseline;
- border-radius: 0.25em;
-}
-a.label:hover,
-a.label:focus {
- color: #fff;
- text-decoration: none;
- cursor: pointer;
-}
-.label:empty {
- display: none;
-}
-.btn .label {
- position: relative;
- top: -1px;
-}
-.label-default {
- background-color: #777;
-}
-.label-default[href]:hover,
-.label-default[href]:focus {
- background-color: #6b6b6b;
-}
-.label-primary {
- background-color: #088cff;
-}
-.label-primary[href]:hover,
-.label-primary[href]:focus {
- background-color: #007eed;
-}
-.label-success {
- background-color: #22bd89;
-}
-.label-success[href]:hover,
-.label-success[href]:focus {
- background-color: #1faa7b;
-}
-.label-info {
- background-color: #5bdeff;
-}
-.label-info[href]:hover,
-.label-info[href]:focus {
- background-color: #38d7ff;
-}
-.label-warning {
- background-color: #cd8737;
-}
-.label-warning[href]:hover,
-.label-warning[href]:focus {
- background-color: #bb7a2f;
-}
-.label-danger {
- background-color: #da2828;
-}
-.label-danger[href]:hover,
-.label-danger[href]:focus {
- background-color: #c62222;
-}
-.badge {
- display: inline-block;
- min-width: 10px;
- padding: 3px 7px;
- font-size: 12px;
- font-weight: bold;
- color: #fff;
- line-height: 1;
- vertical-align: baseline;
- white-space: nowrap;
- text-align: center;
- background-color: #777;
- border-radius: 10px;
-}
-.badge:empty {
- display: none;
-}
-.btn .badge {
- position: relative;
- top: -1px;
-}
-.btn-xs .badge,
-.btn-group-xs > .btn .badge {
- top: 0;
- padding: 1px 5px;
-}
-a.badge:hover,
-a.badge:focus {
- color: #fff;
- text-decoration: none;
- cursor: pointer;
-}
-.list-group-item.active > .badge,
-.nav-pills > .active > a > .badge {
- color: #d5dfe2;
- background-color: #fff;
-}
-.list-group-item > .badge {
- float: right;
-}
-.list-group-item > .badge + .badge {
- margin-right: 5px;
-}
-.nav-pills > li > a > .badge {
- margin-left: 3px;
-}
-.jumbotron {
- padding: 30px 15px;
- margin-bottom: 30px;
- color: inherit;
- background-color: #003b4a;
-}
-.jumbotron h1,
-.jumbotron .h1 {
- color: inherit;
-}
-.jumbotron p {
- margin-bottom: 15px;
- font-size: 21px;
- font-weight: 200;
-}
-.jumbotron > hr {
- border-top-color: #003543;
-}
-.container .jumbotron,
-.container-fluid .jumbotron {
- border-radius: 6px;
-}
-.jumbotron .container {
- max-width: 100%;
-}
-@media screen and (min-width: 768px) {
- .jumbotron {
- padding: 48px 0;
- }
- .container .jumbotron,
- .container-fluid .jumbotron {
- padding-left: 60px;
- padding-right: 60px;
- }
- .jumbotron h1,
- .jumbotron .h1 {
- font-size: 63px;
- }
-}
-.thumbnail {
- display: block;
- padding: 4px;
- margin-bottom: 20px;
- line-height: 1.428571429;
- background-color: #fff;
- border: 1px solid #ddd;
- border-radius: 4px;
- -webkit-transition: border 0.2s ease-in-out;
- transition: border 0.2s ease-in-out;
-}
-.thumbnail > img,
-.thumbnail a > img {
- margin-left: auto;
- margin-right: auto;
-}
-a.thumbnail:hover,
-a.thumbnail:focus,
-a.thumbnail.active {
- border-color: #d5dfe2;
-}
-.thumbnail .caption {
- padding: 9px;
- color: #333;
-}
-.alert {
- padding: 15px;
- margin-bottom: 20px;
- border: 1px solid transparent;
- border-radius: 4px;
-}
-.alert h4 {
- margin-top: 0;
- color: inherit;
-}
-.alert .alert-link {
- font-weight: bold;
-}
-.alert > p,
-.alert > ul {
- margin-bottom: 0;
-}
-.alert > p + p {
- margin-top: 5px;
-}
-.alert-dismissable,
-.alert-dismissible {
- padding-right: 35px;
-}
-.alert-dismissable .close,
-.alert-dismissible .close {
- position: relative;
- top: -2px;
- right: -21px;
- color: inherit;
-}
-.alert-success {
- background-color: #73c990;
- border-color: #7acc96;
- color: #fff;
-}
-.alert-success hr {
- border-top-color: #6ec78d;
-}
-.alert-success .alert-link {
- color: #e6e6e6;
-}
-.alert-info {
- background-color: #6494ed;
- border-color: #6c99ee;
- color: #fff;
-}
-.alert-info hr {
- border-top-color: #5c8eec;
-}
-.alert-info .alert-link {
- color: #e6e6e6;
-}
-.alert-warning {
- background-color: #e2c08d;
- border-color: #e3c393;
- color: #fff;
-}
-.alert-warning hr {
- border-top-color: #dfbb84;
-}
-.alert-warning .alert-link {
- color: #e6e6e6;
-}
-.alert-danger {
- background-color: #ff6347;
- border-color: #ff6b50;
- color: #fff;
-}
-.alert-danger hr {
- border-top-color: #ff5d3f;
-}
-.alert-danger .alert-link {
- color: #e6e6e6;
-}
-.progress {
- overflow: hidden;
- height: 20px;
- margin-bottom: 20px;
- background-color: #f5f5f5;
- border-radius: 4px;
- box-shadow: inset 0 1px 2px rgba(0,0,0,0.1);
-}
-.progress-bar {
- float: left;
- width: 0%;
- height: 100%;
- font-size: 12px;
- line-height: 20px;
- color: #fff;
- text-align: center;
- background-color: #088cff;
- box-shadow: inset 0 -1px 0 rgba(0,0,0,0.15);
- -webkit-transition: width 0.6s ease;
- transition: width 0.6s ease;
-}
-.progress-striped .progress-bar,
-.progress-bar-striped {
- background-image: -webkit-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);
- background-image: linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);
- background-size: 40px 40px;
-}
-.progress.active .progress-bar,
-.progress-bar.active {
- -webkit-animation: progress-bar-stripes 2s linear infinite;
- animation: progress-bar-stripes 2s linear infinite;
-}
-.progress-bar-success {
- background-color: #22bd89;
-}
-.progress-striped .progress-bar-success {
- background-image: -webkit-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);
- background-image: linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);
-}
-.progress-bar-info {
- background-color: #5bdeff;
-}
-.progress-striped .progress-bar-info {
- background-image: -webkit-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);
- background-image: linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);
-}
-.progress-bar-warning {
- background-color: #cd8737;
-}
-.progress-striped .progress-bar-warning {
- background-image: -webkit-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);
- background-image: linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);
-}
-.progress-bar-danger {
- background-color: #da2828;
-}
-.progress-striped .progress-bar-danger {
- background-image: -webkit-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);
- background-image: linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);
-}
-@-webkit-keyframes progress-bar-stripes {
- from {
- background-position: 40px 0;
- }
- to {
- background-position: 0 0;
- }
-}
-@keyframes progress-bar-stripes {
- from {
- background-position: 40px 0;
- }
- to {
- background-position: 0 0;
- }
-}
-.media {
- margin-top: 15px;
-}
-.media:first-child {
- margin-top: 0;
-}
-.media,
-.media-body {
- zoom: 1;
- overflow: hidden;
-}
-.media-body {
- width: 10000px;
-}
-.media-object {
- display: block;
-}
-.media-right,
-.media > .pull-right {
- padding-left: 10px;
-}
-.media-left,
-.media > .pull-left {
- padding-right: 10px;
-}
-.media-left,
-.media-right,
-.media-body {
- display: table-cell;
- vertical-align: top;
-}
-.media-middle {
- vertical-align: middle;
-}
-.media-bottom {
- vertical-align: bottom;
-}
-.media-heading {
- margin-top: 0;
- margin-bottom: 5px;
-}
-.media-list {
- padding-left: 0;
- list-style: none;
-}
-.list-group {
- margin-bottom: 20px;
- padding-left: 0;
-}
-.list-group-item {
- position: relative;
- display: block;
- padding: 10px 15px;
- margin-bottom: -1px;
- background-color: #fff;
- border: 1px solid #ddd;
-}
-.list-group-item:first-child {
- border-top-right-radius: 4px;
- border-top-left-radius: 4px;
-}
-.list-group-item:last-child {
- margin-bottom: 0;
- border-bottom-right-radius: 4px;
- border-bottom-left-radius: 4px;
-}
-a.list-group-item {
- color: #555;
-}
-a.list-group-item .list-group-item-heading {
- color: #333;
-}
-a.list-group-item:hover,
-a.list-group-item:focus {
- text-decoration: none;
- color: #555;
- background-color: #f5f5f5;
-}
-.list-group-item.disabled,
-.list-group-item.disabled:hover,
-.list-group-item.disabled:focus {
- background-color: #eee;
- color: #777;
- cursor: not-allowed;
-}
-.list-group-item.disabled .list-group-item-heading,
-.list-group-item.disabled:hover .list-group-item-heading,
-.list-group-item.disabled:focus .list-group-item-heading {
- color: inherit;
-}
-.list-group-item.disabled .list-group-item-text,
-.list-group-item.disabled:hover .list-group-item-text,
-.list-group-item.disabled:focus .list-group-item-text {
- color: #777;
-}
-.list-group-item.active,
-.list-group-item.active:hover,
-.list-group-item.active:focus {
- z-index: 2;
- color: #fff;
- background-color: #088cff;
- border-color: #088cff;
-}
-.list-group-item.active .list-group-item-heading,
-.list-group-item.active:hover .list-group-item-heading,
-.list-group-item.active:focus .list-group-item-heading,
-.list-group-item.active .list-group-item-heading > small,
-.list-group-item.active:hover .list-group-item-heading > small,
-.list-group-item.active:focus .list-group-item-heading > small,
-.list-group-item.active .list-group-item-heading > .small,
-.list-group-item.active:hover .list-group-item-heading > .small,
-.list-group-item.active:focus .list-group-item-heading > .small {
- color: inherit;
-}
-.list-group-item.active .list-group-item-text,
-.list-group-item.active:hover .list-group-item-text,
-.list-group-item.active:focus .list-group-item-text {
- color: #6bbaff;
-}
-.list-group-item-success {
- color: #3c763d;
- background-color: #dff0d8;
-}
-a.list-group-item-success {
- color: #3c763d;
-}
-a.list-group-item-success .list-group-item-heading {
- color: inherit;
-}
-a.list-group-item-success:hover,
-a.list-group-item-success:focus {
- color: #3c763d;
- background-color: #d1eac8;
-}
-a.list-group-item-success.active,
-a.list-group-item-success.active:hover,
-a.list-group-item-success.active:focus {
- color: #fff;
- background-color: #3c763d;
- border-color: #3c763d;
-}
-.list-group-item-info {
- color: #31708f;
- background-color: #d9edf7;
-}
-a.list-group-item-info {
- color: #31708f;
-}
-a.list-group-item-info .list-group-item-heading {
- color: inherit;
-}
-a.list-group-item-info:hover,
-a.list-group-item-info:focus {
- color: #31708f;
- background-color: #c6e4f3;
-}
-a.list-group-item-info.active,
-a.list-group-item-info.active:hover,
-a.list-group-item-info.active:focus {
- color: #fff;
- background-color: #31708f;
- border-color: #31708f;
-}
-.list-group-item-warning {
- color: #8a6d3b;
- background-color: #fcf8e3;
-}
-a.list-group-item-warning {
- color: #8a6d3b;
-}
-a.list-group-item-warning .list-group-item-heading {
- color: inherit;
-}
-a.list-group-item-warning:hover,
-a.list-group-item-warning:focus {
- color: #8a6d3b;
- background-color: #faf3cd;
-}
-a.list-group-item-warning.active,
-a.list-group-item-warning.active:hover,
-a.list-group-item-warning.active:focus {
- color: #fff;
- background-color: #8a6d3b;
- border-color: #8a6d3b;
-}
-.list-group-item-danger {
- color: #a94442;
- background-color: #f2dede;
-}
-a.list-group-item-danger {
- color: #a94442;
-}
-a.list-group-item-danger .list-group-item-heading {
- color: inherit;
-}
-a.list-group-item-danger:hover,
-a.list-group-item-danger:focus {
- color: #a94442;
- background-color: #ebcdcd;
-}
-a.list-group-item-danger.active,
-a.list-group-item-danger.active:hover,
-a.list-group-item-danger.active:focus {
- color: #fff;
- background-color: #a94442;
- border-color: #a94442;
-}
-.list-group-item-heading {
- margin-top: 0;
- margin-bottom: 5px;
-}
-.list-group-item-text {
- margin-bottom: 0;
- line-height: 1.3;
-}
-.panel {
- margin-bottom: 20px;
- background-color: #002b36;
- border: 1px solid transparent;
- border-radius: 4px;
- box-shadow: 0 1px 1px rgba(0,0,0,0.05);
-}
-.panel-body {
- padding: 15px;
-}
-.panel-heading {
- padding: 10px 15px;
- border-bottom: 1px solid transparent;
- border-top-right-radius: 3px;
- border-top-left-radius: 3px;
-}
-.panel-heading > .dropdown .dropdown-toggle {
- color: inherit;
-}
-.panel-title {
- margin-top: 0;
- margin-bottom: 0;
- font-size: 16px;
- color: inherit;
-}
-.panel-title > a,
-.panel-title > small,
-.panel-title > .small,
-.panel-title > small > a,
-.panel-title > .small > a {
- color: inherit;
-}
-.panel-footer {
- padding: 10px 15px;
- background-color: #f5f5f5;
- border-top: 1px solid #ddd;
- border-bottom-right-radius: 3px;
- border-bottom-left-radius: 3px;
-}
-.panel > .list-group,
-.panel > .panel-collapse > .list-group {
- margin-bottom: 0;
-}
-.panel > .list-group .list-group-item,
-.panel > .panel-collapse > .list-group .list-group-item {
- border-width: 1px 0;
- border-radius: 0;
-}
-.panel > .list-group:first-child .list-group-item:first-child,
-.panel > .panel-collapse > .list-group:first-child .list-group-item:first-child {
- border-top: 0;
- border-top-right-radius: 3px;
- border-top-left-radius: 3px;
-}
-.panel > .list-group:last-child .list-group-item:last-child,
-.panel > .panel-collapse > .list-group:last-child .list-group-item:last-child {
- border-bottom: 0;
- border-bottom-right-radius: 3px;
- border-bottom-left-radius: 3px;
-}
-.panel-heading + .list-group .list-group-item:first-child {
- border-top-width: 0;
-}
-.list-group + .panel-footer {
- border-top-width: 0;
-}
-.panel > .table,
-.panel > .table-responsive > .table,
-.panel > .panel-collapse > .table {
- margin-bottom: 0;
-}
-.panel > .table caption,
-.panel > .table-responsive > .table caption,
-.panel > .panel-collapse > .table caption {
- padding-left: 15px;
- padding-right: 15px;
-}
-.panel > .table:first-child,
-.panel > .table-responsive:first-child > .table:first-child {
- border-top-right-radius: 3px;
- border-top-left-radius: 3px;
-}
-.panel > .table:first-child > thead:first-child > tr:first-child,
-.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child,
-.panel > .table:first-child > tbody:first-child > tr:first-child,
-.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child {
- border-top-left-radius: 3px;
- border-top-right-radius: 3px;
-}
-.panel > .table:first-child > thead:first-child > tr:first-child td:first-child,
-.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:first-child,
-.panel > .table:first-child > tbody:first-child > tr:first-child td:first-child,
-.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:first-child,
-.panel > .table:first-child > thead:first-child > tr:first-child th:first-child,
-.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:first-child,
-.panel > .table:first-child > tbody:first-child > tr:first-child th:first-child,
-.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:first-child {
- border-top-left-radius: 3px;
-}
-.panel > .table:first-child > thead:first-child > tr:first-child td:last-child,
-.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:last-child,
-.panel > .table:first-child > tbody:first-child > tr:first-child td:last-child,
-.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:last-child,
-.panel > .table:first-child > thead:first-child > tr:first-child th:last-child,
-.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:last-child,
-.panel > .table:first-child > tbody:first-child > tr:first-child th:last-child,
-.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:last-child {
- border-top-right-radius: 3px;
-}
-.panel > .table:last-child,
-.panel > .table-responsive:last-child > .table:last-child {
- border-bottom-right-radius: 3px;
- border-bottom-left-radius: 3px;
-}
-.panel > .table:last-child > tbody:last-child > tr:last-child,
-.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child,
-.panel > .table:last-child > tfoot:last-child > tr:last-child,
-.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child {
- border-bottom-left-radius: 3px;
- border-bottom-right-radius: 3px;
-}
-.panel > .table:last-child > tbody:last-child > tr:last-child td:first-child,
-.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:first-child,
-.panel > .table:last-child > tfoot:last-child > tr:last-child td:first-child,
-.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:first-child,
-.panel > .table:last-child > tbody:last-child > tr:last-child th:first-child,
-.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:first-child,
-.panel > .table:last-child > tfoot:last-child > tr:last-child th:first-child,
-.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:first-child {
- border-bottom-left-radius: 3px;
-}
-.panel > .table:last-child > tbody:last-child > tr:last-child td:last-child,
-.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:last-child,
-.panel > .table:last-child > tfoot:last-child > tr:last-child td:last-child,
-.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:last-child,
-.panel > .table:last-child > tbody:last-child > tr:last-child th:last-child,
-.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:last-child,
-.panel > .table:last-child > tfoot:last-child > tr:last-child th:last-child,
-.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:last-child {
- border-bottom-right-radius: 3px;
-}
-.panel > .panel-body + .table,
-.panel > .panel-body + .table-responsive,
-.panel > .table + .panel-body,
-.panel > .table-responsive + .panel-body {
- border-top: 1px solid #001a20;
-}
-.panel > .table > tbody:first-child > tr:first-child th,
-.panel > .table > tbody:first-child > tr:first-child td {
- border-top: 0;
-}
-.panel > .table-bordered,
-.panel > .table-responsive > .table-bordered {
- border: 0;
-}
-.panel > .table-bordered > thead > tr > th:first-child,
-.panel > .table-responsive > .table-bordered > thead > tr > th:first-child,
-.panel > .table-bordered > tbody > tr > th:first-child,
-.panel > .table-responsive > .table-bordered > tbody > tr > th:first-child,
-.panel > .table-bordered > tfoot > tr > th:first-child,
-.panel > .table-responsive > .table-bordered > tfoot > tr > th:first-child,
-.panel > .table-bordered > thead > tr > td:first-child,
-.panel > .table-responsive > .table-bordered > thead > tr > td:first-child,
-.panel > .table-bordered > tbody > tr > td:first-child,
-.panel > .table-responsive > .table-bordered > tbody > tr > td:first-child,
-.panel > .table-bordered > tfoot > tr > td:first-child,
-.panel > .table-responsive > .table-bordered > tfoot > tr > td:first-child {
- border-left: 0;
-}
-.panel > .table-bordered > thead > tr > th:last-child,
-.panel > .table-responsive > .table-bordered > thead > tr > th:last-child,
-.panel > .table-bordered > tbody > tr > th:last-child,
-.panel > .table-responsive > .table-bordered > tbody > tr > th:last-child,
-.panel > .table-bordered > tfoot > tr > th:last-child,
-.panel > .table-responsive > .table-bordered > tfoot > tr > th:last-child,
-.panel > .table-bordered > thead > tr > td:last-child,
-.panel > .table-responsive > .table-bordered > thead > tr > td:last-child,
-.panel > .table-bordered > tbody > tr > td:last-child,
-.panel > .table-responsive > .table-bordered > tbody > tr > td:last-child,
-.panel > .table-bordered > tfoot > tr > td:last-child,
-.panel > .table-responsive > .table-bordered > tfoot > tr > td:last-child {
- border-right: 0;
-}
-.panel > .table-bordered > thead > tr:first-child > td,
-.panel > .table-responsive > .table-bordered > thead > tr:first-child > td,
-.panel > .table-bordered > tbody > tr:first-child > td,
-.panel > .table-responsive > .table-bordered > tbody > tr:first-child > td,
-.panel > .table-bordered > thead > tr:first-child > th,
-.panel > .table-responsive > .table-bordered > thead > tr:first-child > th,
-.panel > .table-bordered > tbody > tr:first-child > th,
-.panel > .table-responsive > .table-bordered > tbody > tr:first-child > th {
- border-bottom: 0;
-}
-.panel > .table-bordered > tbody > tr:last-child > td,
-.panel > .table-responsive > .table-bordered > tbody > tr:last-child > td,
-.panel > .table-bordered > tfoot > tr:last-child > td,
-.panel > .table-responsive > .table-bordered > tfoot > tr:last-child > td,
-.panel > .table-bordered > tbody > tr:last-child > th,
-.panel > .table-responsive > .table-bordered > tbody > tr:last-child > th,
-.panel > .table-bordered > tfoot > tr:last-child > th,
-.panel > .table-responsive > .table-bordered > tfoot > tr:last-child > th {
- border-bottom: 0;
-}
-.panel > .table-responsive {
- border: 0;
- margin-bottom: 0;
-}
-.panel-group {
- margin-bottom: 20px;
-}
-.panel-group .panel {
- margin-bottom: 0;
- border-radius: 4px;
-}
-.panel-group .panel + .panel {
- margin-top: 5px;
-}
-.panel-group .panel-heading {
- border-bottom: 0;
-}
-.panel-group .panel-heading + .panel-collapse > .panel-body,
-.panel-group .panel-heading + .panel-collapse > .list-group {
- border-top: 1px solid #ddd;
-}
-.panel-group .panel-footer {
- border-top: 0;
-}
-.panel-group .panel-footer + .panel-collapse .panel-body {
- border-bottom: 1px solid #ddd;
-}
-.panel-default {
- border-color: #001a20;
-}
-.panel-default > .panel-heading {
- color: #333;
- background-color: #f5f5f5;
- border-color: #001a20;
-}
-.panel-default > .panel-heading + .panel-collapse > .panel-body {
- border-top-color: #001a20;
-}
-.panel-default > .panel-heading .badge {
- color: #f5f5f5;
- background-color: #333;
-}
-.panel-default > .panel-footer + .panel-collapse > .panel-body {
- border-bottom-color: #001a20;
-}
-.panel-primary {
- border-color: #088cff;
-}
-.panel-primary > .panel-heading {
- color: #fff;
- background-color: #088cff;
- border-color: #088cff;
-}
-.panel-primary > .panel-heading + .panel-collapse > .panel-body {
- border-top-color: #088cff;
-}
-.panel-primary > .panel-heading .badge {
- color: #088cff;
- background-color: #fff;
-}
-.panel-primary > .panel-footer + .panel-collapse > .panel-body {
- border-bottom-color: #088cff;
-}
-.panel-success {
- border-color: #d7eac8;
-}
-.panel-success > .panel-heading {
- color: #3c763d;
- background-color: #dff0d8;
- border-color: #d7eac8;
-}
-.panel-success > .panel-heading + .panel-collapse > .panel-body {
- border-top-color: #d7eac8;
-}
-.panel-success > .panel-heading .badge {
- color: #dff0d8;
- background-color: #3c763d;
-}
-.panel-success > .panel-footer + .panel-collapse > .panel-body {
- border-bottom-color: #d7eac8;
-}
-.panel-info {
- border-color: #bee9f1;
-}
-.panel-info > .panel-heading {
- color: #31708f;
- background-color: #d9edf7;
- border-color: #bee9f1;
-}
-.panel-info > .panel-heading + .panel-collapse > .panel-body {
- border-top-color: #bee9f1;
-}
-.panel-info > .panel-heading .badge {
- color: #d9edf7;
- background-color: #31708f;
-}
-.panel-info > .panel-footer + .panel-collapse > .panel-body {
- border-bottom-color: #bee9f1;
-}
-.panel-warning {
- border-color: #faeccd;
-}
-.panel-warning > .panel-heading {
- color: #8a6d3b;
- background-color: #fcf8e3;
- border-color: #faeccd;
-}
-.panel-warning > .panel-heading + .panel-collapse > .panel-body {
- border-top-color: #faeccd;
-}
-.panel-warning > .panel-heading .badge {
- color: #fcf8e3;
- background-color: #8a6d3b;
-}
-.panel-warning > .panel-footer + .panel-collapse > .panel-body {
- border-bottom-color: #faeccd;
-}
-.panel-danger {
- border-color: #ebcdd2;
-}
-.panel-danger > .panel-heading {
- color: #a94442;
- background-color: #f2dede;
- border-color: #ebcdd2;
-}
-.panel-danger > .panel-heading + .panel-collapse > .panel-body {
- border-top-color: #ebcdd2;
-}
-.panel-danger > .panel-heading .badge {
- color: #f2dede;
- background-color: #a94442;
-}
-.panel-danger > .panel-footer + .panel-collapse > .panel-body {
- border-bottom-color: #ebcdd2;
-}
-.embed-responsive {
- position: relative;
- display: block;
- height: 0;
- padding: 0;
- overflow: hidden;
-}
-.embed-responsive .embed-responsive-item,
-.embed-responsive iframe,
-.embed-responsive embed,
-.embed-responsive object,
-.embed-responsive video {
- position: absolute;
- top: 0;
- left: 0;
- bottom: 0;
- height: 100%;
- width: 100%;
- border: 0;
-}
-.embed-responsive-16by9 {
- padding-bottom: 56.25%;
-}
-.embed-responsive-4by3 {
- padding-bottom: 75%;
-}
-.well {
- min-height: 20px;
- padding: 19px;
- margin-bottom: 20px;
- background-color: #f5f5f5;
- border: 1px solid #e4e4e4;
- border-radius: 4px;
- box-shadow: inset 0 1px 1px rgba(0,0,0,0.05);
-}
-.well blockquote {
- border-color: #ddd;
- border-color: rgba(0,0,0,0.15);
-}
-.well-lg {
- padding: 24px;
- border-radius: 6px;
-}
-.well-sm {
- padding: 9px;
- border-radius: 3px;
-}
-.close {
- float: right;
- font-size: 21px;
- font-weight: bold;
- line-height: 1;
- color: #000;
- text-shadow: 0 1px 0 #fff;
- opacity: 0.2;
- filter: alpha(opacity=20);
-}
-.close:hover,
-.close:focus {
- color: #000;
- text-decoration: none;
- cursor: pointer;
- opacity: 0.5;
- filter: alpha(opacity=50);
-}
-button.close {
- padding: 0;
- cursor: pointer;
- background: transparent;
- border: 0;
- -webkit-appearance: none;
-}
-.modal-open {
- overflow: hidden;
-}
-.modal {
- display: none;
- overflow: hidden;
- position: fixed;
- top: 0;
- right: 0;
- bottom: 0;
- left: 0;
- z-index: 1050;
- -webkit-overflow-scrolling: touch;
- outline: 0;
-}
-.modal.fade .modal-dialog {
- -webkit-transform: translate(0, -25%);
- -ms-transform: translate(0, -25%);
- transform: translate(0, -25%);
- -webkit-transition: -webkit-transform 0.3s ease-out;
- transition: transform 0.3s ease-out;
-}
-.modal.in .modal-dialog {
- -webkit-transform: translate(0, 0);
- -ms-transform: translate(0, 0);
- transform: translate(0, 0);
-}
-.modal-open .modal {
- overflow-x: hidden;
- overflow-y: auto;
-}
-.modal-dialog {
- position: relative;
- width: auto;
- margin: 10px;
-}
-.modal-content {
- position: relative;
- background-color: #002b36;
- border: 1px solid #999;
- border: 1px solid #001a20;
- border-radius: 6px;
- box-shadow: 0 3px 9px rgba(0,0,0,0.5);
- background-clip: padding-box;
- outline: 0;
-}
-.modal-backdrop {
- position: fixed;
- top: 0;
- right: 0;
- bottom: 0;
- left: 0;
- z-index: 1040;
- background-color: #000;
-}
-.modal-backdrop.fade {
- opacity: 0;
- filter: alpha(opacity=0);
-}
-.modal-backdrop.in {
- opacity: 0.5;
- filter: alpha(opacity=50);
-}
-.modal-header {
- padding: 15px;
- border-bottom: 1px solid #001a20;
- min-height: 16.428571429px;
-}
-.modal-header .close {
- margin-top: -2px;
-}
-.modal-title {
- margin: 0;
- line-height: 1.428571429;
-}
-.modal-body {
- position: relative;
- padding: 15px;
-}
-.modal-footer {
- padding: 15px;
- text-align: right;
- border-top: 1px solid #001a20;
-}
-.modal-footer .btn + .btn {
- margin-left: 5px;
- margin-bottom: 0;
-}
-.modal-footer .btn-group .btn + .btn {
- margin-left: -1px;
-}
-.modal-footer .btn-block + .btn-block {
- margin-left: 0;
-}
-.modal-scrollbar-measure {
- position: absolute;
- top: -9999px;
- width: 50px;
- height: 50px;
- overflow: scroll;
-}
-@media (min-width: 768px) {
- .modal-dialog {
- width: 600px;
- margin: 30px auto;
- }
- .modal-content {
- box-shadow: 0 5px 15px rgba(0,0,0,0.5);
- }
- .modal-sm {
- width: 300px;
- }
-}
-@media (min-width: 992px) {
- .modal-lg {
- width: 900px;
- }
-}
-.tooltip {
- position: absolute;
- z-index: 1070;
- display: block;
- font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
- font-size: 12px;
- font-weight: normal;
- line-height: 1.4;
- opacity: 0;
- filter: alpha(opacity=0);
-}
-.tooltip.in {
- opacity: 0.9;
- filter: alpha(opacity=90);
-}
-.tooltip.top {
- margin-top: -3px;
- padding: 5px 0;
-}
-.tooltip.right {
- margin-left: 3px;
- padding: 0 5px;
-}
-.tooltip.bottom {
- margin-top: 3px;
- padding: 5px 0;
-}
-.tooltip.left {
- margin-left: -3px;
- padding: 0 5px;
-}
-.tooltip-inner {
- max-width: 200px;
- padding: 3px 8px;
- color: #fff;
- text-align: center;
- text-decoration: none;
- background-color: #000;
- border-radius: 4px;
-}
-.tooltip-arrow {
- position: absolute;
- width: 0;
- height: 0;
- border-color: transparent;
- border-style: solid;
-}
-.tooltip.top .tooltip-arrow {
- bottom: 0;
- left: 50%;
- margin-left: -5px;
- border-width: 5px 5px 0;
- border-top-color: #000;
-}
-.tooltip.top-left .tooltip-arrow {
- bottom: 0;
- right: 5px;
- margin-bottom: -5px;
- border-width: 5px 5px 0;
- border-top-color: #000;
-}
-.tooltip.top-right .tooltip-arrow {
- bottom: 0;
- left: 5px;
- margin-bottom: -5px;
- border-width: 5px 5px 0;
- border-top-color: #000;
-}
-.tooltip.right .tooltip-arrow {
- top: 50%;
- left: 0;
- margin-top: -5px;
- border-width: 5px 5px 5px 0;
- border-right-color: #000;
-}
-.tooltip.left .tooltip-arrow {
- top: 50%;
- right: 0;
- margin-top: -5px;
- border-width: 5px 0 5px 5px;
- border-left-color: #000;
-}
-.tooltip.bottom .tooltip-arrow {
- top: 0;
- left: 50%;
- margin-left: -5px;
- border-width: 0 5px 5px;
- border-bottom-color: #000;
-}
-.tooltip.bottom-left .tooltip-arrow {
- top: 0;
- right: 5px;
- margin-top: -5px;
- border-width: 0 5px 5px;
- border-bottom-color: #000;
-}
-.tooltip.bottom-right .tooltip-arrow {
- top: 0;
- left: 5px;
- margin-top: -5px;
- border-width: 0 5px 5px;
- border-bottom-color: #000;
-}
-.popover {
- position: absolute;
- top: 0;
- left: 0;
- z-index: 1060;
- display: none;
- max-width: 276px;
- padding: 1px;
- font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
- font-size: 14px;
- font-weight: normal;
- line-height: 1.428571429;
- text-align: left;
- background-color: #fff;
- background-clip: padding-box;
- border: 1px solid #ccc;
- border: 1px solid rgba(0,0,0,0.2);
- border-radius: 6px;
- box-shadow: 0 5px 10px rgba(0,0,0,0.2);
- white-space: normal;
-}
-.popover.top {
- margin-top: -10px;
-}
-.popover.right {
- margin-left: 10px;
-}
-.popover.bottom {
- margin-top: 10px;
-}
-.popover.left {
- margin-left: -10px;
-}
-.popover-title {
- margin: 0;
- padding: 8px 14px;
- font-size: 14px;
- background-color: #f7f7f7;
- border-bottom: 1px solid #ebebeb;
- border-radius: 5px 5px 0 0;
-}
-.popover-content {
- padding: 9px 14px;
-}
-.popover > .arrow,
-.popover > .arrow:after {
- position: absolute;
- display: block;
- width: 0;
- height: 0;
- border-color: transparent;
- border-style: solid;
-}
-.popover > .arrow {
- border-width: 11px;
-}
-.popover > .arrow:after {
- border-width: 10px;
- content: "";
-}
-.popover.top > .arrow {
- left: 50%;
- margin-left: -11px;
- border-bottom-width: 0;
- border-top-color: #a3a3a3;
- border-top-color: rgba(0,0,0,0.25);
- bottom: -11px;
-}
-.popover.top > .arrow:after {
- content: " ";
- bottom: 1px;
- margin-left: -10px;
- border-bottom-width: 0;
- border-top-color: #fff;
-}
-.popover.right > .arrow {
- top: 50%;
- left: -11px;
- margin-top: -11px;
- border-left-width: 0;
- border-right-color: #a3a3a3;
- border-right-color: rgba(0,0,0,0.25);
-}
-.popover.right > .arrow:after {
- content: " ";
- left: 1px;
- bottom: -10px;
- border-left-width: 0;
- border-right-color: #fff;
-}
-.popover.bottom > .arrow {
- left: 50%;
- margin-left: -11px;
- border-top-width: 0;
- border-bottom-color: #a3a3a3;
- border-bottom-color: rgba(0,0,0,0.25);
- top: -11px;
-}
-.popover.bottom > .arrow:after {
- content: " ";
- top: 1px;
- margin-left: -10px;
- border-top-width: 0;
- border-bottom-color: #fff;
-}
-.popover.left > .arrow {
- top: 50%;
- right: -11px;
- margin-top: -11px;
- border-right-width: 0;
- border-left-color: #a3a3a3;
- border-left-color: rgba(0,0,0,0.25);
-}
-.popover.left > .arrow:after {
- content: " ";
- right: 1px;
- border-right-width: 0;
- border-left-color: #fff;
- bottom: -10px;
-}
-.alert {
- margin: 5px 0;
-}
-input.form-control::-webkit-input-placeholder,
-textarea.form-control::-webkit-input-placeholder,
-input.inline-form-control::-webkit-input-placeholder {
- color: #99b2b8;
-}
-input.form-control:-moz-placeholder,
-textarea.form-control:-moz-placeholder,
-input.inline-form-control:-moz-placeholder {
- color: #99b2b8;
-}
-input.form-control::-moz-placeholder,
-textarea.form-control::-moz-placeholder,
-input.inline-form-control::-moz-placeholder {
- color: #99b2b8;
-}
-input.form-control:-ms-input-placeholder,
-textarea.form-control:-ms-input-placeholder,
-input.inline-form-control:-ms-input-placeholder {
- color: #99b2b8;
-}
-.inline-form-control {
- width: auto;
- display: inline-block;
-}
-.btn.btn-default {
- border-style: solid;
- border-width: 1px;
- color: #99b2b8;
- background-color: #004355;
- border-color: #001a20;
-}
-.btn.btn-default:hover,
-.btn.btn-default:focus,
-.btn.btn-default.focus,
-.btn.btn-default:active,
-.btn.btn-default.active,
-.open > .dropdown-toggle.btn.btn-default {
- color: #a3babf;
- background-color: #006480;
- border-color: #004959;
-}
-.btn.btn-default:active,
-.btn.btn-default.active,
-.open > .dropdown-toggle.btn.btn-default {
- background-image: none;
-}
-.btn.btn-default.disabled,
-.btn.btn-default[disabled],
-fieldset[disabled] .btn.btn-default,
-.btn.btn-default.disabled:hover,
-.btn.btn-default[disabled]:hover,
-fieldset[disabled] .btn.btn-default:hover,
-.btn.btn-default.disabled:focus,
-.btn.btn-default[disabled]:focus,
-fieldset[disabled] .btn.btn-default:focus,
-.btn.btn-default.disabled.focus,
-.btn.btn-default[disabled].focus,
-fieldset[disabled] .btn.btn-default.focus,
-.btn.btn-default.disabled:active,
-.btn.btn-default[disabled]:active,
-fieldset[disabled] .btn.btn-default:active,
-.btn.btn-default.disabled.active,
-.btn.btn-default[disabled].active,
-fieldset[disabled] .btn.btn-default.active {
- background-color: #004355;
- border-color: #001a20;
-}
-.btn.btn-default .badge {
- color: #004355;
- background-color: #99b2b8;
-}
-.btn.btn-primary {
- color: #fff;
- background-color: #088cff;
- border-color: #0086fa;
-}
-.btn.btn-primary:hover,
-.btn.btn-primary:focus,
-.btn.btn-primary.focus,
-.btn.btn-primary:active,
-.btn.btn-primary.active,
-.open > .dropdown-toggle.btn.btn-primary {
- color: #e6e6e6;
- background-color: #007eed;
- border-color: #1a95ff;
-}
-.btn.btn-primary:active,
-.btn.btn-primary.active,
-.open > .dropdown-toggle.btn.btn-primary {
- background-image: none;
-}
-.btn.btn-primary.disabled,
-.btn.btn-primary[disabled],
-fieldset[disabled] .btn.btn-primary,
-.btn.btn-primary.disabled:hover,
-.btn.btn-primary[disabled]:hover,
-fieldset[disabled] .btn.btn-primary:hover,
-.btn.btn-primary.disabled:focus,
-.btn.btn-primary[disabled]:focus,
-fieldset[disabled] .btn.btn-primary:focus,
-.btn.btn-primary.disabled.focus,
-.btn.btn-primary[disabled].focus,
-fieldset[disabled] .btn.btn-primary.focus,
-.btn.btn-primary.disabled:active,
-.btn.btn-primary[disabled]:active,
-fieldset[disabled] .btn.btn-primary:active,
-.btn.btn-primary.disabled.active,
-.btn.btn-primary[disabled].active,
-fieldset[disabled] .btn.btn-primary.active {
- background-color: #088cff;
- border-color: #0086fa;
-}
-.btn.btn-primary .badge {
- color: #088cff;
- background-color: #fff;
-}
-.btn.btn-info {
- color: #fff;
- background-color: #5bdeff;
- border-color: #4adbff;
-}
-.btn.btn-info:hover,
-.btn.btn-info:focus,
-.btn.btn-info.focus,
-.btn.btn-info:active,
-.btn.btn-info.active,
-.open > .dropdown-toggle.btn.btn-info {
- color: #e6e6e6;
- background-color: #38d7ff;
- border-color: #23d3ff;
-}
-.btn.btn-info:active,
-.btn.btn-info.active,
-.open > .dropdown-toggle.btn.btn-info {
- background-image: none;
-}
-.btn.btn-info.disabled,
-.btn.btn-info[disabled],
-fieldset[disabled] .btn.btn-info,
-.btn.btn-info.disabled:hover,
-.btn.btn-info[disabled]:hover,
-fieldset[disabled] .btn.btn-info:hover,
-.btn.btn-info.disabled:focus,
-.btn.btn-info[disabled]:focus,
-fieldset[disabled] .btn.btn-info:focus,
-.btn.btn-info.disabled.focus,
-.btn.btn-info[disabled].focus,
-fieldset[disabled] .btn.btn-info.focus,
-.btn.btn-info.disabled:active,
-.btn.btn-info[disabled]:active,
-fieldset[disabled] .btn.btn-info:active,
-.btn.btn-info.disabled.active,
-.btn.btn-info[disabled].active,
-fieldset[disabled] .btn.btn-info.active {
- background-color: #5bdeff;
- border-color: #4adbff;
-}
-.btn.btn-info .badge {
- color: #5bdeff;
- background-color: #fff;
-}
-.btn.btn-success {
- color: #fff;
- background-color: #22bd89;
- border-color: #20b482;
-}
-.btn.btn-success:hover,
-.btn.btn-success:focus,
-.btn.btn-success.focus,
-.btn.btn-success:active,
-.btn.btn-success.active,
-.open > .dropdown-toggle.btn.btn-success {
- color: #fff;
- background-color: #26d59b;
- border-color: #25d298;
-}
-.btn.btn-success:active,
-.btn.btn-success.active,
-.open > .dropdown-toggle.btn.btn-success {
- background-image: none;
-}
-.btn.btn-success.disabled,
-.btn.btn-success[disabled],
-fieldset[disabled] .btn.btn-success,
-.btn.btn-success.disabled:hover,
-.btn.btn-success[disabled]:hover,
-fieldset[disabled] .btn.btn-success:hover,
-.btn.btn-success.disabled:focus,
-.btn.btn-success[disabled]:focus,
-fieldset[disabled] .btn.btn-success:focus,
-.btn.btn-success.disabled.focus,
-.btn.btn-success[disabled].focus,
-fieldset[disabled] .btn.btn-success.focus,
-.btn.btn-success.disabled:active,
-.btn.btn-success[disabled]:active,
-fieldset[disabled] .btn.btn-success:active,
-.btn.btn-success.disabled.active,
-.btn.btn-success[disabled].active,
-fieldset[disabled] .btn.btn-success.active {
- background-color: #22bd89;
- border-color: #20b482;
-}
-.btn.btn-success .badge {
- color: #22bd89;
- background-color: #fff;
-}
-.btn.btn-danger {
- color: #fff;
- background-color: #da2828;
- border-color: #d12424;
-}
-.btn.btn-danger:hover,
-.btn.btn-danger:focus,
-.btn.btn-danger.focus,
-.btn.btn-danger:active,
-.btn.btn-danger.active,
-.open > .dropdown-toggle.btn.btn-danger {
- color: #e6e6e6;
- background-color: #c62222;
- border-color: #dd3838;
-}
-.btn.btn-danger:active,
-.btn.btn-danger.active,
-.open > .dropdown-toggle.btn.btn-danger {
- background-image: none;
-}
-.btn.btn-danger.disabled,
-.btn.btn-danger[disabled],
-fieldset[disabled] .btn.btn-danger,
-.btn.btn-danger.disabled:hover,
-.btn.btn-danger[disabled]:hover,
-fieldset[disabled] .btn.btn-danger:hover,
-.btn.btn-danger.disabled:focus,
-.btn.btn-danger[disabled]:focus,
-fieldset[disabled] .btn.btn-danger:focus,
-.btn.btn-danger.disabled.focus,
-.btn.btn-danger[disabled].focus,
-fieldset[disabled] .btn.btn-danger.focus,
-.btn.btn-danger.disabled:active,
-.btn.btn-danger[disabled]:active,
-fieldset[disabled] .btn.btn-danger:active,
-.btn.btn-danger.disabled.active,
-.btn.btn-danger[disabled].active,
-fieldset[disabled] .btn.btn-danger.active {
- background-color: #da2828;
- border-color: #d12424;
-}
-.btn.btn-danger .badge {
- color: #da2828;
- background-color: #fff;
-}
-.btn.btn-warning {
- color: #fff;
- background-color: #cd8737;
- border-color: #c68031;
-}
-.btn.btn-warning:hover,
-.btn.btn-warning:focus,
-.btn.btn-warning.focus,
-.btn.btn-warning:active,
-.btn.btn-warning.active,
-.open > .dropdown-toggle.btn.btn-warning {
- color: #e6e6e6;
- background-color: #bb7a2f;
- border-color: #d18f45;
-}
-.btn.btn-warning:active,
-.btn.btn-warning.active,
-.open > .dropdown-toggle.btn.btn-warning {
- background-image: none;
-}
-.btn.btn-warning.disabled,
-.btn.btn-warning[disabled],
-fieldset[disabled] .btn.btn-warning,
-.btn.btn-warning.disabled:hover,
-.btn.btn-warning[disabled]:hover,
-fieldset[disabled] .btn.btn-warning:hover,
-.btn.btn-warning.disabled:focus,
-.btn.btn-warning[disabled]:focus,
-fieldset[disabled] .btn.btn-warning:focus,
-.btn.btn-warning.disabled.focus,
-.btn.btn-warning[disabled].focus,
-fieldset[disabled] .btn.btn-warning.focus,
-.btn.btn-warning.disabled:active,
-.btn.btn-warning[disabled]:active,
-fieldset[disabled] .btn.btn-warning:active,
-.btn.btn-warning.disabled.active,
-.btn.btn-warning[disabled].active,
-fieldset[disabled] .btn.btn-warning.active {
- background-color: #cd8737;
- border-color: #c68031;
-}
-.btn.btn-warning .badge {
- color: #cd8737;
- background-color: #fff;
-}
-textarea.form-control,
-.ace_editor {
- border-radius: 4px;
-}
-.ace_editor {
- border: solid 1px #001a20;
- box-shadow: inset 0 1px 1px rgba(0,0,0,0.075);
- font-family: 'Lucida Grande';
-}
-.ace_editor.ace_focus {
- border-color: #52dcff;
- outline: 0;
- box-shadow: inset 0 1px 1px rgba(0,0,0,0.075), 0 0 8px rgba(82,220,255,0.6);
-}
-.modal-content {
- background-color: $bg;
-}
-.jumbotron {
- padding: 48px 10px;
-}
-html {
- overflow: hidden;
- height: 100%;
-}
-body {
- height: 100%;
- overflow: auto;
- font-family: "Lato", sans-serif;
- color: #99b2b8;
- background-color: #001f27;
-}
-label {
- font-family: "Lato", sans-serif;
- color: #99b2b8;
-}
-h1,
-h2,
-h3,
-h4,
-h5 {
- color: #d5dfe2;
- margin: 0;
-}
-textarea {
- resize: vertical;
-}
-hr {
- border-color: #001a20;
-}
diff --git a/src/browser/shared/styles/bootstrap.styl b/src/browser/shared/styles/bootstrap.styl
deleted file mode 100644
index 9ae767fb..00000000
--- a/src/browser/shared/styles/bootstrap.styl
+++ /dev/null
@@ -1,57 +0,0 @@
-// Override vars and mixins
-@import '_vars'
-@import 'mixins/*'
-
-// Core variables and mixins
-@import '../../../../node_modules/bootstrap-styl/bootstrap/variables'
-@import '../../../../node_modules/bootstrap-styl/bootstrap/mixins'
-
-// Utilities
-@import '../../../../node_modules/bootstrap-styl/bootstrap/utilities'
-@import '../../../../node_modules/bootstrap-styl/bootstrap/responsive-utilities'
-
-// Reset and dependencies
-@import '../../../../node_modules/bootstrap-styl/bootstrap/normalize'
-@import '../../../../node_modules/bootstrap-styl/bootstrap/print'
-
-// Core CSS
-@import '../../../../node_modules/bootstrap-styl/bootstrap/scaffolding'
-@import '../../../../node_modules/bootstrap-styl/bootstrap/type'
-// @import '../../../../node_modules/bootstrap-styl/bootstrap/code'
-@import '../../../../node_modules/bootstrap-styl/bootstrap/grid'
-@import '../../../../node_modules/bootstrap-styl/bootstrap/tables'
-@import '../../../../node_modules/bootstrap-styl/bootstrap/forms'
-@import '../../../../node_modules/bootstrap-styl/bootstrap/buttons'
-
-// Components
-@import '../../../../node_modules/bootstrap-styl/bootstrap/component-animations'
-@import '../../../../node_modules/bootstrap-styl/bootstrap/dropdowns'
-@import '../../../../node_modules/bootstrap-styl/bootstrap/button-groups'
-@import '../../../../node_modules/bootstrap-styl/bootstrap/input-groups'
-@import '../../../../node_modules/bootstrap-styl/bootstrap/navs'
-@import '../../../../node_modules/bootstrap-styl/bootstrap/navbar'
-// @import '../../../../node_modules/bootstrap-styl/bootstrap/breadcrumbs'
-// @import '../../../../node_modules/bootstrap-styl/bootstrap/pagination'
-// @import '../../../../node_modules/bootstrap-styl/bootstrap/pager'
-@import '../../../../node_modules/bootstrap-styl/bootstrap/labels'
-@import '../../../../node_modules/bootstrap-styl/bootstrap/badges'
-@import '../../../../node_modules/bootstrap-styl/bootstrap/jumbotron'
-@import '../../../../node_modules/bootstrap-styl/bootstrap/thumbnails'
-@import '../../../../node_modules/bootstrap-styl/bootstrap/alerts'
-@import '../../../../node_modules/bootstrap-styl/bootstrap/progress-bars'
-@import '../../../../node_modules/bootstrap-styl/bootstrap/media'
-@import '../../../../node_modules/bootstrap-styl/bootstrap/list-group'
-@import '../../../../node_modules/bootstrap-styl/bootstrap/panels'
-@import '../../../../node_modules/bootstrap-styl/bootstrap/responsive-embed'
-@import '../../../../node_modules/bootstrap-styl/bootstrap/wells'
-@import '../../../../node_modules/bootstrap-styl/bootstrap/close'
-
-// Components w/ JavaScript
-@import '../../../../node_modules/bootstrap-styl/bootstrap/modals'
-@import '../../../../node_modules/bootstrap-styl/bootstrap/tooltip'
-@import '../../../../node_modules/bootstrap-styl/bootstrap/popovers'
-// @import '../../../../node_modules/bootstrap-styl/bootstrap/carousel'
-
-// Overrides
-@import '_shared'
-@import '_index'
diff --git a/src/browser/shared/styles/mixins/btn-color.styl b/src/browser/shared/styles/mixins/btn-color.styl
deleted file mode 100644
index fa5e3053..00000000
--- a/src/browser/shared/styles/mixins/btn-color.styl
+++ /dev/null
@@ -1,35 +0,0 @@
-btn-color($color, $background, $border)
- color $color
- background-color $background
- border-color $border
-
- &:hover,
- &:focus,
- &.focus,
- &:active,
- &.active,
- .open > .dropdown-toggle&
- color dark($background) ? lighten($color, 10%) : darken($color, 10%)
- background-color dark($background) ? lighten($background, 10%) : darken($background, 10%)
- border-color dark($border) ? lighten($border, 12%) : darken($border, 12%)
-
- &:active,
- &.active,
- .open > .dropdown-toggle&
- background-image none
-
- &.disabled,
- &[disabled],
- fieldset[disabled] &
- &,
- &:hover,
- &:focus,
- &.focus,
- &:active,
- &.active
- background-color $background
- border-color $border
-
- .badge
- color $background
- background-color $color
diff --git a/src/browser/shared/styles/mixins/control-glow.styl b/src/browser/shared/styles/mixins/control-glow.styl
deleted file mode 100644
index 0d981d94..00000000
--- a/src/browser/shared/styles/mixins/control-glow.styl
+++ /dev/null
@@ -1,5 +0,0 @@
-controlGlow($color = $input-border-focus)
- $color-rgba = rgba(red($color), green($color), blue($color), .6)
- border-color $color
- outline 0
- box-shadow inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 8px $color-rgba
diff --git a/src/main.js b/src/main.js
deleted file mode 100644
index 8b76a5b4..00000000
--- a/src/main.js
+++ /dev/null
@@ -1,247 +0,0 @@
-var app = require('app') // Module to control application life.
-var BrowserWindow = require('browser-window') // Module to create native browser window.
-
-// Report crashes to our server.
-require('crash-reporter').start()
-
-// Keep a global reference of the window object, if you don't, the window will
-// be closed automatically when the javascript object is GCed.
-var mainWindow = null
-
-// app.on('window-all-closed', function () {
-// if (process.platform !== 'darwin') app.quit()
-// })
-
-var clipboard = require('clipboard')
-var Tray = require('tray')
-var notifier = require('node-notifier')
-
-var appIcon = null
-
-app.on('ready', function () {
- appIcon = new Tray(__dirname + '/tray-icon.png')
- appIcon.setToolTip('This is my application.')
- appIcon.on('clicked', function () {
- if (mainWindow == null) {
- makeNewMainWindow()
- }
- mainWindow.show()
- })
-
- makeNewMainWindow()
-
- var globalShortcut = require('global-shortcut')
-
- var popUpWindow = new BrowserWindow({
- width: 600,
- height: 400,
- show: false,
- frame: false,
- 'web-preferences': {
- 'overlay-scrollbars': true,
- 'skip-taskbar': true
- }
- })
-
- popUpWindow.loadUrl('file://' + __dirname + '/browser/popup/index.html')
-
- app.on('activate-with-no-open-windows', function () {
- if (mainWindow == null) {
- makeNewMainWindow()
- }
- mainWindow.show()
- })
-
- popUpWindow.on('blur', function () {
- popUpWindow.hide()
- })
- popUpWindow.setVisibleOnAllWorkspaces(true)
-
- var hidePopUp = function () {
- if (fromMain) {
-
- } else {
- mainWindow ? mainWindow.hide() : null
- Menu.sendActionToFirstResponder('hide:')
- }
-
- popUpWindow.hide()
- }
-
- var ipc = require('ipc')
- ipc.on('hidePopUp', function () {
- hidePopUp()
- })
-
- ipc.on('writeCode', function (e, code) {
- clipboard.writeText(code)
- notifier.notify({
- title: 'Write on clipboard!',
- message: 'Ready to paste',
- wait: false
- }, function (err, res) {
-
- })
- hidePopUp()
- })
-
- var fromMain
- // Register a 'ctrl+x' shortcut listener.
- globalShortcut.register('ctrl+tab+shift', function () {
- if (popUpWindow.isVisible()) {
- hidePopUp()
- return
- }
- fromMain = mainWindow ? mainWindow.isFocused() : false
- popUpWindow.show()
- })
-
- // MENU
- var Menu = require('menu')
- var template = [
- {
- label: 'Electron',
- submenu: [
- {
- label: 'About Electron',
- selector: 'orderFrontStandardAboutPanel:'
- },
- {
- type: 'separator'
- },
- {
- label: 'Services',
- submenu: []
- },
- {
- type: 'separator'
- },
- {
- label: 'Hide Electron',
- accelerator: 'Command+H',
- selector: 'hide:'
- },
- {
- label: 'Hide Others',
- accelerator: 'Command+Shift+H',
- selector: 'hideOtherApplications:'
- },
- {
- label: 'Show All',
- selector: 'unhideAllApplications:'
- },
- {
- type: 'separator'
- },
- {
- label: 'Quit',
- accelerator: 'Command+Q',
- click: function () { app.quit() }
- }
- ]
- },
- {
- label: 'Edit',
- submenu: [
- {
- label: 'Undo',
- accelerator: 'Command+Z',
- selector: 'undo:'
- },
- {
- label: 'Redo',
- accelerator: 'Shift+Command+Z',
- selector: 'redo:'
- },
- {
- type: 'separator'
- },
- {
- label: 'Cut',
- accelerator: 'Command+X',
- selector: 'cut:'
- },
- {
- label: 'Copy',
- accelerator: 'Command+C',
- selector: 'copy:'
- },
- {
- label: 'Paste',
- accelerator: 'Command+V',
- selector: 'paste:'
- },
- {
- label: 'Select All',
- accelerator: 'Command+A',
- selector: 'selectAll:'
- }
- ]
- },
- {
- label: 'View',
- submenu: [
- {
- label: 'Reload',
- accelerator: 'Command+R',
- click: function () { BrowserWindow.getFocusedWindow().reloadIgnoringCache() }
- },
- {
- label: 'Toggle DevTools',
- accelerator: 'Alt+Command+I',
- click: function () { BrowserWindow.getFocusedWindow().toggleDevTools() }
- }
- ]
- },
- {
- label: 'Window',
- submenu: [
- {
- label: 'Minimize',
- accelerator: 'Command+M',
- selector: 'performMiniaturize:'
- },
- {
- label: 'Close',
- accelerator: 'Command+W',
- selector: 'performClose:'
- },
- {
- type: 'separator'
- },
- {
- label: 'Bring All to Front',
- selector: 'arrangeInFront:'
- }
- ]
- },
- {
- label: 'Help',
- submenu: []
- }
- ]
-
- var menu = Menu.buildFromTemplate(template)
-
- Menu.setApplicationMenu(menu)
-
- function makeNewMainWindow () {
- console.log('new Window!')
- mainWindow = new BrowserWindow({
- width: 920,
- height: 640,
- 'web-preferences': {
- 'overlay-scrollbars': true
- }
- })
-
- mainWindow.loadUrl('file://' + __dirname + '/browser/main/index.html')
-
- mainWindow.on('closed', function () {
- console.log('main closed')
- mainWindow = null
- app.dock.hide()
- })
- app.dock.show()
- }
-})
diff --git a/src/package.json b/src/package.json
deleted file mode 100644
index da0dd095..00000000
--- a/src/package.json
+++ /dev/null
@@ -1,32 +0,0 @@
-{
- "name": "codexen-app",
- "version": "0.2.0",
- "description": "CodeXen App",
- "main": "main.js",
- "scripts": {
- "test": "echo \"Error: no test specified\" && exit 1"
- },
- "keywords": [
- "codexen",
- "snippet",
- "template",
- "task",
- "runner",
- "remote",
- "automator",
- "code",
- "storage",
- "short code"
- ],
- "author": "Dick Choi (http://kazup.co)",
- "license": "No License",
- "bugs": {
- "url": "https://github.com/Rokt33r/codexen-app/issues"
- },
- "homepage": "https://codexen.github.io",
- "dependencies": {
- "dotenv": "^1.1.0",
- "robotjs": "^0.1.2",
- "node-notifier": "^4.2.1"
- },
-}
diff --git a/src/tray-icon.png b/src/tray-icon.png
deleted file mode 100644
index fde41991..00000000
Binary files a/src/tray-icon.png and /dev/null differ
diff --git a/src/tray-icon@2x.png b/src/tray-icon@2x.png
deleted file mode 100644
index c615b960..00000000
Binary files a/src/tray-icon@2x.png and /dev/null differ
diff --git a/src/tray-icon@4x.png b/src/tray-icon@4x.png
deleted file mode 100644
index 25c9f14b..00000000
Binary files a/src/tray-icon@4x.png and /dev/null differ
diff --git a/tray-icon.png b/tray-icon.png
new file mode 100644
index 00000000..aba8e7d5
Binary files /dev/null and b/tray-icon.png differ
diff --git a/tray-icon@2x.png b/tray-icon@2x.png
new file mode 100644
index 00000000..eff01fc0
Binary files /dev/null and b/tray-icon@2x.png differ
diff --git a/tray-icon@4x.png b/tray-icon@4x.png
new file mode 100644
index 00000000..c3aba762
Binary files /dev/null and b/tray-icon@4x.png differ
diff --git a/update-log.md b/update-log.md
new file mode 100644
index 00000000..f92b0cc7
--- /dev/null
+++ b/update-log.md
@@ -0,0 +1,18 @@
+※ 最近の方が上に来るように書きためていく
+
+# Update Log
+
+## v0.1.2 (2015/7/3)
+
+- 利用規約・プライベートポリシーの追加
+
+## v0.1.1 (2015/6/25)
+
+- バーグ改善
+- Recipe機能追加
+
+## v0.1.0 (2015/6/17)
+
+- Web/OS X app release
+
+## v0.2.0 (2015/7/...)
diff --git a/webpack.config.js b/webpack.config.js
new file mode 100644
index 00000000..b113c964
--- /dev/null
+++ b/webpack.config.js
@@ -0,0 +1,39 @@
+module.exports = {
+ entry: {
+ main: './browser/main/index.jsx',
+ 'main-style': './browser/main/style.js'
+ },
+ output: {
+ filename: '[name].js',
+ publicPath: 'http://localhost:8090/assets'
+ },
+ devtool: '#inline-source-map',
+ module: {
+ loaders: [
+ {
+ test: /\.jsx$/,
+ loader: 'jsx-loader?insertPragma=React.DOM&harmony'
+ },
+ {
+ test: /\.styl$/,
+ loader: 'style-loader!css-loader!stylus-loader'
+ },
+ {
+ test: /\.css$/,
+ loader: 'style-loader!css-loader'
+ }
+ ]
+ },
+ externals: {
+ 'react': 'React',
+ 'react/addons': 'React',
+ 'react-router': 'ReactRouter',
+ 'ace': 'ace',
+ 'reflux': 'Reflux',
+ 'moment': 'moment',
+ 'markdown-it': 'markdownit'
+ },
+ resolve: {
+ extensions: ['', '.js', '.jsx']
+ }
+}