diff --git a/Gemfile b/Gemfile index 11f42b7..205e6bb 100644 --- a/Gemfile +++ b/Gemfile @@ -3,8 +3,12 @@ source 'https://rubygems.org' # Bundle edge Rails instead: gem 'rails', github: 'rails/rails' gem 'rails', '4.1.8' -# Use sqlite3 as the database for Active Record -gem 'sqlite3' +# Use sqlite3 as the database for Active Record (Just Development) +gem 'sqlite3', group: [:development] +# Use Postgres for Production +gem 'pg' +# Use rails_12factor +gem 'rails_12factor', group: :production # Use SCSS for stylesheets gem 'sass-rails', '~> 4.0.3' # Use Uglifier as compressor for JavaScript assets diff --git a/Gemfile.lock b/Gemfile.lock index 57e0ffc..0932289 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -53,6 +53,7 @@ GEM mime-types (2.4.3) minitest (5.5.1) multi_json (1.11.0) + pg (0.17.1) rack (1.5.2) rack-test (0.6.3) rack (>= 1.0) @@ -66,6 +67,11 @@ GEM bundler (>= 1.3.0, < 2.0) railties (= 4.1.8) sprockets-rails (~> 2.0) + rails_12factor (0.0.3) + rails_serve_static_assets + rails_stdout_logging + rails_serve_static_assets (0.0.4) + rails_stdout_logging (0.0.3) railties (4.1.8) actionpack (= 4.1.8) activesupport (= 4.1.8) @@ -113,7 +119,9 @@ DEPENDENCIES coffee-rails (~> 4.0.0) jbuilder (~> 2.0) jquery-rails + pg rails (= 4.1.8) + rails_12factor sass-rails (~> 4.0.3) sdoc (~> 0.4.0) spring diff --git a/README.rdoc b/README.rdoc index dd4e97e..0d46be1 100644 --- a/README.rdoc +++ b/README.rdoc @@ -1,28 +1,21 @@ == README -This README would normally document whatever steps are necessary to get the -application up and running. +Get back to what makes you happy. Give yourself the feedback you need to put your time where it matters most, and pull away from what’s dragging you down. -Things you may want to cover: +== Scope +Minimum Viable Product: +A light & fun way to mark down how you plan to fill your day, then in the evening quickly rate how much you enjoyed or disliked each thing you did. -* Ruby version +== Features: -* System dependencies +In the morning, add list items: As in the jQuery project “ListEasy”, the user can create a list of what they plan to do each day (by adding to the html form element with added jquery function ). -* Configuration +In the evening, rate list items: From a drop down menu (code to be found), rate with a percentage +number how much you enjoyed or disliked that project. + +== In a later version: +Features: -* Database creation +By the end of 7 days, get back a digest of what you enjoyed or disliked the most. To one’s surprise you may not be putting your time towards what you like the most! Time to reprioritize! -* Database initialization - -* How to run the test suite - -* Services (job queues, cache servers, search engines, etc.) - -* Deployment instructions - -* ... - - -Please feel free to use a different markup language if you do not plan to run -rake doc:app. +Also, it’d be cool if the app knew how to assign an emoji face to the rating reports, so that the feeling was more approachable than like a grade! diff --git a/app/assets/images/blue2light.jpg b/app/assets/images/blue2light.jpg new file mode 100644 index 0000000..5db2e98 Binary files /dev/null and b/app/assets/images/blue2light.jpg differ diff --git a/app/assets/images/bluedandelion.jpg b/app/assets/images/bluedandelion.jpg new file mode 100644 index 0000000..ed7cf57 Binary files /dev/null and b/app/assets/images/bluedandelion.jpg differ diff --git a/app/assets/images/bluestmood.jpg b/app/assets/images/bluestmood.jpg new file mode 100644 index 0000000..4500154 Binary files /dev/null and b/app/assets/images/bluestmood.jpg differ diff --git a/app/assets/images/class3v2.jpg b/app/assets/images/class3v2.jpg new file mode 100644 index 0000000..6512338 Binary files /dev/null and b/app/assets/images/class3v2.jpg differ diff --git a/app/assets/images/favicon.ico b/app/assets/images/favicon.ico new file mode 100755 index 0000000..02f7707 Binary files /dev/null and b/app/assets/images/favicon.ico differ diff --git a/app/assets/images/icons.png b/app/assets/images/icons.png new file mode 100644 index 0000000..3524b2e Binary files /dev/null and b/app/assets/images/icons.png differ diff --git a/app/assets/images/icons.svg b/app/assets/images/icons.svg new file mode 100644 index 0000000..03e90b4 --- /dev/null +++ b/app/assets/images/icons.svg @@ -0,0 +1,3 @@ + + + r r diff --git a/app/assets/images/logo2.svg b/app/assets/images/logo2.svg new file mode 100755 index 0000000..ac3144c --- /dev/null +++ b/app/assets/images/logo2.svg @@ -0,0 +1,20 @@ + + + + + + + + + + + + +r + diff --git a/app/assets/images/logo_solo_2.svg b/app/assets/images/logo_solo_2.svg new file mode 100644 index 0000000..ac3144c --- /dev/null +++ b/app/assets/images/logo_solo_2.svg @@ -0,0 +1,20 @@ + + + + + + + + + + + + +r + diff --git a/app/assets/images/logo_solo_3.svg b/app/assets/images/logo_solo_3.svg new file mode 100644 index 0000000..2fcaf5f --- /dev/null +++ b/app/assets/images/logo_solo_3.svg @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + +r + + + + + + + diff --git a/app/assets/images/logo_solo_4.svg b/app/assets/images/logo_solo_4.svg new file mode 100644 index 0000000..1daef74 --- /dev/null +++ b/app/assets/images/logo_solo_4.svg @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + +r + + + + + + + diff --git a/app/assets/images/rethinklogo1.gif b/app/assets/images/rethinklogo1.gif new file mode 100644 index 0000000..3c81c98 Binary files /dev/null and b/app/assets/images/rethinklogo1.gif differ diff --git a/app/assets/images/rethinklogo2.gif b/app/assets/images/rethinklogo2.gif new file mode 100644 index 0000000..dae2ae6 Binary files /dev/null and b/app/assets/images/rethinklogo2.gif differ diff --git a/app/assets/images/solo_logos1.svg b/app/assets/images/solo_logos1.svg new file mode 100755 index 0000000..ba156a9 --- /dev/null +++ b/app/assets/images/solo_logos1.svg @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + +r + diff --git a/app/assets/images/solo_logos_GRAY-01.svg b/app/assets/images/solo_logos_GRAY-01.svg new file mode 100755 index 0000000..8ac5f39 --- /dev/null +++ b/app/assets/images/solo_logos_GRAY-01.svg @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + +r + diff --git a/app/assets/images/solo_logos_STRIPEOJ-01.svg b/app/assets/images/solo_logos_STRIPEOJ-01.svg new file mode 100755 index 0000000..aa60321 --- /dev/null +++ b/app/assets/images/solo_logos_STRIPEOJ-01.svg @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/assets/images/sparkler.jpg b/app/assets/images/sparkler.jpg new file mode 100755 index 0000000..79e116b Binary files /dev/null and b/app/assets/images/sparkler.jpg differ diff --git a/app/assets/images/star-half.png b/app/assets/images/star-half.png new file mode 100755 index 0000000..3c19e90 Binary files /dev/null and b/app/assets/images/star-half.png differ diff --git a/app/assets/images/star-off.png b/app/assets/images/star-off.png new file mode 100755 index 0000000..956fa7c Binary files /dev/null and b/app/assets/images/star-off.png differ diff --git a/app/assets/images/star-on.png b/app/assets/images/star-on.png new file mode 100755 index 0000000..975fe7f Binary files /dev/null and b/app/assets/images/star-on.png differ diff --git a/app/assets/javascripts/jquery.raty.js b/app/assets/javascripts/jquery.raty.js new file mode 100755 index 0000000..c583651 --- /dev/null +++ b/app/assets/javascripts/jquery.raty.js @@ -0,0 +1,760 @@ +/*! + * jQuery Raty - A Star Rating Plugin + * + * The MIT License + * + * @author : Washington Botelho + * @doc : http://wbotelhos.com/raty + * @version : 2.7.0 + * + */ + +; +(function($) { + 'use strict'; + + var methods = { + init: function(options) { + return this.each(function() { + this.self = $(this); + + methods.destroy.call(this.self); + + this.opt = $.extend(true, {}, $.fn.raty.defaults, options); + + methods._adjustCallback.call(this); + methods._adjustNumber.call(this); + methods._adjustHints.call(this); + + this.opt.score = methods._adjustedScore.call(this, this.opt.score); + + if (this.opt.starType !== 'img') { + methods._adjustStarType.call(this); + } + + methods._adjustPath.call(this); + methods._createStars.call(this); + + if (this.opt.cancel) { + methods._createCancel.call(this); + } + + if (this.opt.precision) { + methods._adjustPrecision.call(this); + } + + methods._createScore.call(this); + methods._apply.call(this, this.opt.score); + methods._setTitle.call(this, this.opt.score); + methods._target.call(this, this.opt.score); + + if (this.opt.readOnly) { + methods._lock.call(this); + } else { + this.style.cursor = 'pointer'; + + methods._binds.call(this); + } + }); + }, + + _adjustCallback: function() { + var options = ['number', 'readOnly', 'score', 'scoreName', 'target']; + + for (var i = 0; i < options.length; i++) { + if (typeof this.opt[options[i]] === 'function') { + this.opt[options[i]] = this.opt[options[i]].call(this); + } + } + }, + + _adjustedScore: function(score) { + if (!score) { + return score; + } + + return methods._between(score, 0, this.opt.number); + }, + + _adjustHints: function() { + if (!this.opt.hints) { + this.opt.hints = []; + } + + if (!this.opt.halfShow && !this.opt.half) { + return; + } + + var steps = this.opt.precision ? 10 : 2; + + for (var i = 0; i < this.opt.number; i++) { + var group = this.opt.hints[i]; + + if (Object.prototype.toString.call(group) !== '[object Array]') { + group = [group]; + } + + this.opt.hints[i] = []; + + for (var j = 0; j < steps; j++) { + var + hint = group[j], + last = group[group.length - 1]; + + if (last === undefined) { + last = null; + } + + this.opt.hints[i][j] = hint === undefined ? last : hint; + } + } + }, + + _adjustNumber: function() { + this.opt.number = methods._between(this.opt.number, 1, this.opt.numberMax); + }, + + _adjustPath: function() { + this.opt.path = this.opt.path || ''; + + if (this.opt.path && this.opt.path.charAt(this.opt.path.length - 1) !== '/') { + this.opt.path += '/'; + } + }, + + _adjustPrecision: function() { + this.opt.half = true; + }, + + _adjustStarType: function() { + var replaces = ['cancelOff', 'cancelOn', 'starHalf', 'starOff', 'starOn']; + + this.opt.path = ''; + + for (var i = 0; i < replaces.length; i++) { + this.opt[replaces[i]] = this.opt[replaces[i]].replace('.', '-'); + } + }, + + _apply: function(score) { + methods._fill.call(this, score); + + if (score) { + if (score > 0) { + this.score.val(score); + } + + methods._roundStars.call(this, score); + } + }, + + _between: function(value, min, max) { + return Math.min(Math.max(parseFloat(value), min), max); + }, + + _binds: function() { + if (this.cancel) { + methods._bindOverCancel.call(this); + methods._bindClickCancel.call(this); + methods._bindOutCancel.call(this); + } + + methods._bindOver.call(this); + methods._bindClick.call(this); + methods._bindOut.call(this); + }, + + _bindClick: function() { + var that = this; + + that.stars.on('click.raty', function(evt) { + var + execute = true, + score = (that.opt.half || that.opt.precision) ? that.self.data('score') : (this.alt || $(this).data('alt')); + + if (that.opt.click) { + execute = that.opt.click.call(that, +score, evt); + } + + if (execute || execute === undefined) { + if (that.opt.half && !that.opt.precision) { + score = methods._roundHalfScore.call(that, score); + } + + methods._apply.call(that, score); + } + }); + }, + + _bindClickCancel: function() { + var that = this; + + that.cancel.on('click.raty', function(evt) { + that.score.removeAttr('value'); + + if (that.opt.click) { + that.opt.click.call(that, null, evt); + } + }); + }, + + _bindOut: function() { + var that = this; + + that.self.on('mouseleave.raty', function(evt) { + var score = +that.score.val() || undefined; + + methods._apply.call(that, score); + methods._target.call(that, score, evt); + methods._resetTitle.call(that); + + if (that.opt.mouseout) { + that.opt.mouseout.call(that, score, evt); + } + }); + }, + + _bindOutCancel: function() { + var that = this; + + that.cancel.on('mouseleave.raty', function(evt) { + var icon = that.opt.cancelOff; + + if (that.opt.starType !== 'img') { + icon = that.opt.cancelClass + ' ' + icon; + } + + methods._setIcon.call(that, this, icon); + + if (that.opt.mouseout) { + var score = +that.score.val() || undefined; + + that.opt.mouseout.call(that, score, evt); + } + }); + }, + + _bindOver: function() { + var that = this, + action = that.opt.half ? 'mousemove.raty' : 'mouseover.raty'; + + that.stars.on(action, function(evt) { + var score = methods._getScoreByPosition.call(that, evt, this); + + methods._fill.call(that, score); + + if (that.opt.half) { + methods._roundStars.call(that, score, evt); + methods._setTitle.call(that, score, evt); + + that.self.data('score', score); + } + + methods._target.call(that, score, evt); + + if (that.opt.mouseover) { + that.opt.mouseover.call(that, score, evt); + } + }); + }, + + _bindOverCancel: function() { + var that = this; + + that.cancel.on('mouseover.raty', function(evt) { + var + starOff = that.opt.path + that.opt.starOff, + icon = that.opt.cancelOn; + + if (that.opt.starType === 'img') { + that.stars.attr('src', starOff); + } else { + icon = that.opt.cancelClass + ' ' + icon; + + that.stars.attr('class', starOff); + } + + methods._setIcon.call(that, this, icon); + methods._target.call(that, null, evt); + + if (that.opt.mouseover) { + that.opt.mouseover.call(that, null); + } + }); + }, + + _buildScoreField: function() { + return $('', { name: this.opt.scoreName, type: 'hidden' }).appendTo(this); + }, + + _createCancel: function() { + var icon = this.opt.path + this.opt.cancelOff, + cancel = $('<' + this.opt.starType + ' />', { title: this.opt.cancelHint, 'class': this.opt.cancelClass }); + + if (this.opt.starType === 'img') { + cancel.attr({ src: icon, alt: 'x' }); + } else { + // TODO: use $.data + cancel.attr('data-alt', 'x').addClass(icon); + } + + if (this.opt.cancelPlace === 'left') { + this.self.prepend(' ').prepend(cancel); + } else { + this.self.append(' ').append(cancel); + } + + this.cancel = cancel; + }, + + _createScore: function() { + var score = $(this.opt.targetScore); + + this.score = score.length ? score : methods._buildScoreField.call(this); + }, + + _createStars: function() { + for (var i = 1; i <= this.opt.number; i++) { + var + name = methods._nameForIndex.call(this, i), + attrs = { alt: i, src: this.opt.path + this.opt[name] }; + + if (this.opt.starType !== 'img') { + attrs = { 'data-alt': i, 'class': attrs.src }; // TODO: use $.data. + } + + attrs.title = methods._getHint.call(this, i); + + $('<' + this.opt.starType + ' />', attrs).appendTo(this); + + if (this.opt.space) { + this.self.append(i < this.opt.number ? ' ' : ''); + } + } + + this.stars = this.self.children(this.opt.starType); + }, + + _error: function(message) { + $(this).text(message); + + $.error(message); + }, + + _fill: function(score) { + var hash = 0; + + for (var i = 1; i <= this.stars.length; i++) { + var + icon, + star = this.stars[i - 1], + turnOn = methods._turnOn.call(this, i, score); + + if (this.opt.iconRange && this.opt.iconRange.length > hash) { + var irange = this.opt.iconRange[hash]; + + icon = methods._getRangeIcon.call(this, irange, turnOn); + + if (i <= irange.range) { + methods._setIcon.call(this, star, icon); + } + + if (i === irange.range) { + hash++; + } + } else { + icon = this.opt[turnOn ? 'starOn' : 'starOff']; + + methods._setIcon.call(this, star, icon); + } + } + }, + + _getFirstDecimal: function(number) { + var + decimal = number.toString().split('.')[1], + result = 0; + + if (decimal) { + result = parseInt(decimal.charAt(0), 10); + + if (decimal.slice(1, 5) === '9999') { + result++; + } + } + + return result; + }, + + _getRangeIcon: function(irange, turnOn) { + return turnOn ? irange.on || this.opt.starOn : irange.off || this.opt.starOff; + }, + + _getScoreByPosition: function(evt, icon) { + var score = parseInt(icon.alt || icon.getAttribute('data-alt'), 10); + + if (this.opt.half) { + var + size = methods._getWidth.call(this), + percent = parseFloat((evt.pageX - $(icon).offset().left) / size); + + score = score - 1 + percent; + } + + return score; + }, + + _getHint: function(score, evt) { + if (score !== 0 && !score) { + return this.opt.noRatedMsg; + } + + var + decimal = methods._getFirstDecimal.call(this, score), + integer = Math.ceil(score), + group = this.opt.hints[(integer || 1) - 1], + hint = group, + set = !evt || this.move; + + if (this.opt.precision) { + if (set) { + decimal = decimal === 0 ? 9 : decimal - 1; + } + + hint = group[decimal]; + } else if (this.opt.halfShow || this.opt.half) { + decimal = set && decimal === 0 ? 1 : decimal > 5 ? 1 : 0; + + hint = group[decimal]; + } + + return hint === '' ? '' : hint || score; + }, + + _getWidth: function() { + var width = this.stars[0].width || parseFloat(this.stars.eq(0).css('font-size')); + + if (!width) { + methods._error.call(this, 'Could not get the icon width!'); + } + + return width; + }, + + _lock: function() { + var hint = methods._getHint.call(this, this.score.val()); + + this.style.cursor = ''; + this.title = hint; + + this.score.prop('readonly', true); + this.stars.prop('title', hint); + + if (this.cancel) { + this.cancel.hide(); + } + + this.self.data('readonly', true); + }, + + _nameForIndex: function(i) { + return this.opt.score && this.opt.score >= i ? 'starOn' : 'starOff'; + }, + + _resetTitle: function(star) { + for (var i = 0; i < this.opt.number; i++) { + this.stars[i].title = methods._getHint.call(this, i + 1); + } + }, + + _roundHalfScore: function(score) { + var integer = parseInt(score, 10), + decimal = methods._getFirstDecimal.call(this, score); + + if (decimal !== 0) { + decimal = decimal > 5 ? 1 : 0.5; + } + + return integer + decimal; + }, + + _roundStars: function(score, evt) { + var + decimal = (score % 1).toFixed(2), + name ; + + if (evt || this.move) { + name = decimal > 0.5 ? 'starOn' : 'starHalf'; + } else if (decimal > this.opt.round.down) { // Up: [x.76 .. x.99] + name = 'starOn'; + + if (this.opt.halfShow && decimal < this.opt.round.up) { // Half: [x.26 .. x.75] + name = 'starHalf'; + } else if (decimal < this.opt.round.full) { // Down: [x.00 .. x.5] + name = 'starOff'; + } + } + + if (name) { + var + icon = this.opt[name], + star = this.stars[Math.ceil(score) - 1]; + + methods._setIcon.call(this, star, icon); + } // Full down: [x.00 .. x.25] + }, + + _setIcon: function(star, icon) { + star[this.opt.starType === 'img' ? 'src' : 'className'] = this.opt.path + icon; + }, + + _setTarget: function(target, score) { + if (score) { + score = this.opt.targetFormat.toString().replace('{score}', score); + } + + if (target.is(':input')) { + target.val(score); + } else { + target.html(score); + } + }, + + _setTitle: function(score, evt) { + if (score) { + var + integer = parseInt(Math.ceil(score), 10), + star = this.stars[integer - 1]; + + star.title = methods._getHint.call(this, score, evt); + } + }, + + _target: function(score, evt) { + if (this.opt.target) { + var target = $(this.opt.target); + + if (!target.length) { + methods._error.call(this, 'Target selector invalid or missing!'); + } + + var mouseover = evt && evt.type === 'mouseover'; + + if (score === undefined) { + score = this.opt.targetText; + } else if (score === null) { + score = mouseover ? this.opt.cancelHint : this.opt.targetText; + } else { + if (this.opt.targetType === 'hint') { + score = methods._getHint.call(this, score, evt); + } else if (this.opt.precision) { + score = parseFloat(score).toFixed(1); + } + + var mousemove = evt && evt.type === 'mousemove'; + + if (!mouseover && !mousemove && !this.opt.targetKeep) { + score = this.opt.targetText; + } + } + + methods._setTarget.call(this, target, score); + } + }, + + _turnOn: function(i, score) { + return this.opt.single ? (i === score) : (i <= score); + }, + + _unlock: function() { + this.style.cursor = 'pointer'; + this.removeAttribute('title'); + + this.score.removeAttr('readonly'); + + this.self.data('readonly', false); + + for (var i = 0; i < this.opt.number; i++) { + this.stars[i].title = methods._getHint.call(this, i + 1); + } + + if (this.cancel) { + this.cancel.css('display', ''); + } + }, + + cancel: function(click) { + return this.each(function() { + var self = $(this); + + if (self.data('readonly') !== true) { + methods[click ? 'click' : 'score'].call(self, null); + + this.score.removeAttr('value'); + } + }); + }, + + click: function(score) { + return this.each(function() { + if ($(this).data('readonly') !== true) { + score = methods._adjustedScore.call(this, score); + + methods._apply.call(this, score); + + if (this.opt.click) { + this.opt.click.call(this, score, $.Event('click')); + } + + methods._target.call(this, score); + } + }); + }, + + destroy: function() { + return this.each(function() { + var self = $(this), + raw = self.data('raw'); + + if (raw) { + self.off('.raty').empty().css({ cursor: raw.style.cursor }).removeData('readonly'); + } else { + self.data('raw', self.clone()[0]); + } + }); + }, + + getScore: function() { + var score = [], + value ; + + this.each(function() { + value = this.score.val(); + + score.push(value ? +value : undefined); + }); + + return (score.length > 1) ? score : score[0]; + }, + + move: function(score) { + return this.each(function() { + var + integer = parseInt(score, 10), + decimal = methods._getFirstDecimal.call(this, score); + + if (integer >= this.opt.number) { + integer = this.opt.number - 1; + decimal = 10; + } + + var + width = methods._getWidth.call(this), + steps = width / 10, + star = $(this.stars[integer]), + percent = star.offset().left + steps * decimal, + evt = $.Event('mousemove', { pageX: percent }); + + this.move = true; + + star.trigger(evt); + + this.move = false; + }); + }, + + readOnly: function(readonly) { + return this.each(function() { + var self = $(this); + + if (self.data('readonly') !== readonly) { + if (readonly) { + self.off('.raty').children('img').off('.raty'); + + methods._lock.call(this); + } else { + methods._binds.call(this); + methods._unlock.call(this); + } + + self.data('readonly', readonly); + } + }); + }, + + reload: function() { + return methods.set.call(this, {}); + }, + + score: function() { + var self = $(this); + + return arguments.length ? methods.setScore.apply(self, arguments) : methods.getScore.call(self); + }, + + set: function(options) { + return this.each(function() { + $(this).raty($.extend({}, this.opt, options)); + }); + }, + + setScore: function(score) { + return this.each(function() { + if ($(this).data('readonly') !== true) { + score = methods._adjustedScore.call(this, score); + + methods._apply.call(this, score); + methods._target.call(this, score); + } + }); + } + }; + + $.fn.raty = function(method) { + if (methods[method]) { + return methods[method].apply(this, Array.prototype.slice.call(arguments, 1)); + } else if (typeof method === 'object' || !method) { + return methods.init.apply(this, arguments); + } else { + $.error('Method ' + method + ' does not exist!'); + } + }; + + $.fn.raty.defaults = { + cancel : false, + cancelClass : 'raty-cancel', + cancelHint : 'Cancel this rating!', + cancelOff : 'cancel-off.png', + cancelOn : 'cancel-on.png', + cancelPlace : 'left', + click : undefined, + half : false, + halfShow : true, + hints : ['bad', 'poor', 'regular', 'good', 'gorgeous'], + iconRange : undefined, + mouseout : undefined, + mouseover : undefined, + noRatedMsg : 'Not rated yet!', + number : 5, + numberMax : 20, + path : undefined, + precision : false, + readOnly : false, + round : { down: 0.25, full: 0.6, up: 0.76 }, + score : undefined, + scoreName : 'score', + single : false, + space : true, + starHalf : 'star-half.png', + starOff : 'star-off.png', + starOn : 'star-on.png', + starType : 'img', + target : undefined, + targetFormat : '{score}', + targetKeep : false, + targetScore : undefined, + targetText : '', + targetType : 'hint' + }; + +})(jQuery); diff --git a/app/assets/stylesheets/_header.scss b/app/assets/stylesheets/_header.scss new file mode 100644 index 0000000..247deb3 --- /dev/null +++ b/app/assets/stylesheets/_header.scss @@ -0,0 +1,5 @@ +.navbar { + img { + width: 30px; + } +} \ No newline at end of file diff --git a/app/assets/stylesheets/activities.css.scss b/app/assets/stylesheets/activities.css.scss index 2b1364e..6902eb6 100644 --- a/app/assets/stylesheets/activities.css.scss +++ b/app/assets/stylesheets/activities.css.scss @@ -1,3 +1,434 @@ -// Place all the styles related to the Activities controller here. -// They will automatically be included in application.css. -// You can use Sass (SCSS) here: http://sass-lang.com/ +/*! + * Start Bootstrap - Landing Page Bootstrap Theme (http://startbootstrap.com) + * Code licensed under the Apache License v2.0. + * For details, see http://www.apache.org/licenses/LICENSE-2.0. + */ + /*! + + /* Palette + darker blue: #0F79B5; + med blue: #018DC2; + button blue: #2BADD7; bright version #3ECDFD + charcoal 1c1c1c #232220 whitesmoke f5f5f5 + */ + + /* WORKING NOTES: + * fix contact link in nav bar, will need to fix scroll tos, and might want to easein transitions + * might want to animate transitions on buttons, navbar + * might want to animate happy face logo on hover, wink? frown? spin? + * would like to randomly switch out hero photo + need photos for testimonials and for inspiring quotes + * might want to add bouncy circle pointer icon before first Get Started button + * might want to add cute illust for take a guess, mark how happy, ch-ch-changes + * On my wishlist: add a random Math.floor to swap images on each refresh +*/ + + + +body, +html { + width: 100%; + height: 100%; +} + +body, +h1, +h2, +h3, +h4, +h5, +h6 { + font-family: "Lato","Helvetica Neue",Helvetica,Arial,sans-serif; + font-weight: 500; +} +/* NAVBAR */ + +.nav>li>a { + position: relative; + display: block; + padding-right: 20px; +} + +.navbar-default +.navbar-brand { + color: #2E2E2E; +} + +.navbar-right li a { + font-size:16px; + color: red; +} + +.navbar-brand span { + font-weight:900; + color: #2BADD7; +} + +.navbar-default .navbar-nav>li>a { + color: #2BADD7; +} + +.topnav { + font-size: 20px; +} + +.navbar-default .btn-nav { + color: white; + background-color:#3DBAFC; + border:4px #3DBAFC solid; +} + +.lead { + font-size: 18px; + font-weight: 300; + font-style:italic; + color:#f5f5f5; + margin-top:40px; + line-height:130%; +} + +.lead span { + color: #3ECDFD; + font-size: 15px; +} + +.lead-divider { + width: 380px; + border-top: 1px solid #3ECDFD; + border-bottom: 1px solid rgba(0,0,0,0.2); +} + + +.speech { + font-style:normal; + font-weight: 300; + position: relative; + padding: 15px; + margin: 1em 0 3em; + border: 5px solid #2BADD7; + color: #f5f5f5; + background:#3E849D; + -webkit-border-radius: 10px; + -moz-border-radius: 10px; + border-radius: 10px; +} + +.speech:before { + content: ""; + position: absolute; + bottom: -20px; + left: 40px; + border-width: 20px 20px 0; + border-style: solid; + border-color: #2BADD7 transparent; + display: block; + width: 0; +} + +.speech:after { + content: ""; + position: absolute; + bottom: -13px; + left: 47px; + border-width: 13px 13px 0; + border-style: solid; + border-color: #3E849D transparent; + display: block; + width: 0; +} + + +/* INTRO HEADER */ + +.intro-header { + padding-top: 50px; /* If you're making other pages, make sure there is 50px of padding to make sure the navbar doesn't overlap content! */ + padding-bottom: 50px; + text-align: center; + color: #f8f8f8; + background: image-url("sparkler.jpg") no-repeat center center; + background-size: cover; +} + +.intro-message { + position: relative; + padding-top: 20%; + padding-bottom: 20%; +} + +.intro-message > h1 { + margin: 0; + text-shadow: 2px 2px 3px rgba(0,0,0,0.4); + font-size: 5em; +} + +.intro-divider { + width: 380px; + border-top: 1px solid #f8f8f8; + border-bottom: 1px solid rgba(0,0,0,0.2); +} + +.intro-message > h4 { + letter-spacing:1.2px; +} + +@media(max-width:767px) { + .intro-message { + padding-bottom: 15%; + } + + .intro-message > h1 { + font-size: 3em; + } + + ul.intro-social-buttons > li { + display: block; + margin-bottom: 20px; + padding: 0; + } + + ul.intro-social-buttons > li:last-child { + margin-bottom: 0; + } + + .intro-divider { + width: 80%; + } +} + + + +/* SECTION SUPPORTING */ + +.supporting { + padding: 50px 0 80px; + background: #f5f5f5; + text-align:center; +} + +.supporting .col { + float: left; + width: 28%; + padding: 14px; +} + +.supporting h2 { + color: #4c4c4c; + font-size: 38px; + margin-bottom: 30px; + font-weight:800; +} + +.supporting h3 { + color: #2BADD7; + font-size: 30px; + margin-bottom: 16px; + margin-top: 34px; + font-weight:600; +} + +.clearfix { + clear: both; +} + +.supporting p { + color: #1c1c1c; + font-size:16px; + margin-bottom: 20px; + line-height: 1.6; +} + +.supporting .btn { + background-color: #eee; + color: #1c1c1c; + font-size: 18px; + padding: 8px 30px; + text-decoration: none; + display: inline-block; +} + +.section-divider { + text-align:center; + width: 280px; + border-top: 1px solid #f8f8f8; + border-bottom: 1px solid rgba(0,0,0,0.2); +} + +.network-name { + text-transform: uppercase; + font-size: 14px; + font-weight: 500; + letter-spacing: 2px; +} + +.content-section-a { + padding: 50px 0; + background-color: #f8f8f8; + background: image-url("blue2light.jpg") no-repeat center center; + background-size: cover; + border-bottom: 1px solid #e7e7e7; +} + +.content-section-b { + padding: 50px 0; + border-top: 1px solid #e7e7e7; + border-bottom: 1px solid #e7e7e7; + background: image-url("bluestmood.jpg") no-repeat center center; + z-index:2; + text-align: center; + background-size: cover; +} + +.content-section-b .btn { + margin-top:40px; +} + +.section-heading { + margin-bottom: 30px; +} + +.section-heading-divider { + float: left; + width: 200px; + border-top: 3px solid #e7e7e7; +} + + +/* SECTION BANNER */ + +.banner { + + padding: 46px 0 230px; + color: #f8f8f8; + background: image-url("class3v2.jpg") no-repeat center center; + background-size: cover; + text-align:center; + border-bottom: 1px solid #e7e7e7; +} + +.banner h2 { + margin: 0; + font-size: 44px; +} + +.banner ul { + margin-bottom: 0; +} + +.btn-default { + padding: 10px 50px; + margin: 30px 10px; + border: 3px solid #3ECDFD; + color: #3ECDFD; + background-color: transparent; + -webkit-transition: All 0.5s ease; + -moz-transition: All 0.5s ease; + -o-transition: All 0.5s ease; + -ms-transition: All 0.5s ease; + transition: All 0.5s ease; +} + +.btn-reverse { + padding: 10px 50px; + margin: 30px 10px; + border: 3px solid #f5f5f5; + color: #f5f5f5; + background-color: transparent; + -webkit-transition: All 0.5s ease; + -moz-transition: All 0.5s ease; + -o-transition: All 0.5s ease; + -ms-transition: All 0.5s ease; + transition: All 0.5s ease; + +} + +.btn-default.active, .btn-default.focus, .btn-default:active, .btn-default:focus, .btn-default:hover, .open>.dropdown-toggle.btn-default{ + color: #f5f5f5; + background-color: #3ECDFD; +} + +.banner-social-buttons { + float: right; + margin-top: 0; +} + +@media(max-width:1199px) { + ul.banner-social-buttons { + float: left; + margin-top: 15px; + } +} + +@media(max-width:767px) { + .banner h2 { + margin: 0; + font-size: 3em; + } + + ul.banner-social-buttons > li { + display: block; + margin-bottom: 20px; + padding: 0; + } + + ul.banner-social-buttons > li:last-child { + margin-bottom: 0; + } +} + +/* FOOTER */ + +footer { + padding: 50px 0 20px; + background-color: #f8f8f8; + text-align: center; + + img { + width:50px; + } +} + +.rotate { + margin-top:-10px; + -webkit-transition-duration: 0.8s; + -moz-transition-duration: 0.8s; + -o-transition-duration: 0.8s; + transition-duration: 0.8s; + -webkit-transition-property: -webkit-transform; + -moz-transition-property: -moz-transform; + -o-transition-property: -o-transform; + transition-property: transform; + overflow:hidden; + } + +.rotate:hover { + -webkit-transform:rotate(360deg); + -moz-transform:rotate(360deg); + -o-transform:rotate(360deg); + transform:rotate(360deg); +} + +p.copyright { + margin: 15px 0 0; + text-transform: uppercase; +} + +td .btn, td .description { + margin: 5px; +} + +.big-btn { + display: block; + width: 250px; + text-align: center; + margin: 0 auto; +} + +.table-responsive { + max-width: 1000px; + margin: 25px auto; +} + +#activities-intro { + padding: 0; + background-color: inherit; +} \ No newline at end of file diff --git a/app/assets/stylesheets/application.css b/app/assets/stylesheets/application.css index a443db3..890b449 100644 --- a/app/assets/stylesheets/application.css +++ b/app/assets/stylesheets/application.css @@ -13,3 +13,8 @@ *= require_tree . *= require_self */ + +body { + padding-top: 50px; + background-color: #f5f8fa; +} \ No newline at end of file diff --git a/app/assets/stylesheets/scaffolds.css.scss b/app/assets/stylesheets/scaffolds.css.scss deleted file mode 100644 index 6ec6a8f..0000000 --- a/app/assets/stylesheets/scaffolds.css.scss +++ /dev/null @@ -1,69 +0,0 @@ -body { - background-color: #fff; - color: #333; - font-family: verdana, arial, helvetica, sans-serif; - font-size: 13px; - line-height: 18px; -} - -p, ol, ul, td { - font-family: verdana, arial, helvetica, sans-serif; - font-size: 13px; - line-height: 18px; -} - -pre { - background-color: #eee; - padding: 10px; - font-size: 11px; -} - -a { - color: #000; - &:visited { - color: #666; - } - &:hover { - color: #fff; - background-color: #000; - } -} - -div { - &.field, &.actions { - margin-bottom: 10px; - } -} - -#notice { - color: green; -} - -.field_with_errors { - padding: 2px; - background-color: red; - display: table; -} - -#error_explanation { - width: 450px; - border: 2px solid red; - padding: 7px; - padding-bottom: 0; - margin-bottom: 20px; - background-color: #f0f0f0; - h2 { - text-align: left; - font-weight: bold; - padding: 5px 5px 5px 15px; - font-size: 12px; - margin: -7px; - margin-bottom: 0px; - background-color: #c00; - color: #fff; - } - ul li { - font-size: 12px; - list-style: square; - } -} diff --git a/app/assets/stylesheets/users.css.scss b/app/assets/stylesheets/users.css.scss index 31a2eac..cc9d4bb 100644 --- a/app/assets/stylesheets/users.css.scss +++ b/app/assets/stylesheets/users.css.scss @@ -1,3 +1,29 @@ // Place all the styles related to the Users controller here. // They will automatically be included in application.css. // You can use Sass (SCSS) here: http://sass-lang.com/ +.login-container { + width: 50%; + min-width: 400px; + margin: 0 auto; + background-color: #fff; + padding: 50px; + border-radius: 10px; + border: 1px solid darken(#f5f8fa, 30%); + + .btn-info { + display: block; + width: 50%; + height: 50px; + margin: 25px auto; + } + + .no-account { + text-align: center; + } + img { + display: block; + text-align: center; + width: 70px; + margin: 0 auto; + } +} \ No newline at end of file diff --git a/app/controllers/activities_controller.rb b/app/controllers/activities_controller.rb index feb332d..1f70d74 100644 --- a/app/controllers/activities_controller.rb +++ b/app/controllers/activities_controller.rb @@ -5,7 +5,13 @@ class ActivitiesController < ApplicationController # GET /activities # GET /activities.json def index + @activity = Activity.new @activities = Activity.all + if @activities.blank? + @avg_rating = 0 + else + @avg_rating = @activities.average(:prediction) + end end # GET /activities/1 @@ -29,7 +35,7 @@ def create respond_to do |format| if @activity.save - format.html { redirect_to @activity, notice: 'Activity was successfully created.' } + format.html { redirect_to ('/activities'), notice: 'Activity was successfully created.' } format.json { render :show, status: :created, location: @activity } else format.html { render :new } @@ -43,7 +49,7 @@ def create def update respond_to do |format| if @activity.update(activity_params) - format.html { redirect_to @activity, notice: 'Activity was successfully updated.' } + format.html { redirect_to ('/activities'), notice: 'Activity was successfully updated.' } format.json { render :show, status: :ok, location: @activity } else format.html { render :edit } diff --git a/app/controllers/sessions_controller.rb b/app/controllers/sessions_controller.rb index d35b8a6..be13257 100644 --- a/app/controllers/sessions_controller.rb +++ b/app/controllers/sessions_controller.rb @@ -7,7 +7,7 @@ def create user = User.find_by_email(params[:email]) if user && user.authenticate(params[:password]) session[:user_id] = user.id - redirect_to('/') + redirect_to('/activities') else redirect_to('/login') end diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index a3dd05a..6e760ef 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -14,6 +14,9 @@ def create end end + def welcome + end + private def user_params diff --git a/app/models/activity.rb b/app/models/activity.rb index 0d88c75..ec407da 100644 --- a/app/models/activity.rb +++ b/app/models/activity.rb @@ -1,2 +1,3 @@ class Activity < ActiveRecord::Base -end + validates :name, presence: true +end \ No newline at end of file diff --git a/app/views/activities/_form.html.erb b/app/views/activities/_form.html.erb index ea2dc90..abcd7e8 100644 --- a/app/views/activities/_form.html.erb +++ b/app/views/activities/_form.html.erb @@ -13,17 +13,53 @@
<%= f.label :name %>
- <%= f.text_field :name %> + <%= f.text_field :name, placeholder: "Enter Activity Name" %>
+
<%= f.label :prediction %>
- <%= f.number_field :prediction %> +

<%= f.label :actual %>
- <%= f.number_field :actual %> +

- <%= f.submit %> + <%= f.submit 'Enter Activity', :class => 'btn btn-default' %>
<% end %> + + + + + + + + + + + + + + + + + + + diff --git a/app/views/activities/astley.html.erb b/app/views/activities/astley.html.erb new file mode 100644 index 0000000..e982004 --- /dev/null +++ b/app/views/activities/astley.html.erb @@ -0,0 +1,6 @@ +
+ + <%= image_tag("star-off.png") %> + <%= image_tag("star-half.png") %> + <%= image_tag("star-on.png") %> +
\ No newline at end of file diff --git a/app/views/activities/edit.html.erb b/app/views/activities/edit.html.erb index a9b2630..955f993 100644 --- a/app/views/activities/edit.html.erb +++ b/app/views/activities/edit.html.erb @@ -1,6 +1,9 @@ -

Editing activity

- -<%= render 'form' %> - -<%= link_to 'Show', @activity %> | -<%= link_to 'Back', activities_path %> +

How's it Goin'?

+
+
+
+ <%= render 'form' %> +
+ <%= link_to 'Show', @activity, class: 'btn btn-default' %> + <%= link_to 'Back', activities_path, class: 'btn btn-default' %> +
\ No newline at end of file diff --git a/app/views/activities/index.html.erb b/app/views/activities/index.html.erb index 4699446..2cb51c7 100644 --- a/app/views/activities/index.html.erb +++ b/app/views/activities/index.html.erb @@ -1,41 +1,85 @@ -<% if current_user %> - -<% else %> - +
+

Hey <%= @current_user.name %>, what are you up to today?

+
+<% if @avg_rating && @avg_rating < 3 && @avg_rating > 0 %> +

Hey, it looks like you're gonna have a rough day!
How about some puppy videos to brighten your day?

<% end %> -

Listing activities

+ +
+ +
+ +
+ +
+

Take A Guess!

+

First step - jot down what you plan to do today. Make a prediction on how much you expect to enjoy your activity.

+
+ +
+

Answer for Yourself

+

Later on, mark how much each event actually made you happy.

+
+ +
+

Repave The Way

+

Start a new habit and we will track your progress. At the end of the week we will send you a recap of your progress. You'll see if you're using your energy where it matters the most.

+
- - - - - - - - - + - - <% @activities.each do |activity| %> + + + + <%= link_to 'Add new Activity', new_activity_path, class: "btn btn-default big-btn" %> +
+ +
+
NamePredictionActual
+ - - - - - - + + + + - <% end %> - -
<%= activity.name %><%= activity.prediction %><%= activity.actual %><%= link_to 'Show', activity %><%= link_to 'Edit', edit_activity_path(activity) %><%= link_to 'Destroy', activity, method: :delete, data: { confirm: 'Are you sure?' } %>Activity NamePredictionActual
+ + + -
+ <% @activities.each do |activity| %> + + +

<%= activity.name %>

+

+ <%= link_to activity, method: :delete, data: { confirm: 'Are you sure?' } do %> + + <% end %> +

+ +
+
+ + <%= link_to edit_activity_path(activity), class: "btn btn-warning" do %> + Edit + <% end %> + + + <% end %> + + +
-<%= link_to 'New Activity', new_activity_path %> + \ No newline at end of file diff --git a/app/views/activities/new.html.erb b/app/views/activities/new.html.erb index c176e73..b147db5 100644 --- a/app/views/activities/new.html.erb +++ b/app/views/activities/new.html.erb @@ -1,5 +1,8 @@ -

New activity

- -<%= render 'form' %> - -<%= link_to 'Back', activities_path %> +

Whatchoo Gonna Do?

+
+
+
+ <%= render 'form' %> +
+ <%= link_to 'Back', activities_path, class: 'btn btn-default' %> +
\ No newline at end of file diff --git a/app/views/activities/show.html.erb b/app/views/activities/show.html.erb index e374cbd..bc2d76c 100644 --- a/app/views/activities/show.html.erb +++ b/app/views/activities/show.html.erb @@ -1,19 +1,35 @@

<%= notice %>

-

- Name: - <%= @activity.name %> -

+
+
+ + + + Name: +

<%= @activity.name %>

+ + + Prediction: +
+ + + Actual: +
+ + + + <%= link_to 'Edit', edit_activity_path(@activity), class: 'btn btn-default' %> + <%= link_to 'Back', activities_path, class: 'btn btn-default' %> +
+
-

- Prediction: - <%= @activity.prediction %> -

- -

- Actual: - <%= @activity.actual %> -

- -<%= link_to 'Edit', edit_activity_path(@activity) %> | -<%= link_to 'Back', activities_path %> + \ No newline at end of file diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb index f415cac..f89a86f 100644 --- a/app/views/layouts/application.html.erb +++ b/app/views/layouts/application.html.erb @@ -2,13 +2,79 @@ ReThinkHappy + + + + + + <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track' => true %> <%= javascript_include_tag 'application', 'data-turbolinks-track' => true %> + + + <%= favicon_link_tag 'favicon.ico' %> <%= csrf_meta_tags %> +
-<%= yield %> + + +
+ <%= yield %> + +
+
+ +
+ +
+ + <%= link_to image_tag("logo2.svg"), "/", class: "rotate" %> + +
+ +

ReThinkHappy

+ + +
+ +
+ +
diff --git a/app/views/sessions/new.html.erb b/app/views/sessions/new.html.erb index cf7e3b3..52907be 100644 --- a/app/views/sessions/new.html.erb +++ b/app/views/sessions/new.html.erb @@ -1,9 +1,17 @@ -

Login

- -<%= form_tag('/login', method: 'post') do %> - -

Email: <%= text_field_tag :email %>

-

Password: <%= password_field_tag :password %>

- <%= submit_tag "Submit" %> - -<% end %> \ No newline at end of file + \ No newline at end of file diff --git a/app/views/users/new.html.erb b/app/views/users/new.html.erb index 2e4d337..3c09bb3 100644 --- a/app/views/users/new.html.erb +++ b/app/views/users/new.html.erb @@ -1,11 +1,23 @@ -

Signup!

+ \ No newline at end of file diff --git a/app/views/users/welcome.html.erb b/app/views/users/welcome.html.erb new file mode 100644 index 0000000..a2eab23 --- /dev/null +++ b/app/views/users/welcome.html.erb @@ -0,0 +1,175 @@ + + + + +
+ +
+ +
+
+ +
+

Get back to what makes
you happy.

+

Sometimes we need a restart.

+ +
+ + <%= link_to "Get Started", '/signup', class: "btn btn-default" %> +
+ +
+
+ +
+ + +
+ + + + +
+ +
+ +
+ +

What's this all about?

+
+ + +
+

Take A Guess!

+

First step - jot down what you plan to do today. Make a prediction on how much you expect to enjoy your activity.

+
+ +
+

Answer for Yourself

+

Later on, mark how much each event actually made you happy.

+
+ +
+

Repave The Way

+

Start a new habit and we will track your progress. At the end of the week we will send you a recap of your progress. You'll see if you're using your energy where it matters the most.

+
+ +
+ +
+
+ + +
+
+ + + + +
+ +
+ +
+ +
+ +
+
+

User's Feedback

+ +
+ +
+ +

I didn’t realize how little I got out of checking Facebook all the time - now I’ve scaled back and I’m more focused.
~ D’Angelo

+
+ +

It sounds really simple, but just taking a walk outside was the best part of my day.
~ Charles

+
+ +

Just doing two small things on my side project turned out to be today’s highlight. It didn’t even take that long.
~ Fiona

+
+ + <%= link_to "Get Started", '/signup', class: "btn btn-default" %> + +
+ +
+ + +
+ +
+ +
+ + + +
+ +
+ +
+ +
+ +
+
+

Tips and Encouragement

+ +
+

It’s a helluva start, being able to recognize what makes you happy. – Lucille Ball

+
+ +
+

The things you can do to increase your happiness are obvious and small and just take a little time. But you have to do them every day and wait for the results.– David Gilbert, author of Stumbling on Happiness

+
+ +
+

Happiness is when what you think, what you say, and what you do are in harmony.– Mahatma Gandhi

+
+ + +
+ +
+ +
+ + +
+ + + + + + + \ No newline at end of file diff --git a/config/database.yml b/config/database.yml index 1c1a37c..197d9de 100644 --- a/config/database.yml +++ b/config/database.yml @@ -22,4 +22,5 @@ test: production: <<: *default - database: db/production.sqlite3 + adapter: postgresql + database: db/production.sqlite3 \ No newline at end of file diff --git a/config/routes.rb b/config/routes.rb index 07b6831..8661fa4 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -13,7 +13,9 @@ # See how all your routes lay out with "rake routes". # You can have the root of your site routed with "root" - # root 'welcome#index' + root 'users#welcome' + + get '/astley' => 'activities#astley' # Example of regular route: # get 'products/:id' => 'catalog#view' diff --git a/db/schema.rb b/db/schema.rb index 97f511f..a05ba1f 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -21,14 +21,6 @@ t.datetime "updated_at" end - create_table "days", force: true do |t| - t.string "activity" - t.integer "prediction" - t.integer "actual" - t.datetime "created_at" - t.datetime "updated_at" - end - create_table "users", force: true do |t| t.string "name" t.string "email" diff --git a/text b/text new file mode 100644 index 0000000..e69de29