Fixed tests by getting rid of valid_session

This commit is contained in:
Skud
2012-11-26 19:04:43 +11:00
parent b39ee792b4
commit 760cf03b2c
133 changed files with 1969 additions and 12370 deletions

View File

@@ -22,11 +22,12 @@ group :assets do
# See https://github.com/sstephenson/execjs#readme for more supported runtimes
# long term, we'll probably want node.js for performance, but this will do for now as it's easier for new people to install
gem 'therubyracer', :platforms => :ruby
gem "less-rails"
gem "twitter-bootstrap-rails"
gem 'uglifier', '>= 1.0.3'
gem 'compass-rails', '~> 1.0.3'
gem 'zurb-foundation', '~> 3.0.9'
end
gem 'jquery-rails'
@@ -48,7 +49,8 @@ gem 'capistrano-ext'
# To use debugger
# gem 'debugger'
# GROWSTUFF ADDITIONS BELOW HERE
# Markdown formatting for updates etc
gem 'bluecloth'
# user signup/login/etc
gem 'devise'

View File

@@ -30,9 +30,10 @@ GEM
multi_json (~> 1.0)
arel (3.0.2)
bcrypt-ruby (3.0.1)
bluecloth (2.2.0)
builder (3.0.4)
cape (1.5.0)
capistrano (2.13.4)
capistrano (2.13.5)
highline
net-scp (>= 1.0.0)
net-sftp (>= 2.0.0)
@@ -48,13 +49,14 @@ GEM
coffee-script-source
execjs
coffee-script-source (1.4.0)
commonjs (0.2.6)
compass (0.12.2)
chunky_png (~> 1.2)
fssm (>= 0.2.7)
sass (~> 3.1)
compass-rails (1.0.3)
compass (>= 0.12.2, < 0.14)
daemon_controller (1.0.0)
daemon_controller (1.1.0)
devise (2.1.2)
bcrypt-ruby (~> 3.0)
orm_adapter (~> 0.1)
@@ -65,7 +67,7 @@ GEM
execjs (1.4.0)
multi_json (~> 1.0)
fastthread (1.0.7)
friendly_id (4.0.8)
friendly_id (4.0.9)
fssm (0.2.9)
haml (3.1.7)
haml-rails (0.3.5)
@@ -81,16 +83,18 @@ GEM
railties (>= 3.1.0, < 5.0)
thor (~> 0.14)
json (1.7.5)
less (2.2.2)
commonjs (~> 0.2.6)
less-rails (2.2.6)
actionpack (>= 3.1)
less (~> 2.2.0)
libv8 (3.3.10.4)
mail (2.4.4)
i18n (>= 0.4.0)
mime-types (~> 1.16)
treetop (~> 1.4.8)
mime-types (1.19)
modular-scale (1.0.2)
compass (>= 0.11.5)
sassy-math (>= 1.2)
multi_json (1.3.6)
multi_json (1.3.7)
net-scp (1.0.4)
net-ssh (>= 1.99.1)
net-sftp (2.0.5)
@@ -100,7 +104,7 @@ GEM
net-ssh (>= 1.99.1)
nokogiri (1.5.5)
orm_adapter (0.4.0)
passenger (3.0.17)
passenger (3.0.18)
daemon_controller (>= 1.0.0)
fastthread (>= 1.0.1)
rack
@@ -147,13 +151,11 @@ GEM
rspec (~> 2.11.0)
rvm-capistrano (1.2.7)
capistrano (>= 2.0.0)
sass (3.2.1)
sass (3.2.2)
sass-rails (3.2.5)
railties (~> 3.2.0)
sass (>= 3.1.10)
tilt (~> 1.3)
sassy-math (1.2)
compass (~> 0.11)
spork (0.9.2)
sprockets (2.1.3)
hike (~> 1.2)
@@ -164,10 +166,14 @@ GEM
libv8 (~> 3.3.10)
thor (0.16.0)
tilt (1.3.3)
treetop (1.4.11)
treetop (1.4.12)
polyglot
polyglot (>= 0.3.1)
tzinfo (0.3.33)
twitter-bootstrap-rails (2.1.6)
actionpack (>= 3.1)
execjs
railties (>= 3.1)
tzinfo (0.3.35)
uglifier (1.3.0)
execjs (>= 0.3.0)
multi_json (~> 1.0, >= 1.0.2)
@@ -178,16 +184,12 @@ GEM
nokogiri (>= 1.2.0)
rack (>= 1.0)
rack-test (>= 0.5.3)
zurb-foundation (3.0.9)
compass (>= 0.12.2)
modular-scale (>= 1.0.2)
rake
sass (>= 3.2.0)
PLATFORMS
ruby
DEPENDENCIES
bluecloth
bundler (>= 1.1.5)
cape
capistrano
@@ -200,6 +202,7 @@ DEPENDENCIES
haml
haml-rails
jquery-rails
less-rails
passenger
pg
rails (= 3.2.8)
@@ -210,7 +213,7 @@ DEPENDENCIES
spork (~> 0.9.0.rc)
sqlite3
therubyracer
twitter-bootstrap-rails
uglifier (>= 1.0.3)
watchr
webrat
zurb-foundation (~> 3.0.9)

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 657 B

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 522 B

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 526 B

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 288 B

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 536 B

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 526 B

View File

@@ -12,7 +12,6 @@
//
//= require jquery
//= require jquery_ujs
//= require foundation
//= require foundation/app
//= require twitter/bootstrap
//= require_tree .

View File

@@ -0,0 +1,4 @@
jQuery ->
$("a[rel=popover]").popover()
$(".tooltip").tooltip()
$("a[rel=tooltip]").tooltip()

View File

@@ -1,22 +0,0 @@
(function ($) {
$(function(){
$(document).foundationAlerts();
$(document).foundationButtons();
$(document).foundationAccordion();
$(document).foundationNavigation();
$(document).foundationCustomForms();
$(document).foundationMediaQueryViewer();
$(document).foundationTabs({callback:$.foundation.customForms.appendCustomMarkup});
$(document).tooltips();
$('input, textarea').placeholder();
// UNCOMMENT THE LINE YOU WANT BELOW IF YOU WANT IE8 SUPPORT AND ARE USING .block-grids
// $('.block-grid.two-up>li:nth-child(2n+1)').css({clear: 'both'});
// $('.block-grid.three-up>li:nth-child(3n+1)').css({clear: 'both'});
// $('.block-grid.four-up>li:nth-child(4n+1)').css({clear: 'both'});
// $('.block-grid.five-up>li:nth-child(5n+1)').css({clear: 'both'});
});
})(jQuery);

View File

@@ -1,15 +0,0 @@
(function ($){
$.fn.foundationAccordion = function (options) {
$(document).on('click.fndtn', '.accordion li', function () {
var flyout = $(this).children('.content').first();
$('.accordion .content').not(flyout).hide().parent('li').removeClass('active');
flyout.show(0, function () {
flyout.parent('li').addClass('active');
});
});
};
})( jQuery );

View File

@@ -1,19 +0,0 @@
(function ($) {
$.fn.foundationAlerts = function (options) {
var settings = $.extend({
callback: $.noop
}, options);
$(document).on("click", ".alert-box a.close", function (event) {
event.preventDefault();
$(this).closest(".alert-box").fadeOut(function (event) {
$(this).remove();
// Do something else after the alert closes
settings.callback();
});
});
};
})(jQuery);

View File

@@ -1,49 +0,0 @@
(function ($) {
$.fn.foundationButtons = function(options) {
// Prevent event propagation on disabled buttons
$(document).on('click.fndtn', '.button.disabled', function (e) {
e.preventDefault();
});
$('.button.dropdown > ul', this).addClass('no-hover');
$(document).on('click.fndtn', '.button.dropdown, .button.dropdown.split span', function (e) {
// Stops further propagation of the event up the DOM tree when clicked on the button.
// Events fired by its descendants are not being blocked.
if (e.target === this) {
e.stopPropagation();
}
});
$(document).on('click.fndtn', '.button.dropdown.split span', function (e) {
e.preventDefault();
$('.button.dropdown', this).not($(this).parent()).children('ul').removeClass('show-dropdown');
$(this).siblings('ul').toggleClass('show-dropdown');
});
$(document).on('click.fndtn', '.button.dropdown:not(.split)', function (e) {
$('.button.dropdown', this).not(this).children('ul').removeClass('show-dropdown');
$(this).children('ul').toggleClass('show-dropdown');
});
$(document).on('click.fndtn', 'body, html', function () {
$('.button.dropdown ul').removeClass('show-dropdown');
});
// Positioning the Flyout List
var normalButtonHeight = $('.button.dropdown:not(.large):not(.small):not(.tiny)', this).outerHeight() - 1,
largeButtonHeight = $('.button.large.dropdown', this).outerHeight() - 1,
smallButtonHeight = $('.button.small.dropdown', this).outerHeight() - 1,
tinyButtonHeight = $('.button.tiny.dropdown', this).outerHeight() - 1;
$('.button.dropdown:not(.large):not(.small):not(.tiny) > ul', this).css('top', normalButtonHeight);
$('.button.dropdown.large > ul', this).css('top', largeButtonHeight);
$('.button.dropdown.small > ul', this).css('top', smallButtonHeight);
$('.button.dropdown.tiny > ul', this).css('top', tinyButtonHeight);
$('.button.dropdown.up:not(.large):not(.small):not(.tiny) > ul', this).css('top', 'auto').css('bottom', normalButtonHeight - 2);
$('.button.dropdown.up.large > ul', this).css('top', 'auto').css('bottom', largeButtonHeight - 2);
$('.button.dropdown.up.small > ul', this).css('top', 'auto').css('bottom', smallButtonHeight - 2);
$('.button.dropdown.up.tiny > ul', this).css('top', 'auto').css('bottom', tinyButtonHeight - 2);
};
})( jQuery );

View File

@@ -1,483 +0,0 @@
/*
* jQuery Custom Forms Plugin 1.0
* www.ZURB.com
* Copyright 2010, ZURB
* Free to use under the MIT license.
* http://www.opensource.org/licenses/mit-license.php
*/
(function( $ ){
/**
* Helper object used to quickly adjust all hidden parent element's, display and visibility properties.
* This is currently used for the custom drop downs. When the dropdowns are contained within a reveal modal
* we cannot accurately determine the list-item elements width property, since the modal's display property is set
* to 'none'.
*
* This object will help us work around that problem.
*
* NOTE: This could also be plugin.
*
* @function hiddenFix
*/
var hiddenFix = function() {
return {
/**
* Sets all hidden parent elements and self to visibile.
*
* @method adjust
* @param {jQuery Object} $child
*/
// We'll use this to temporarily store style properties.
tmp : [],
// We'll use this to set hidden parent elements.
hidden : null,
adjust : function( $child ) {
// Internal reference.
var _self = this;
// Set all hidden parent elements, including this element.
_self.hidden = $child.parents().andSelf().filter( ":hidden" );
// Loop through all hidden elements.
_self.hidden.each( function() {
// Cache the element.
var $elem = $( this );
// Store the style attribute.
// Undefined if element doesn't have a style attribute.
_self.tmp.push( $elem.attr( 'style' ) );
// Set the element's display property to block,
// but ensure it's visibility is hidden.
$elem.css( { 'visibility' : 'hidden', 'display' : 'block' } );
});
}, // end adjust
/**
* Resets the elements previous state.
*
* @method reset
*/
reset : function() {
// Internal reference.
var _self = this;
// Loop through our hidden element collection.
_self.hidden.each( function( i ) {
// Cache this element.
var $elem = $( this ),
_tmp = _self.tmp[ i ]; // Get the stored 'style' value for this element.
// If the stored value is undefined.
if( _tmp === undefined )
// Remove the style attribute.
$elem.removeAttr( 'style' );
else
// Otherwise, reset the element style attribute.
$elem.attr( 'style', _tmp );
});
// Reset the tmp array.
_self.tmp = [];
// Reset the hidden elements variable.
_self.hidden = null;
} // end reset
}; // end return
};
jQuery.foundation = jQuery.foundation || {};
jQuery.foundation.customForms = jQuery.foundation.customForms || {};
$.foundation.customForms.appendCustomMarkup = function ( options ) {
var defaults = {
disable_class: "js-disable-custom"
};
options = $.extend( defaults, options );
function appendCustomMarkup(idx, sel) {
var $this = $(sel).hide(),
type = $this.attr('type'),
$span = $this.next('span.custom.' + type);
if ($span.length === 0) {
$span = $('<span class="custom ' + type + '"></span>').insertAfter($this);
}
$span.toggleClass('checked', $this.is(':checked'));
$span.toggleClass('disabled', $this.is(':disabled'));
}
function appendCustomSelect(idx, sel) {
var hiddenFixObj = hiddenFix();
//
// jQueryify the <select> element and cache it.
//
var $this = $( sel ),
//
// Find the custom drop down element.
//
$customSelect = $this.next( 'div.custom.dropdown' ),
//
// Find the custom select element within the custom drop down.
//
$customList = $customSelect.find( 'ul' ),
//
// Find the custom a.current element.
//
$selectCurrent = $customSelect.find( ".current" ),
//
// Find the custom a.selector element (the drop-down icon).
//
$selector = $customSelect.find( ".selector" ),
//
// Get the <options> from the <select> element.
//
$options = $this.find( 'option' ),
//
// Filter down the selected options
//
$selectedOption = $options.filter( ':selected' ),
//
// Initial max width.
//
maxWidth = 0,
//
// We'll use this variable to create the <li> elements for our custom select.
//
liHtml = '',
//
// We'll use this to cache the created <li> elements within our custom select.
//
$listItems
;
var $currentSelect = false;
//
// Should we not create a custom list?
//
if ( $this.hasClass( 'no-custom' ) ) return;
//
// Did we not create a custom select element yet?
//
if ( $customSelect.length === 0 ) {
//
// Let's create our custom select element!
//
//
// Determine what select size to use.
//
var customSelectSize = $this.hasClass( 'small' ) ? 'small' :
$this.hasClass( 'medium' ) ? 'medium' :
$this.hasClass( 'large' ) ? 'large' :
$this.hasClass( 'expand' ) ? 'expand' : ''
;
//
// Build our custom list.
//
$customSelect = $('<div class="' + ['custom', 'dropdown', customSelectSize ].join( ' ' ) + '"><a href="#" class="selector"></a><ul /></div>"');
//
// Grab the selector element
//
$selector = $customSelect.find( ".selector" );
//
// Grab the unordered list element from the custom list.
//
$customList = $customSelect.find( "ul" );
//
// Build our <li> elements.
//
liHtml = $options.map( function() { return "<li>" + $( this ).html() + "</li>"; } ).get().join( '' );
//
// Append our <li> elements to the custom list (<ul>).
//
$customList.append( liHtml );
//
// Insert the the currently selected list item before all other elements.
// Then, find the element and assign it to $currentSelect.
//
$currentSelect = $customSelect.prepend( '<a href="#" class="current">' + $selectedOption.html() + '</a>' ).find( ".current" );
//
// Add the custom select element after the <select> element.
//
$this.after( $customSelect )
//
//then hide the <select> element.
//
.hide();
} else {
//
// Create our list item <li> elements.
//
liHtml = $options.map( function() { return "<li>" + $( this ).html() + "</li>"; } ).get().join( '' );
//
// Refresh the ul with options from the select in case the supplied markup doesn't match.
// Clear what's currently in the <ul> element.
//
$customList.html( '' )
//
// Populate the list item <li> elements.
//
.append( liHtml );
} // endif $customSelect.length === 0
//
// Determine whether or not the custom select element should be disabled.
//
$customSelect.toggleClass( 'disabled', $this.is( ':disabled' ) );
//
// Cache our List item elements.
//
$listItems = $customList.find( 'li' );
//
// Determine which elements to select in our custom list.
//
$options.each( function ( index ) {
if ( this.selected ) {
//
// Add the selected class to the current li element
//
$listItems.eq( index ).addClass( 'selected' );
//
// Update the current element with the option value.
//
if ($currentSelect) {
$currentSelect.html( $( this ).html() );
}
}
});
//
// Update the custom <ul> list width property.
//
$customList.css( 'width', 'inherit' );
//
// Set the custom select width property.
//
$customSelect.css( 'width', 'inherit' );
//
// If we're not specifying a predetermined form size.
//
if ( !$customSelect.is( '.small, .medium, .large, .expand' ) ) {
// ------------------------------------------------------------------------------------
// This is a work-around for when elements are contained within hidden parents.
// For example, when custom-form elements are inside of a hidden reveal modal.
//
// We need to display the current custom list element as well as hidden parent elements
// in order to properly calculate the list item element's width property.
// -------------------------------------------------------------------------------------
//
// Show the drop down.
// This should ensure that the list item's width values are properly calculated.
//
$customSelect.addClass( 'open' );
//
// Quickly, display all parent elements.
// This should help us calcualate the width of the list item's within the drop down.
//
hiddenFixObj.adjust( $customList );
//
// Grab the largest list item width.
//
maxWidth = ( $listItems.outerWidth() > maxWidth ) ? $listItems.outerWidth() : maxWidth;
//
// Okay, now reset the parent elements.
// This will hide them again.
//
hiddenFixObj.reset();
//
// Finally, hide the drop down.
//
$customSelect.removeClass( 'open' );
//
// Set the custom list width.
//
$customSelect.width( maxWidth + 18);
//
// Set the custom list element (<ul />) width.
//
$customList.width( maxWidth + 16 );
} // endif
}
$('form.custom input:radio[data-customforms!=disabled]').each(appendCustomMarkup);
$('form.custom input:checkbox[data-customforms!=disabled]').each(appendCustomMarkup);
$('form.custom select[data-customforms!=disabled]').each(appendCustomSelect);
};
var refreshCustomSelect = function($select) {
var maxWidth = 0,
$customSelect = $select.next();
$options = $select.find('option');
$customSelect.find('ul').html('');
$options.each(function () {
$li = $('<li>' + $(this).html() + '</li>');
$customSelect.find('ul').append($li);
});
// re-populate
$options.each(function (index) {
if (this.selected) {
$customSelect.find('li').eq(index).addClass('selected');
$customSelect.find('.current').html($(this).html());
}
});
// fix width
$customSelect.removeAttr('style')
.find('ul').removeAttr('style');
$customSelect.find('li').each(function () {
$customSelect.addClass('open');
if ($(this).outerWidth() > maxWidth) {
maxWidth = $(this).outerWidth();
}
$customSelect.removeClass('open');
});
$customSelect.css('width', maxWidth + 18 + 'px');
$customSelect.find('ul').css('width', maxWidth + 16 + 'px');
};
var toggleCheckbox = function($element) {
var $input = $element.prev(),
input = $input[0];
if (false === $input.is(':disabled')) {
input.checked = ((input.checked) ? false : true);
$element.toggleClass('checked');
}
};
var toggleRadio = function($element) {
var $input = $element.prev(),
input = $input[0];
if (false === $input.is(':disabled')) {
$('input:radio[name="' + $input.attr('name') + '"]').each(function () {
$(this).next().removeClass('checked');
});
input.checked = ((input.checked) ? false : true);
$element.toggleClass('checked');
$input.trigger('change');
}
};
$(document).on('click', 'form.custom span.custom.checkbox', function (event) {
event.preventDefault();
event.stopPropagation();
toggleCheckbox($(this));
});
$(document).on('click', 'form.custom span.custom.radio', function (event) {
event.preventDefault();
event.stopPropagation();
toggleRadio($(this));
});
$(document).on('change', 'form.custom select[data-customforms!=disabled]', function (event) {
refreshCustomSelect($(this));
});
$(document).on('click', 'form.custom label', function (event) {
var $associatedElement = $('#' + $(this).attr('for')),
$customCheckbox,
$customRadio;
if ($associatedElement.length !== 0) {
if ($associatedElement.attr('type') === 'checkbox') {
event.preventDefault();
$customCheckbox = $(this).find('span.custom.checkbox');
toggleCheckbox($customCheckbox);
} else if ($associatedElement.attr('type') === 'radio') {
event.preventDefault();
$customRadio = $(this).find('span.custom.radio');
toggleRadio($customRadio);
}
}
});
$(document).on('click', 'form.custom div.custom.dropdown a.current, form.custom div.custom.dropdown a.selector', function (event) {
var $this = $(this),
$dropdown = $this.closest('div.custom.dropdown'),
$select = $dropdown.prev();
event.preventDefault();
$('div.dropdown').removeClass('open');
if (false === $select.is(':disabled')) {
$dropdown.toggleClass('open');
if ($dropdown.hasClass('open')) {
$(document).bind('click.customdropdown', function (event) {
$dropdown.removeClass('open');
$(document).unbind('.customdropdown');
});
} else {
$(document).unbind('.customdropdown');
}
return false;
}
});
$(document).on('click', 'form.custom div.custom.dropdown li', function (event) {
var $this = $(this),
$customDropdown = $this.closest('div.custom.dropdown'),
$select = $customDropdown.prev(),
selectedIndex = 0;
event.preventDefault();
event.stopPropagation();
$('div.dropdown').removeClass('open');
$this
.closest('ul')
.find('li')
.removeClass('selected');
$this.addClass('selected');
$customDropdown
.removeClass('open')
.find('a.current')
.html($this.html());
$this.closest('ul').find('li').each(function (index) {
if ($this[0] == this) {
selectedIndex = index;
}
});
$select[0].selectedIndex = selectedIndex;
$select.trigger('change');
});
$.fn.foundationCustomForms = $.foundation.customForms.appendCustomMarkup;
})( jQuery );

View File

@@ -1,25 +0,0 @@
(function ($) {
$.fn.foundationMediaQueryViewer = function (options) {
var settings = $.extend(options,{toggleKey:77}); // // Press 'M'
$(document).on("keyup.mediaQueryViewer", ":input", function(e){
if (e.which === settings.toggleKey) {
e.stopPropagation();
}
});
$(document).on("keyup.mediaQueryViewer", function(e) {
var $mqViewer = $('#fqv');
if (e.which === settings.toggleKey) {
if ($mqViewer.length > 0) {
$mqViewer.remove();
} else {
$('body').prepend('<div id="fqv" style="position:fixed;top:4px;left:4px;z-index:999;color:#fff;"><p style="font-size:12px;background:rgba(0,0,0,0.75);padding:5px;margin-bottom:1px;line-height:1.2;"><span class="left">Media:</span> <span style="font-weight:bold;" class="show-for-xlarge">Extra Large</span><span style="font-weight:bold;" class="show-for-large">Large</span><span style="font-weight:bold;" class="show-for-medium">Medium</span><span style="font-weight:bold;" class="show-for-small">Small</span><span style="font-weight:bold;" class="show-for-landscape">Landscape</span><span style="font-weight:bold;" class="show-for-portrait">Portrait</span><span style="font-weight:bold;" class="show-for-touch">Touch</span></p></div>');
}
}
});
};
})(jQuery);

View File

@@ -1,30 +0,0 @@
(function ($){
$.fn.foundationNavigation = function (options) {
var lockNavBar = false;
// Windows Phone, sadly, does not register touch events :(
if (Modernizr.touch || navigator.userAgent.match(/Windows Phone/i)) {
$(document).on('click.fndtn touchstart.fndtn', '.nav-bar a.flyout-toggle', function (e) {
e.preventDefault();
var flyout = $(this).siblings('.flyout').first();
if (lockNavBar === false) {
$('.nav-bar .flyout').not(flyout).slideUp(500);
flyout.slideToggle(500, function () {
lockNavBar = false;
});
}
lockNavBar = true;
});
$('.nav-bar>li.has-flyout', this).addClass('is-touch');
} else {
$('.nav-bar>li.has-flyout', this).hover(function () {
$(this).children('.flyout').show();
}, function () {
$(this).children('.flyout').hide();
});
}
};
})( jQuery );

View File

@@ -1,634 +0,0 @@
/*
* jQuery Orbit Plugin 1.4.0
* www.ZURB.com/playground
* Copyright 2010, ZURB
* Free to use under the MIT license.
* http://www.opensource.org/licenses/mit-license.php
*/
(function ($) {
'use strict';
$.fn.findFirstImage = function () {
return this.first()
.find('img')
.andSelf().filter('img')
.first();
};
var ORBIT = {
defaults: {
animation: 'horizontal-push', // fade, horizontal-slide, vertical-slide, horizontal-push, vertical-push
animationSpeed: 600, // how fast animtions are
timer: true, // true or false to have the timer
advanceSpeed: 4000, // if timer is enabled, time between transitions
pauseOnHover: false, // if you hover pauses the slider
startClockOnMouseOut: false, // if clock should start on MouseOut
startClockOnMouseOutAfter: 1000, // how long after MouseOut should the timer start again
directionalNav: true, // manual advancing directional navs
directionalNavRightText: 'Right', // text of right directional element for accessibility
directionalNavLeftText: 'Left', // text of left directional element for accessibility
captions: true, // do you want captions?
captionAnimation: 'fade', // fade, slideOpen, none
captionAnimationSpeed: 600, // if so how quickly should they animate in
resetTimerOnClick: false, // true resets the timer instead of pausing slideshow progress on manual navigation
bullets: false, // true or false to activate the bullet navigation
bulletThumbs: false, // thumbnails for the bullets
bulletThumbLocation: '', // location from this file where thumbs will be
afterSlideChange: $.noop, // empty function
afterLoadComplete: $.noop, //callback to execute after everything has been loaded
fluid: true,
centerBullets: true // center bullet nav with js, turn this off if you want to position the bullet nav manually
},
activeSlide: 0,
numberSlides: 0,
orbitWidth: null,
orbitHeight: null,
locked: null,
timerRunning: null,
degrees: 0,
wrapperHTML: '<div class="orbit-wrapper" />',
timerHTML: '<div class="timer"><span class="mask"><span class="rotator"></span></span><span class="pause"></span></div>',
captionHTML: '<div class="orbit-caption"></div>',
directionalNavHTML: '<div class="slider-nav"><span class="right"></span><span class="left"></span></div>',
bulletHTML: '<ul class="orbit-bullets"></ul>',
init: function (element, options) {
var $imageSlides,
imagesLoadedCount = 0,
self = this;
// Bind functions to correct context
this.clickTimer = $.proxy(this.clickTimer, this);
this.addBullet = $.proxy(this.addBullet, this);
this.resetAndUnlock = $.proxy(this.resetAndUnlock, this);
this.stopClock = $.proxy(this.stopClock, this);
this.startTimerAfterMouseLeave = $.proxy(this.startTimerAfterMouseLeave, this);
this.clearClockMouseLeaveTimer = $.proxy(this.clearClockMouseLeaveTimer, this);
this.rotateTimer = $.proxy(this.rotateTimer, this);
this.options = $.extend({}, this.defaults, options);
if (this.options.timer === 'false') this.options.timer = false;
if (this.options.captions === 'false') this.options.captions = false;
if (this.options.directionalNav === 'false') this.options.directionalNav = false;
this.$element = $(element);
this.$wrapper = this.$element.wrap(this.wrapperHTML).parent();
this.$slides = this.$element.children('img, a, div');
this.$element.bind('orbit.next', function () {
self.shift('next');
});
this.$element.bind('orbit.prev', function () {
self.shift('prev');
});
this.$element.bind('orbit.goto', function (event, index) {
self.shift(index);
});
this.$element.bind('orbit.start', function (event, index) {
self.startClock();
});
this.$element.bind('orbit.stop', function (event, index) {
self.stopClock();
});
$imageSlides = this.$slides.filter('img');
if ($imageSlides.length === 0) {
this.loaded();
} else {
$imageSlides.bind('imageready', function () {
imagesLoadedCount += 1;
if (imagesLoadedCount === $imageSlides.length) {
self.loaded();
}
});
}
},
loaded: function () {
this.$element
.addClass('orbit')
.css({width: '1px', height: '1px'});
this.$slides.addClass('orbit-slide');
this.setDimentionsFromLargestSlide();
this.updateOptionsIfOnlyOneSlide();
this.setupFirstSlide();
if (this.options.timer) {
this.setupTimer();
this.startClock();
}
if (this.options.captions) {
this.setupCaptions();
}
if (this.options.directionalNav) {
this.setupDirectionalNav();
}
if (this.options.bullets) {
this.setupBulletNav();
this.setActiveBullet();
}
this.options.afterLoadComplete.call(this);
},
currentSlide: function () {
return this.$slides.eq(this.activeSlide);
},
setDimentionsFromLargestSlide: function () {
//Collect all slides and set slider size of largest image
var self = this,
$fluidPlaceholder;
self.$element.add(self.$wrapper).width(this.$slides.first().outerWidth());
self.$element.add(self.$wrapper).height(this.$slides.first().height());
self.orbitWidth = this.$slides.first().outerWidth();
self.orbitHeight = this.$slides.first().height();
$fluidPlaceholder = this.$slides.first().findFirstImage().clone();
this.$slides.each(function () {
var slide = $(this),
slideWidth = slide.outerWidth(),
slideHeight = slide.height();
if (slideWidth > self.$element.outerWidth()) {
self.$element.add(self.$wrapper).width(slideWidth);
self.orbitWidth = self.$element.outerWidth();
}
if (slideHeight > self.$element.height()) {
self.$element.add(self.$wrapper).height(slideHeight);
self.orbitHeight = self.$element.height();
$fluidPlaceholder = $(this).findFirstImage().clone();
}
self.numberSlides += 1;
});
if (this.options.fluid) {
if (typeof this.options.fluid === "string") {
$fluidPlaceholder = $('<img src="http://placehold.it/' + this.options.fluid + '" />')
}
self.$element.prepend($fluidPlaceholder);
$fluidPlaceholder.addClass('fluid-placeholder');
self.$element.add(self.$wrapper).css({width: 'inherit'});
self.$element.add(self.$wrapper).css({height: 'inherit'});
$(window).bind('resize', function () {
self.orbitWidth = self.$element.outerWidth();
self.orbitHeight = self.$element.height();
});
}
},
//Animation locking functions
lock: function () {
this.locked = true;
},
unlock: function () {
this.locked = false;
},
updateOptionsIfOnlyOneSlide: function () {
if(this.$slides.length === 1) {
this.options.directionalNav = false;
this.options.timer = false;
this.options.bullets = false;
}
},
setupFirstSlide: function () {
//Set initial front photo z-index and fades it in
var self = this;
this.$slides.first()
.css({"z-index" : 3})
.fadeIn(function() {
//brings in all other slides IF css declares a display: none
self.$slides.css({"display":"block"})
});
},
startClock: function () {
var self = this;
if(!this.options.timer) {
return false;
}
if (this.$timer.is(':hidden')) {
this.clock = setInterval(function () {
self.$element.trigger('orbit.next');
}, this.options.advanceSpeed);
} else {
this.timerRunning = true;
this.$pause.removeClass('active');
this.clock = setInterval(this.rotateTimer, this.options.advanceSpeed / 180, false);
}
},
rotateTimer: function (reset) {
var degreeCSS = "rotate(" + this.degrees + "deg)";
this.degrees += 2;
this.$rotator.css({
"-webkit-transform": degreeCSS,
"-moz-transform": degreeCSS,
"-o-transform": degreeCSS,
"-ms-transform": degreeCSS
});
if(this.degrees > 180) {
this.$rotator.addClass('move');
this.$mask.addClass('move');
}
if(this.degrees > 360 || reset) {
this.$rotator.removeClass('move');
this.$mask.removeClass('move');
this.degrees = 0;
this.$element.trigger('orbit.next');
}
},
stopClock: function () {
if (!this.options.timer) {
return false;
} else {
this.timerRunning = false;
clearInterval(this.clock);
this.$pause.addClass('active');
}
},
setupTimer: function () {
this.$timer = $(this.timerHTML);
this.$wrapper.append(this.$timer);
this.$rotator = this.$timer.find('.rotator');
this.$mask = this.$timer.find('.mask');
this.$pause = this.$timer.find('.pause');
this.$timer.click(this.clickTimer);
if (this.options.startClockOnMouseOut) {
this.$wrapper.mouseleave(this.startTimerAfterMouseLeave);
this.$wrapper.mouseenter(this.clearClockMouseLeaveTimer);
}
if (this.options.pauseOnHover) {
this.$wrapper.mouseenter(this.stopClock);
}
},
startTimerAfterMouseLeave: function () {
var self = this;
this.outTimer = setTimeout(function() {
if(!self.timerRunning){
self.startClock();
}
}, this.options.startClockOnMouseOutAfter)
},
clearClockMouseLeaveTimer: function () {
clearTimeout(this.outTimer);
},
clickTimer: function () {
if(!this.timerRunning) {
this.startClock();
} else {
this.stopClock();
}
},
setupCaptions: function () {
this.$caption = $(this.captionHTML);
this.$wrapper.append(this.$caption);
this.setCaption();
},
setCaption: function () {
var captionLocation = this.currentSlide().attr('data-caption'),
captionHTML;
if (!this.options.captions) {
return false;
}
//Set HTML for the caption if it exists
if (captionLocation) {
//if caption text is blank, don't show captions
if ($.trim($(captionLocation).text()).length < 1){
return false;
}
captionHTML = $(captionLocation).html(); //get HTML from the matching HTML entity
this.$caption
.attr('id', captionLocation) // Add ID caption TODO why is the id being set?
.html(captionHTML); // Change HTML in Caption
//Animations for Caption entrances
switch (this.options.captionAnimation) {
case 'none':
this.$caption.show();
break;
case 'fade':
this.$caption.fadeIn(this.options.captionAnimationSpeed);
break;
case 'slideOpen':
this.$caption.slideDown(this.options.captionAnimationSpeed);
break;
}
} else {
//Animations for Caption exits
switch (this.options.captionAnimation) {
case 'none':
this.$caption.hide();
break;
case 'fade':
this.$caption.fadeOut(this.options.captionAnimationSpeed);
break;
case 'slideOpen':
this.$caption.slideUp(this.options.captionAnimationSpeed);
break;
}
}
},
setupDirectionalNav: function () {
var self = this,
$directionalNav = $(this.directionalNavHTML);
$directionalNav.find('.right').html(this.options.directionalNavRightText);
$directionalNav.find('.left').html(this.options.directionalNavLeftText);
this.$wrapper.append($directionalNav);
this.$wrapper.find('.left').click(function () {
self.stopClock();
if (self.options.resetTimerOnClick) {
self.rotateTimer(true);
self.startClock();
}
self.$element.trigger('orbit.prev');
});
this.$wrapper.find('.right').click(function () {
self.stopClock();
if (self.options.resetTimerOnClick) {
self.rotateTimer(true);
self.startClock();
}
self.$element.trigger('orbit.next');
});
},
setupBulletNav: function () {
this.$bullets = $(this.bulletHTML);
this.$wrapper.append(this.$bullets);
this.$slides.each(this.addBullet);
this.$element.addClass('with-bullets');
if (this.options.centerBullets) this.$bullets.css('margin-left', -this.$bullets.outerWidth() / 2);
},
addBullet: function (index, slide) {
var position = index + 1,
$li = $('<li>' + (position) + '</li>'),
thumbName,
self = this;
if (this.options.bulletThumbs) {
thumbName = $(slide).attr('data-thumb');
if (thumbName) {
$li
.addClass('has-thumb')
.css({background: "url(" + this.options.bulletThumbLocation + thumbName + ") no-repeat"});;
}
}
this.$bullets.append($li);
$li.data('index', index);
$li.click(function () {
self.stopClock();
if (self.options.resetTimerOnClick) {
self.rotateTimer(true);
self.startClock();
}
self.$element.trigger('orbit.goto', [$li.data('index')])
});
},
setActiveBullet: function () {
if(!this.options.bullets) { return false; } else {
this.$bullets.find('li')
.removeClass('active')
.eq(this.activeSlide)
.addClass('active');
}
},
resetAndUnlock: function () {
this.$slides
.eq(this.prevActiveSlide)
.css({"z-index" : 1});
this.unlock();
this.options.afterSlideChange.call(this, this.$slides.eq(this.prevActiveSlide), this.$slides.eq(this.activeSlide));
},
shift: function (direction) {
var slideDirection = direction;
//remember previous activeSlide
this.prevActiveSlide = this.activeSlide;
//exit function if bullet clicked is same as the current image
if (this.prevActiveSlide == slideDirection) { return false; }
if (this.$slides.length == "1") { return false; }
if (!this.locked) {
this.lock();
//deduce the proper activeImage
if (direction == "next") {
this.activeSlide++;
if (this.activeSlide == this.numberSlides) {
this.activeSlide = 0;
}
} else if (direction == "prev") {
this.activeSlide--
if (this.activeSlide < 0) {
this.activeSlide = this.numberSlides - 1;
}
} else {
this.activeSlide = direction;
if (this.prevActiveSlide < this.activeSlide) {
slideDirection = "next";
} else if (this.prevActiveSlide > this.activeSlide) {
slideDirection = "prev"
}
}
//set to correct bullet
this.setActiveBullet();
//set previous slide z-index to one below what new activeSlide will be
this.$slides
.eq(this.prevActiveSlide)
.css({"z-index" : 2});
//fade
if (this.options.animation == "fade") {
this.$slides
.eq(this.activeSlide)
.css({"opacity" : 0, "z-index" : 3})
.animate({"opacity" : 1}, this.options.animationSpeed, this.resetAndUnlock);
}
//horizontal-slide
if (this.options.animation == "horizontal-slide") {
if (slideDirection == "next") {
this.$slides
.eq(this.activeSlide)
.css({"left": this.orbitWidth, "z-index" : 3})
.animate({"left" : 0}, this.options.animationSpeed, this.resetAndUnlock);
}
if (slideDirection == "prev") {
this.$slides
.eq(this.activeSlide)
.css({"left": -this.orbitWidth, "z-index" : 3})
.animate({"left" : 0}, this.options.animationSpeed, this.resetAndUnlock);
}
}
//vertical-slide
if (this.options.animation == "vertical-slide") {
if (slideDirection == "prev") {
this.$slides
.eq(this.activeSlide)
.css({"top": this.orbitHeight, "z-index" : 3})
.animate({"top" : 0}, this.options.animationSpeed, this.resetAndUnlock);
}
if (slideDirection == "next") {
this.$slides
.eq(this.activeSlide)
.css({"top": -this.orbitHeight, "z-index" : 3})
.animate({"top" : 0}, this.options.animationSpeed, this.resetAndUnlock);
}
}
//horizontal-push
if (this.options.animation == "horizontal-push") {
if (slideDirection == "next") {
this.$slides
.eq(this.activeSlide)
.css({"left": this.orbitWidth, "z-index" : 3})
.animate({"left" : 0}, this.options.animationSpeed, this.resetAndUnlock);
this.$slides
.eq(this.prevActiveSlide)
.animate({"left" : -this.orbitWidth}, this.options.animationSpeed);
}
if (slideDirection == "prev") {
this.$slides
.eq(this.activeSlide)
.css({"left": -this.orbitWidth, "z-index" : 3})
.animate({"left" : 0}, this.options.animationSpeed, this.resetAndUnlock);
this.$slides
.eq(this.prevActiveSlide)
.animate({"left" : this.orbitWidth}, this.options.animationSpeed);
}
}
//vertical-push
if (this.options.animation == "vertical-push") {
if (slideDirection == "next") {
this.$slides
.eq(this.activeSlide)
.css({top: -this.orbitHeight, "z-index" : 3})
.animate({top : 0}, this.options.animationSpeed, this.resetAndUnlock);
this.$slides
.eq(this.prevActiveSlide)
.animate({top : this.orbitHeight}, this.options.animationSpeed);
}
if (slideDirection == "prev") {
this.$slides
.eq(this.activeSlide)
.css({top: this.orbitHeight, "z-index" : 3})
.animate({top : 0}, this.options.animationSpeed, this.resetAndUnlock);
this.$slides
.eq(this.prevActiveSlide)
.animate({top : -this.orbitHeight}, this.options.animationSpeed);
}
}
this.setCaption();
}
}
};
$.fn.orbit = function (options) {
return this.each(function () {
var orbit = $.extend({}, ORBIT);
orbit.init(this, options);
});
};
})(jQuery);
/*!
* jQuery imageready Plugin
* http://www.zurb.com/playground/
*
* Copyright 2011, ZURB
* Released under the MIT License
*/
(function ($) {
var options = {};
$.event.special.imageready = {
setup: function (data, namespaces, eventHandle) {
options = data || options;
},
add: function (handleObj) {
var $this = $(this),
src;
if ( this.nodeType === 1 && this.tagName.toLowerCase() === 'img' && this.src !== '' ) {
if (options.forceLoad) {
src = $this.attr('src');
$this.attr('src', '');
bindToLoad(this, handleObj.handler);
$this.attr('src', src);
} else if ( this.complete || this.readyState === 4 ) {
handleObj.handler.apply(this, arguments);
} else {
bindToLoad(this, handleObj.handler);
}
}
},
teardown: function (namespaces) {
$(this).unbind('.imageready');
}
};
function bindToLoad(element, callback) {
var $this = $(element);
$this.bind('load.imageready', function () {
callback.apply(element, arguments);
$this.unbind('load.imageready');
});
}
}(jQuery));

View File

@@ -1,773 +0,0 @@
/*
* jQuery Reveal Plugin 1.1
* www.ZURB.com
* Copyright 2010, ZURB
* Free to use under the MIT license.
* http://www.opensource.org/licenses/mit-license.php
*/
/*globals jQuery */
(function ($) {
'use strict';
//
// Global variable.
// Helps us determine if the current modal is being queued for display.
//
var modalQueued = false;
//
// Bind the live 'click' event to all anchor elemnets with the data-reveal-id attribute.
//
$(document).on('click', 'a[data-reveal-id]', function ( event ) {
//
// Prevent default action of the event.
//
event.preventDefault();
//
// Get the clicked anchor data-reveal-id attribute value.
//
var modalLocation = $( this ).attr( 'data-reveal-id' );
//
// Find the element with that modalLocation id and call the reveal plugin.
//
$( '#' + modalLocation ).reveal( $( this ).data() );
});
/**
* @module reveal
* @property {Object} [options] Reveal options
*/
$.fn.reveal = function ( options ) {
/*
* Cache the document object.
*/
var $doc = $( document ),
/*
* Default property values.
*/
defaults = {
/**
* Possible options: fade, fadeAndPop, none
*
* @property animation
* @type {String}
* @default fadeAndPop
*/
animation: 'fadeAndPop',
/**
* Speed at which the reveal should show. How fast animtions are.
*
* @property animationSpeed
* @type {Integer}
* @default 300
*/
animationSpeed: 300,
/**
* Should the modal close when the background is clicked?
*
* @property closeOnBackgroundClick
* @type {Boolean}
* @default true
*/
closeOnBackgroundClick: true,
/**
* Specify a class name for the 'close modal' element.
* This element will close an open modal.
*
@example
<a href='#close' class='close-reveal-modal'>Close Me</a>
*
* @property dismissModalClass
* @type {String}
* @default close-reveal-modal
*/
dismissModalClass: 'close-reveal-modal',
/**
* Specify a callback function that triggers 'before' the modal opens.
*
* @property open
* @type {Function}
* @default function(){}
*/
open: $.noop,
/**
* Specify a callback function that triggers 'after' the modal is opened.
*
* @property opened
* @type {Function}
* @default function(){}
*/
opened: $.noop,
/**
* Specify a callback function that triggers 'before' the modal prepares to close.
*
* @property close
* @type {Function}
* @default function(){}
*/
close: $.noop,
/**
* Specify a callback function that triggers 'after' the modal is closed.
*
* @property closed
* @type {Function}
* @default function(){}
*/
closed: $.noop
}
;
//
// Extend the default options.
// This replaces the passed in option (options) values with default values.
//
options = $.extend( {}, defaults, options );
//
// Apply the plugin functionality to each element in the jQuery collection.
//
return this.each( function () {
//
// Cache the modal element
//
var modal = $( this ),
//
// Get the current css 'top' property value in decimal format.
//
topMeasure = parseInt( modal.css( 'top' ), 10 ),
//
// Calculate the top offset.
//
topOffset = modal.height() + topMeasure,
//
// Helps determine if the modal is locked.
// This way we keep the modal from triggering while it's in the middle of animating.
//
locked = false,
//
// Get the modal background element.
//
modalBg = $( '.reveal-modal-bg' ),
//
// Show modal properties
//
cssOpts = {
//
// Used, when we show the modal.
//
open : {
//
// Set the 'top' property to the document scroll minus the calculated top offset.
//
'top': 0,
//
// Opacity gets set to 0.
//
'opacity': 0,
//
// Show the modal
//
'visibility': 'visible',
//
// Ensure it's displayed as a block element.
//
'display': 'block'
},
//
// Used, when we hide the modal.
//
close : {
//
// Set the default 'top' property value.
//
'top': topMeasure,
//
// Has full opacity.
//
'opacity': 1,
//
// Hide the modal
//
'visibility': 'hidden',
//
// Ensure the elment is hidden.
//
'display': 'none'
}
},
//
// Initial closeButton variable.
//
$closeButton
;
//
// Do we have a modal background element?
//
if ( modalBg.length === 0 ) {
//
// No we don't. So, let's create one.
//
modalBg = $( '<div />', { 'class' : 'reveal-modal-bg' } )
//
// Then insert it after the modal element.
//
.insertAfter( modal );
//
// Now, fade it out a bit.
//
modalBg.fadeTo( 'fast', 0.8 );
}
//
// Helper Methods
//
/**
* Unlock the modal for animation.
*
* @method unlockModal
*/
function unlockModal() {
locked = false;
}
/**
* Lock the modal to prevent further animation.
*
* @method lockModal
*/
function lockModal() {
locked = true;
}
/**
* Closes all open modals.
*
* @method closeOpenModal
*/
function closeOpenModals() {
//
// Get all reveal-modal elements with the .open class.
//
var $openModals = $( ".reveal-modal.open" );
//
// Do we have modals to close?
//
if ( $openModals.length === 1 ) {
//
// Set the modals for animation queuing.
//
modalQueued = true;
//
// Trigger the modal close event.
//
$openModals.trigger( "reveal:close" );
}
}
/**
* Animates the modal opening.
* Handles the modal 'open' event.
*
* @method openAnimation
*/
function openAnimation() {
//
// First, determine if we're in the middle of animation.
//
if ( !locked ) {
//
// We're not animating, let's lock the modal for animation.
//
lockModal();
//
// Close any opened modals.
//
closeOpenModals();
//
// Now, add the open class to this modal.
//
modal.addClass( "open" );
//
// Are we executing the 'fadeAndPop' animation?
//
if ( options.animation === "fadeAndPop" ) {
//
// Yes, we're doing the 'fadeAndPop' animation.
// Okay, set the modal css properties.
//
//
// Set the 'top' property to the document scroll minus the calculated top offset.
//
cssOpts.open.top = $doc.scrollTop() - topOffset;
//
// Flip the opacity to 0.
//
cssOpts.open.opacity = 0;
//
// Set the css options.
//
modal.css( cssOpts.open );
//
// Fade in the background element, at half the speed of the modal element.
// So, faster than the modal element.
//
modalBg.fadeIn( options.animationSpeed / 2 );
//
// Let's delay the next animation queue.
// We'll wait until the background element is faded in.
//
modal.delay( options.animationSpeed / 2 )
//
// Animate the following css properties.
//
.animate( {
//
// Set the 'top' property to the document scroll plus the calculated top measure.
//
"top": $doc.scrollTop() + topMeasure + 'px',
//
// Set it to full opacity.
//
"opacity": 1
},
/*
* Fade speed.
*/
options.animationSpeed,
/*
* End of animation callback.
*/
function () {
//
// Trigger the modal reveal:opened event.
// This should trigger the functions set in the options.opened property.
//
modal.trigger( 'reveal:opened' );
}); // end of animate.
} // end if 'fadeAndPop'
//
// Are executing the 'fade' animation?
//
if ( options.animation === "fade" ) {
//
// Yes, were executing 'fade'.
// Okay, let's set the modal properties.
//
cssOpts.open.top = $doc.scrollTop() + topMeasure;
//
// Flip the opacity to 0.
//
cssOpts.open.opacity = 0;
//
// Set the css options.
//
modal.css( cssOpts.open );
//
// Fade in the modal background at half the speed of the modal.
// So, faster than modal.
//
modalBg.fadeIn( options.animationSpeed / 2 );
//
// Delay the modal animation.
// Wait till the modal background is done animating.
//
modal.delay( options.animationSpeed / 2 )
//
// Now animate the modal.
//
.animate( {
//
// Set to full opacity.
//
"opacity": 1
},
/*
* Animation speed.
*/
options.animationSpeed,
/*
* End of animation callback.
*/
function () {
//
// Trigger the modal reveal:opened event.
// This should trigger the functions set in the options.opened property.
//
modal.trigger( 'reveal:opened' );
});
} // end if 'fade'
//
// Are we not animating?
//
if ( options.animation === "none" ) {
//
// We're not animating.
// Okay, let's set the modal css properties.
//
//
// Set the top property.
//
cssOpts.open.top = $doc.scrollTop() + topMeasure;
//
// Set the opacity property to full opacity, since we're not fading (animating).
//
cssOpts.open.opacity = 1;
//
// Set the css property.
//
modal.css( cssOpts.open );
//
// Show the modal Background.
//
modalBg.css( { "display": "block" } );
//
// Trigger the modal opened event.
//
modal.trigger( 'reveal:opened' );
} // end if animating 'none'
}// end if !locked
}// end openAnimation
//
// Bind the reveal 'open' event.
// When the event is triggered, openAnimation is called
// along with any function set in the options.open property.
//
modal.bind( 'reveal:open.reveal', openAnimation );
/**
* Closes the modal element(s)
* Handles the modal 'close' event.
*
* @method closeAnimation
*/
function closeAnimation() {
//
// First, determine if we're in the middle of animation.
//
if ( !locked ) {
//
// We're not animating, let's lock the modal for animation.
//
lockModal();
//
// Clear the modal of the open class.
//
modal.removeClass( "open" );
//
// Are we using the 'fadeAndPop' animation?
//
if ( options.animation === "fadeAndPop" ) {
//
// Yes, okay, let's set the animation properties.
//
modal.animate( {
//
// Set the top property to the document scrollTop minus calculated topOffset.
//
"top": $doc.scrollTop() - topOffset + 'px',
//
// Fade the modal out, by using the opacity property.
//
"opacity": 0
},
/*
* Fade speed.
*/
options.animationSpeed / 2,
/*
* End of animation callback.
*/
function () {
//
// Set the css hidden options.
//
modal.css( cssOpts.close );
});
//
// Is the modal animation queued?
//
if ( !modalQueued ) {
//
// Oh, the modal(s) are mid animating.
// Let's delay the animation queue.
//
modalBg.delay( options.animationSpeed )
//
// Fade out the modal background.
//
.fadeOut(
/*
* Animation speed.
*/
options.animationSpeed,
/*
* End of animation callback.
*/
function () {
//
// Trigger the modal 'closed' event.
// This should trigger any method set in the options.closed property.
//
modal.trigger( 'reveal:closed' );
});
} else {
//
// We're not mid queue.
// Trigger the modal 'closed' event.
// This should trigger any method set in the options.closed propety.
//
modal.trigger( 'reveal:closed' );
} // end if !modalQueued
//
// Reset the modalQueued variable.
//
modalQueued = false;
} // end if animation 'fadeAndPop'
//
// Are we using the 'fade' animation.
//
if ( options.animation === "fade" ) {
//
// Yes, we're using the 'fade' animation.
//
modal.animate( { "opacity" : 0 },
/*
* Animation speed.
*/
options.animationSpeed,
/*
* End of animation callback.
*/
function () {
//
// Set the css close options.
//
modal.css( cssOpts.close );
}); // end animate
//
// Are we mid animating the modal(s)?
//
if ( !modalQueued ) {
//
// Oh, the modal(s) are mid animating.
// Let's delay the animation queue.
//
modalBg.delay( options.animationSpeed )
//
// Let's fade out the modal background element.
//
.fadeOut(
/*
* Animation speed.
*/
options.animationSpeed,
/*
* End of animation callback.
*/
function () {
//
// Trigger the modal 'closed' event.
// This should trigger any method set in the options.closed propety.
//
modal.trigger( 'reveal:closed' );
}); // end fadeOut
} else {
//
// We're not mid queue.
// Trigger the modal 'closed' event.
// This should trigger any method set in the options.closed propety.
//
modal.trigger( 'reveal:closed' );
} // end if !modalQueued
} // end if animation 'fade'
//
// Are we not animating?
//
if ( options.animation === "none" ) {
//
// We're not animating.
// Set the modal close css options.
//
modal.css( cssOpts.close );
//
// Is the modal in the middle of an animation queue?
//
if ( !modalQueued ) {
//
// It's not mid queueu. Just hide it.
//
modalBg.css( { 'display': 'none' } );
}
//
// Trigger the modal 'closed' event.
// This should trigger any method set in the options.closed propety.
//
modal.trigger( 'reveal:closed' );
} // end if not animating
} // end if !locked
} // end closeAnimation
/**
* Destroys the modal and it's events.
*
* @method destroy
*/
function destroy() {
//
// Unbind all .reveal events from the modal.
//
modal.unbind( '.reveal' );
//
// Unbind all .reveal events from the modal background.
//
modalBg.unbind( '.reveal' );
//
// Unbind all .reveal events from the modal 'close' button.
//
$closeButton.unbind( '.reveal' );
//
// Unbind all .reveal events from the body.
//
$( 'body' ).unbind( '.reveal' );
}
//
// Bind the modal 'close' event
//
modal.bind( 'reveal:close.reveal', closeAnimation );
//
// Bind the modal 'opened' + 'closed' event
// Calls the unlockModal method.
//
modal.bind( 'reveal:opened.reveal reveal:closed.reveal', unlockModal );
//
// Bind the modal 'closed' event.
// Calls the destroy method.
//
modal.bind( 'reveal:closed.reveal', destroy );
//
// Bind the modal 'open' event
// Handled by the options.open property function.
//
modal.bind( 'reveal:open.reveal', options.open );
//
// Bind the modal 'opened' event.
// Handled by the options.opened property function.
//
modal.bind( 'reveal:opened.reveal', options.opened );
//
// Bind the modal 'close' event.
// Handled by the options.close property function.
//
modal.bind( 'reveal:close.reveal', options.close );
//
// Bind the modal 'closed' event.
// Handled by the options.closed property function.
//
modal.bind( 'reveal:closed.reveal', options.closed );
//
// We're running this for the first time.
// Trigger the modal 'open' event.
//
modal.trigger( 'reveal:open' );
//
// Get the closeButton variable element(s).
//
$closeButton = $( '.' + options.dismissModalClass )
//
// Bind the element 'click' event and handler.
//
.bind( 'click.reveal', function () {
//
// Trigger the modal 'close' event.
//
modal.trigger( 'reveal:close' );
});
//
// Should we close the modal background on click?
//
if ( options.closeOnBackgroundClick ) {
//
// Yes, close the modal background on 'click'
// Set the modal background css 'cursor' propety to pointer.
// Adds a pointer symbol when you mouse over the modal background.
//
modalBg.css( { "cursor": "pointer" } );
//
// Bind a 'click' event handler to the modal background.
//
modalBg.bind( 'click.reveal', function () {
//
// Trigger the modal 'close' event.
//
modal.trigger( 'reveal:close' );
});
}
//
// Bind keyup functions on the body element.
// We'll want to close the modal when the 'escape' key is hit.
//
$( 'body' ).bind( 'keyup.reveal', function ( event ) {
//
// Did the escape key get triggered?
//
if ( event.which === 27 ) { // 27 is the keycode for the Escape key
//
// Escape key was triggered.
// Trigger the modal 'close' event.
//
modal.trigger( 'reveal:close' );
}
}); // end $(body)
}); // end this.each
}; // end $.fn
} ( jQuery ) );

View File

@@ -1,36 +0,0 @@
(function ($) {
$.fn.foundationTabs = function (options) {
var settings = $.extend({
callback: $.noop
}, options);
var activateTab = function ($tab) {
var $activeTab = $tab.closest('dl').find('dd.active'),
contentLocation = $tab.children('a').attr("href") + 'Tab';
// Strip off the current url that IE adds
contentLocation = contentLocation.replace(/^.+#/, '#');
//Make Tab Active
$activeTab.removeClass('active');
$tab.addClass('active');
//Show Tab Content
$(contentLocation).closest('.tabs-content').children('li').removeClass('active').hide();
$(contentLocation).css('display', 'block').addClass('active');
};
$(document).on('click.fndtn', 'dl.tabs dd a', function (event){
activateTab($(this).parent('dd'));
});
if (window.location.hash) {
activateTab($('a[href="' + window.location.hash + '"]').parent('dd'));
settings.callback();
}
};
})(jQuery);

View File

@@ -1,183 +0,0 @@
/*
* jQuery Foundation Tooltip Plugin 2.0.1
* http://foundation.zurb.com
* Copyright 2012, ZURB
* Free to use under the MIT license.
* http://www.opensource.org/licenses/mit-license.php
*/
/*jslint unparam: true, browser: true, indent: 2 */
;(function ($) {
'use strict';
var settings = {
bodyHeight : 0,
targetClass : '.has-tip',
tooltipClass : '.tooltip',
tipTemplate : function (selector, content) {
return '<span data-selector="' + selector + '" class="' + settings.tooltipClass.substring(1) + '">' + content + '<span class="nub"></span></span>';
}
},
methods = {
init : function (options) {
return this.each(function () {
var $body = $('body');
if (Modernizr.touch) {
$body.on('click.tooltip touchstart.tooltip touchend.tooltip', settings.targetClass, function (e) {
e.preventDefault();
$(settings.tooltipClass).hide();
methods.showOrCreateTip($(this));
});
$body.on('click.tooltip touchstart.tooltip touchend.tooltip', settings.tooltipClass, function (e) {
e.preventDefault();
$(this).fadeOut(150);
});
} else {
$body.on('mouseenter.tooltip mouseleave.tooltip', settings.targetClass, function (e) {
var $this = $(this);
if (e.type === 'mouseenter') {
methods.showOrCreateTip($this);
} else if (e.type === 'mouseleave') {
methods.hide($this);
}
});
}
});
},
showOrCreateTip : function ($target) {
var $tip = methods.getTip($target);
if ($tip && $tip.length > 0) {
methods.show($target);
} else {
methods.create($target);
}
},
getTip : function ($target) {
var selector = methods.selector($target),
tip = null;
if (selector) {
tip = $('span[data-selector=' + selector + ']' + settings.tooltipClass);
}
return (tip.length > 0) ? tip : false;
},
selector : function ($target) {
var id = $target.attr('id'),
dataSelector = $target.data('selector');
if (id === undefined && dataSelector === undefined) {
dataSelector = 'tooltip' + Math.random().toString(36).substring(7);
$target.attr('data-selector', dataSelector);
}
return (id) ? id : dataSelector;
},
create : function ($target) {
var $tip = $(settings.tipTemplate(methods.selector($target), $('<div>').text($target.attr('title')).html())),
classes = methods.inheritable_classes($target);
$tip.addClass(classes).appendTo('body');
if (Modernizr.touch) {
$tip.append('<span class="tap-to-close">tap to close </span>');
}
$target.removeAttr('title');
methods.show($target);
},
reposition : function (target, tip, classes) {
var width, nub, nubHeight, nubWidth, column, objPos;
tip.css('visibility', 'hidden').show();
width = target.data('width');
nub = tip.children('.nub');
nubHeight = nub.outerHeight();
nubWidth = nub.outerWidth();
objPos = function (obj, top, right, bottom, left, width) {
return obj.css({
'top' : top,
'bottom' : bottom,
'left' : left,
'right' : right,
'width' : (width) ? width : 'auto'
}).end();
};
objPos(tip, (target.offset().top + target.outerHeight() + 10), 'auto', 'auto', target.offset().left, width);
objPos(nub, -nubHeight, 'auto', 'auto', 10);
if ($(window).width() < 767) {
column = target.closest('.columns');
if (column.length < 0) {
// if not using Foundation
column = $('body');
}
tip.width(column.outerWidth() - 25).css('left', 15).addClass('tip-override');
objPos(nub, -nubHeight, 'auto', 'auto', target.offset().left);
} else {
if (classes.indexOf('tip-top') > -1) {
objPos(tip, (target.offset().top - tip.outerHeight() - nubHeight), 'auto', 'auto', target.offset().left, width)
.removeClass('tip-override');
objPos(nub, 'auto', 'auto', -nubHeight, 'auto');
} else if (classes.indexOf('tip-left') > -1) {
objPos(tip, (target.offset().top + (target.outerHeight() / 2) - nubHeight), 'auto', 'auto', (target.offset().left - tip.outerWidth() - 10), width)
.removeClass('tip-override');
objPos(nub, (tip.outerHeight() / 2) - (nubHeight / 2), -nubHeight, 'auto', 'auto');
} else if (classes.indexOf('tip-right') > -1) {
objPos(tip, (target.offset().top + (target.outerHeight() / 2) - nubHeight), 'auto', 'auto', (target.offset().left + target.outerWidth() + 10), width)
.removeClass('tip-override');
objPos(nub, (tip.outerHeight() / 2) - (nubHeight / 2), 'auto', 'auto', -nubHeight);
}
}
tip.css('visibility', 'visible').hide();
},
inheritable_classes : function (target) {
var inheritables = ['tip-top', 'tip-left', 'tip-bottom', 'tip-right', 'noradius'],
filtered = target.attr('class').split(' ').map(function (el, i) {
if ($.inArray(el, inheritables) !== -1) {
return el;
}
}).join(' ');
return $.trim(filtered);
},
show : function ($target) {
var $tip = methods.getTip($target);
methods.reposition($target, $tip, $target.attr('class'));
$tip.fadeIn(150);
},
hide : function ($target) {
var $tip = methods.getTip($target);
$tip.fadeOut(150);
},
reload : function () {
var $self = $(this);
return ($self.data('tooltips')) ? $self.tooltips('destroy').tooltips('init') : $self.tooltips('init');
},
destroy : function () {
return this.each(function () {
$(window).off('.tooltip');
$(settings.targetClass).off('.tooltip');
$(settings.tooltipClass).each(function (i) {
$($(settings.targetClass).get(i)).attr('title', $(this).text());
}).remove();
});
}
};
$.fn.tooltips = 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 on jQuery.tooltips');
}
};
}(jQuery));

View File

File diff suppressed because it is too large Load Diff

View File

@@ -1,50 +0,0 @@
(function ($) {
// Set the negative margin on the top menu for slide-menu pages
var $selector1 = $('#topMenu'),
events = 'click.fndtn';
if ($selector1.length > 0) $selector1.css("margin-top", $selector1.height() * -1);
// Watch for clicks to show the sidebar
var $selector2 = $('#sidebarButton');
if ($selector2.length > 0) {
$('#sidebarButton').on(events, function (e) {
e.preventDefault();
$('body').toggleClass('active');
});
}
// Watch for clicks to show the menu for slide-menu pages
var $selector3 = $('#menuButton');
if ($selector3.length > 0) {
$('#menuButton').on(events, function (e) {
e.preventDefault();
$('body').toggleClass('active-menu');
});
}
// // Adjust sidebars and sizes when resized
// $(window).resize(function() {
// // if (!navigator.userAgent.match(/Android/i)) $('body').removeClass('active');
// var $selector4 = $('#topMenu');
// if ($selector4.length > 0) $selector4.css("margin-top", $selector4.height() * -1);
// });
// Switch panels for the paneled nav on mobile
var $selector5 = $('#switchPanels');
if ($selector5.length > 0) {
$('#switchPanels dd').on(events, function (e) {
e.preventDefault();
var switchToPanel = $(this).children('a').attr('href'),
switchToIndex = $(switchToPanel).index();
$(this).toggleClass('active').siblings().removeClass('active');
$(switchToPanel).parent().css("left", (switchToIndex * (-100) + '%'));
});
}
$('#nav li a').on(events, function (e) {
e.preventDefault();
var href = $(this).attr('href'),
$target = $(href);
$('html, body').animate({scrollTop : $target.offset().top}, 300);
});
});

View File

@@ -1,157 +0,0 @@
/*! http://mths.be/placeholder v2.0.7 by @mathias */
;(function(window, document, $) {
var isInputSupported = 'placeholder' in document.createElement('input'),
isTextareaSupported = 'placeholder' in document.createElement('textarea'),
prototype = $.fn,
valHooks = $.valHooks,
hooks,
placeholder;
if (isInputSupported && isTextareaSupported) {
placeholder = prototype.placeholder = function() {
return this;
};
placeholder.input = placeholder.textarea = true;
} else {
placeholder = prototype.placeholder = function() {
var $this = this;
$this
.filter((isInputSupported ? 'textarea' : ':input') + '[placeholder]')
.not('.placeholder')
.bind({
'focus.placeholder': clearPlaceholder,
'blur.placeholder': setPlaceholder
})
.data('placeholder-enabled', true)
.trigger('blur.placeholder');
return $this;
};
placeholder.input = isInputSupported;
placeholder.textarea = isTextareaSupported;
hooks = {
'get': function(element) {
var $element = $(element);
return $element.data('placeholder-enabled') && $element.hasClass('placeholder') ? '' : element.value;
},
'set': function(element, value) {
var $element = $(element);
if (!$element.data('placeholder-enabled')) {
return element.value = value;
}
if (value == '') {
element.value = value;
// Issue #56: Setting the placeholder causes problems if the element continues to have focus.
if (element != document.activeElement) {
// We can't use `triggerHandler` here because of dummy text/password inputs :(
setPlaceholder.call(element);
}
} else if ($element.hasClass('placeholder')) {
clearPlaceholder.call(element, true, value) || (element.value = value);
} else {
element.value = value;
}
// `set` can not return `undefined`; see http://jsapi.info/jquery/1.7.1/val#L2363
return $element;
}
};
isInputSupported || (valHooks.input = hooks);
isTextareaSupported || (valHooks.textarea = hooks);
$(function() {
// Look for forms
$(document).delegate('form', 'submit.placeholder', function() {
// Clear the placeholder values so they don't get submitted
var $inputs = $('.placeholder', this).each(clearPlaceholder);
setTimeout(function() {
$inputs.each(setPlaceholder);
}, 10);
});
});
// Clear placeholder values upon page reload
$(window).bind('beforeunload.placeholder', function() {
$('.placeholder').each(function() {
this.value = '';
});
});
}
function args(elem) {
// Return an object of element attributes
var newAttrs = {},
rinlinejQuery = /^jQuery\d+$/;
$.each(elem.attributes, function(i, attr) {
if (attr.specified && !rinlinejQuery.test(attr.name)) {
newAttrs[attr.name] = attr.value;
}
});
return newAttrs;
}
function clearPlaceholder(event, value) {
var input = this,
$input = $(input);
if (input.value == $input.attr('placeholder') && $input.hasClass('placeholder')) {
if ($input.data('placeholder-password')) {
$input = $input.hide().next().show().attr('id', $input.removeAttr('id').data('placeholder-id'));
// If `clearPlaceholder` was called from `$.valHooks.input.set`
if (event === true) {
return $input[0].value = value;
}
$input.focus();
} else {
input.value = '';
$input.removeClass('placeholder');
input == document.activeElement && input.select();
}
}
}
function setPlaceholder() {
var $replacement,
input = this,
$input = $(input),
$origInput = $input,
id = this.id;
if (input.value == '') {
if (input.type == 'password') {
if (!$input.data('placeholder-textinput')) {
try {
$replacement = $input.clone().attr({ 'type': 'text' });
} catch(e) {
$replacement = $('<input>').attr($.extend(args(this), { 'type': 'text' }));
}
$replacement
.removeAttr('name')
.data({
'placeholder-password': true,
'placeholder-id': id
})
.bind('focus.placeholder', clearPlaceholder);
$input
.data({
'placeholder-textinput': $replacement,
'placeholder-id': id
})
.before($replacement);
}
$input = $input.removeAttr('id').hide().prev().attr('id', id).show();
// Note: `$input[0] != input` now!
}
$input.addClass('placeholder');
$input[0].value = $input.attr('placeholder');
} else {
$input.removeClass('placeholder');
}
}
}(this, document, jQuery));

View File

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,3 @@
# Place all the behaviors and hooks related to the matching controller here.
# All this logic will automatically be available in application.js.
# You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/

View File

@@ -0,0 +1,3 @@
# Place all the behaviors and hooks related to the matching controller here.
# All this logic will automatically be available in application.js.
# You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/

View File

@@ -1,76 +0,0 @@
@import "foundation/common/ratios";
// Settings file containing Foundation defaults
// Grid Settings
// $rowWidth: 1000px;
// $columnGutter: 30px;
// $totalColumns: 12;
// $mobileTotalColumns: 4;
// Colors Settings
$mainColor: #009900;
// $secondaryColor: #e9e9e9;
// $alertColor: #c60f13;
// $successColor: #5da423;
// $txtColor: #222;
// $highlightColor: #ffff99;
// $black: #000;
// $white: #fff;
// $shinyEdge: rgba(#fff, .5);
// $darkEdge: rgba(#000, .2);
// Typography Settings
$headerFontFamily: "Sevillana", "Helvetica Neue", "Helvetica", Helvetica, Arial, sans-serif;
$headerFontWeight: normal;
// $headerFontColor: #222;
// $bodyFontFamily: "Helvetica Neue", "Helvetica", Helvetica, Arial, sans-serif;
// $bodyFontWeight: normal;
// $bodyFontColor: #222;
// Button Settings
// $buttonRadius: 3px;
// $btnBase: 10px;
// $tinyBtnBase: $btnBase - 5;
// $smallBtnBase: $btnBase - 3;
// $largeBtnBase: $btnBase + 5;
// Form Settings
// $formSpacing: 12px;
// Tab Settings
// $tabHeight: 40px;
// Nav Bar Settings
// $navBarHeight: 40px;
// $navFlyoutBaseWidth: 250px;
// Modular Scale
// $ratio: $golden;
// $baseFontSize: 14px;
// $importantModNum: 44px;
// Tooltip Settings
// $hasTipBorderBottom: dotted 1px #ccc;
// $hasTipFontWeight: bold;
// $hasTipFontColor: #333;
// $hasTipBorderBottomHover: dotted 1px darken($mainColor, 20%);
// $hasTipFontColorHover: $mainColor;
// $tooltipBackgroundColor: #000;
// $tooltipBackgroundOpacity: 0.85;
// $tooltipFontSize: 12;
// $tooltipFontWeight: bold;
// $tooltipFontColor: #fff;
// $tapToCloseFontSize: 10;
// $tapToCloseFontWeight: normal;
// $tapToCloseFontColor: #888;
// $tooltipFontSizeScreenSmall: 14;
// $tooltipBackgroundOpacityScreenSmall: 0.85;

View File

@@ -1,46 +0,0 @@
// You custom settings file to override Foundation defaults
@import "settings";
// Comment out this import if you are customizing you imports below
@import "foundation";
// ----------------------------------------
// Import specific parts of Foundation by commenting the import "foundation"
// and uncommenting what you want below. You must uncomment the following if customizing
// @import "compass/css3";
// @import "foundation/settings";
// @import "foundation/functions/all";
// @import "foundation/common/globals";
// @import "foundation/mixins/clearfix";
// @import "modular-scale";
// Control which mixins you have access too
// @import "foundation/mixins/css-triangle";
// @import "foundation/mixins/font-size";
// Must include next two for semantic grid to work
// @import "foundation/mixins/respond-to";
// @import "foundation/mixins/semantic-grid";
// Must include the grid for any responsiveness
// @import "foundation/components/grid";
// Control which common styles get compiled
// @import "foundation/common/typography";
// @import "foundation/common/forms";
// Control which components you get if customizing
// @import "foundation/components/modules/buttons";
// @import "foundation/components/modules/tabs";
// @import "foundation/components/modules/ui";
// @import "foundation/components/modules/navbar";
// @import "foundation/components/modules/orbit";
// @import "foundation/components/modules/reveal";
// @import "foundation/components/modules/offcanvas";

View File

@@ -0,0 +1,7 @@
/*
* This is a manifest file that'll automatically include all the stylesheets available in this directory
* and any sub-directories. You're free to add application-wide styles to this file and they'll appear at
* the top of the compiled file, but it's generally better to create a new file per style scope.
*= require_self
*= require_tree .
*/

View File

@@ -1,15 +0,0 @@
/*
* This is a manifest file that'll be compiled into application.css, which will include all the files
* listed below.
*
* Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
* or vendor/assets/stylesheets of plugins, if any, can be referenced here using a relative path.
*
* You're free to add application-wide styles to this file and they'll appear at the top of the
* compiled file, but it's generally better to create a new file per style scope.
*
*= require_self
*= require foundation_and_overrides
*= require_tree .
*/

View File

@@ -0,0 +1,34 @@
@import "twitter/bootstrap/bootstrap";
@import "twitter/bootstrap/responsive";
// Set the correct sprite paths
@iconSpritePath: asset-path("twitter/bootstrap/glyphicons-halflings");
@iconWhiteSpritePath: asset-path("twitter/bootstrap/glyphicons-halflings-white");
// Set the Font Awesome (Font Awesome is default. You can disable by commenting below lines)
// Note: If you use asset_path() here, your compiled boostrap_and_overrides.css will not
// have the proper paths. So for now we use the absolute path.
@fontAwesomeEotPath: asset-path("fontawesome-webfont.eot");
@fontAwesomeWoffPath: asset-path("fontawesome-webfont.woff");
@fontAwesomeTtfPath: asset-path("fontawesome-webfont.ttf");
@fontAwesomeSvgPath: asset-path("fontawesome-webfont.svg");
// Font Awesome
@import "fontawesome";
// Glyphicons
//@import "twitter/bootstrap/sprites.less";
// Your custom LESS stylesheets goes here
//
// Since bootstrap was imported above you have access to its mixins which
// you may use and inherit here
//
// If you'd like to override bootstrap's own variables, you can do so here as well
// See http://twitter.github.com/bootstrap/customize.html#variables for their names and documentation
//
// Example:
@linkColor: @green;
body {
padding-bottom: @navbarHeight + 10px;
}

View File

@@ -1,77 +0,0 @@
@import "foundation/common/ratios";
// Settings file containing Foundation defaults
// Grid Settings
// $rowWidth: 1000px;
// $columnGutter: 30px;
// $totalColumns: 12;
// $mobileTotalColumns: 4;
// Colors Settings
// $mainColor: #2ba6cb;
// $secondaryColor: #e9e9e9;
// $alertColor: #c60f13;
// $successColor: #5da423;
// $txtColor: #222;
// $highlightColor: #ffff99;
// $black: #000;
// $white: #fff;
// $shinyEdge: rgba(#fff, .5);
// $darkEdge: rgba(#000, .2);
// Typography Settings
// $headerFontFamily: "Helvetica Neue", "Helvetica", Helvetica, Arial, sans-serif;
// $headerFontWeight: bold;
// $headerFontColor: #222;
// $bodyFontFamily: "Helvetica Neue", "Helvetica", Helvetica, Arial, sans-serif;
// $bodyFontWeight: normal;
// $bodyFontColor: #222;
// Button Settings
// $buttonRadius: 3px;
// $btnBase: 10px;
// $tinyBtnBase: $btnBase - 5;
// $smallBtnBase: $btnBase - 3;
// $largeBtnBase: $btnBase + 5;
// Form Settings
// $formSpacing: 12px;
// Tab Settings
// $tabHeight: 40px;
// Nav Bar Settings
// $navBarHeight: 40px;
// $navFlyoutBaseWidth: 250px;
// Modular Scale
// $ratio: $golden;
// $baseFontSize: 14px;
// $importantModNum: 44px;
// Tooltip Settings
// $hasTipBorderBottom: dotted 1px #ccc;
// $hasTipFontWeight: bold;
// $hasTipFontColor: #333;
// $hasTipBorderBottomHover: dotted 1px darken($mainColor, 20%);
// $hasTipFontColorHover: $mainColor;
// $tooltipBackgroundColor: #000;
// $tooltipBackgroundOpacity: 0.85;
// $tooltipFontSize: 12;
// $tooltipFontWeight: bold;
// $tooltipFontColor: #fff;
// $tapToCloseFontSize: 10;
// $tapToCloseFontWeight: normal;
// $tapToCloseFontColor: #888;
// $tooltipFontSizeScreenSmall: 14;
// $tooltipBackgroundOpacityScreenSmall: 0.85;
@import 'foundation';

View File

@@ -1,3 +0,0 @@
// Place all the styles related to the home controller here.
// They will automatically be included in application.css.
// You can use Sass (SCSS) here: http://sass-lang.com/

View File

@@ -1,5 +0,0 @@
/* Welcome to Compass. Use this file to write IE specific override styles.
* Import this file using the following HTML or equivalent:
* <!--[if IE]>
* <link href="/stylesheets/ie.css" media="screen, projection" rel="stylesheet" type="text/css" />
* <![endif]--> */

View File

@@ -1,3 +0,0 @@
/* Welcome to Compass. Use this file to define print styles.
* Import this file using the following HTML or equivalent:
* <link href="/stylesheets/print.css" media="print" rel="stylesheet" type="text/css" /> */

View File

@@ -1,6 +0,0 @@
/* Welcome to Compass.
* In this file you should write your main styles. (or centralize your imports)
* Import this file using the following HTML or equivalent:
* <link href="/stylesheets/screen.css" media="screen, projection" rel="stylesheet" type="text/css" /> */
//@import "compass/reset";

View File

@@ -3,10 +3,12 @@ class CropsController < ApplicationController
# GET /crops.json
def index
@crops = Crop.all
@new_crops = Crop.limit(20).order('created_at desc').all
respond_to do |format|
format.html # index.html.erb
format.json { render json: @crops }
format.rss { render :layout => false }
end
end

View File

@@ -0,0 +1,25 @@
class MembersController < ApplicationController
def index
@members = User.all
respond_to do |format|
format.html # index.html.erb
format.json { render json: @members}
end
end
def show
@member = User.find(params[:id])
@updates = @member.updates
respond_to do |format|
format.html # show.html.erb
format.json { render json: @member }
format.rss { render(
:layout => false,
:locals => { :member => @member }
)}
end
end
end

View File

@@ -1,10 +0,0 @@
class ProfileController < ApplicationController
def show
@user = User.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.json { render json: @user }
end
end
end

View File

@@ -0,0 +1,83 @@
class ScientificNamesController < ApplicationController
# GET /scientific_names
# GET /scientific_names.json
def index
@scientific_names = ScientificName.all
respond_to do |format|
format.html # index.html.erb
format.json { render json: @scientific_names }
end
end
# GET /scientific_names/1
# GET /scientific_names/1.json
def show
@scientific_name = ScientificName.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.json { render json: @scientific_name }
end
end
# GET /scientific_names/new
# GET /scientific_names/new.json
def new
@scientific_name = ScientificName.new
respond_to do |format|
format.html # new.html.erb
format.json { render json: @scientific_name }
end
end
# GET /scientific_names/1/edit
def edit
@scientific_name = ScientificName.find(params[:id])
end
# POST /scientific_names
# POST /scientific_names.json
def create
@scientific_name = ScientificName.new(params[:scientific_name])
respond_to do |format|
if @scientific_name.save
format.html { redirect_to @scientific_name, notice: 'Scientific name was successfully created.' }
format.json { render json: @scientific_name, status: :created, location: @scientific_name }
else
format.html { render action: "new" }
format.json { render json: @scientific_name.errors, status: :unprocessable_entity }
end
end
end
# PUT /scientific_names/1
# PUT /scientific_names/1.json
def update
@scientific_name = ScientificName.find(params[:id])
respond_to do |format|
if @scientific_name.update_attributes(params[:scientific_name])
format.html { redirect_to @scientific_name, notice: 'Scientific name was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: "edit" }
format.json { render json: @scientific_name.errors, status: :unprocessable_entity }
end
end
end
# DELETE /scientific_names/1
# DELETE /scientific_names/1.json
def destroy
@scientific_name = ScientificName.find(params[:id])
@scientific_name.destroy
respond_to do |format|
format.html { redirect_to scientific_names_url }
format.json { head :no_content }
end
end
end

View File

@@ -0,0 +1,87 @@
class UpdatesController < ApplicationController
# GET /updates
# GET /updates.json
def index
@updates = Update.all
@recent_updates = Update.limit(100).order('created_at desc').all
respond_to do |format|
format.html # index.html.erb
format.json { render json: @updates }
format.rss { render :layout => false } #index.rss.builder
end
end
# GET /updates/1
# GET /updates/1.json
def show
@update = Update.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.json { render json: @update }
end
end
# GET /updates/new
# GET /updates/new.json
def new
@update = Update.new
respond_to do |format|
format.html # new.html.erb
format.json { render json: @update }
end
end
# GET /updates/1/edit
def edit
@update = Update.find(params[:id])
end
# POST /updates
# POST /updates.json
def create
params[:update][:user_id] = current_user.id
@update = Update.new(params[:update])
respond_to do |format|
if @update.save
format.html { redirect_to @update, notice: 'Update was successfully created.' }
format.json { render json: @update, status: :created, location: @update }
else
format.html { render action: "new" }
format.json { render json: @update.errors, status: :unprocessable_entity }
end
end
end
# PUT /updates/1
# PUT /updates/1.json
def update
@update = Update.find(params[:id])
respond_to do |format|
if @update.update_attributes(params[:update])
format.html { redirect_to @update, notice: 'Update was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: "edit" }
format.json { render json: @update.errors, status: :unprocessable_entity }
end
end
end
# DELETE /updates/1
# DELETE /updates/1.json
def destroy
@update = Update.find(params[:id])
@update.destroy
respond_to do |format|
format.html { redirect_to updates_url }
format.json { head :no_content }
end
end
end

View File

@@ -0,0 +1,2 @@
module ScientificNamesHelper
end

View File

@@ -0,0 +1,2 @@
module UpdatesHelper
end

View File

@@ -2,4 +2,5 @@ class Crop < ActiveRecord::Base
extend FriendlyId
friendly_id :system_name, use: :slugged
attr_accessible :en_wikipedia_url, :system_name
has_many :scientific_names
end

View File

@@ -0,0 +1,4 @@
class ScientificName < ActiveRecord::Base
attr_accessible :crop_id, :scientific_name
belongs_to :crop
end

5
app/models/update.rb Normal file
View File

@@ -0,0 +1,5 @@
class Update < ActiveRecord::Base
attr_accessible :body, :subject, :user_id
belongs_to :user
default_scope order("created_at desc")
end

View File

@@ -1,4 +1,8 @@
class User < ActiveRecord::Base
extend FriendlyId
friendly_id :username, use: :slugged
has_many :updates
has_many :gardens
# Include default devise modules. Others available are:

View File

@@ -2,10 +2,8 @@
- if user_signed_in?
= render 'form'
%ul.link-list
%li
= link_to 'Show', @crop, { :class => 'button' }
%li
= link_to 'Back', crops_path, { :class => 'button' }
%p
= link_to 'Show', @crop, { :class => 'btn' }
= link_to 'Back', crops_path, { :class => 'btn' }
- else
%div.alert-box.alert You're not logged in. Only logged in users can do this.
%div.alert You're not logged in. Only logged in users can do this.

View File

@@ -1,10 +1,22 @@
- content_for :title, "Crops"
- c = 0
%ul
%ul.thumbnails
.row
- @crops.each do |crop|
%li
= link_to crop.system_name, crop
- c += 1
%li.span2
.thumbnail(style='height: 200px')
= image_tag('http://placehold.it/150x150', :alt => '', :class => 'img-rounded')
%p= link_to crop.system_name, crop
- if crop.scientific_names.count > 0
%p
%i
%small
= crop.scientific_names.first.scientific_name
- if (c % 6) == 0
.row
- if user_signed_in?
%div
= link_to 'New Crop', new_crop_path, {:class => 'button'}
= link_to 'New Crop', new_crop_path, {:class => 'btn'}

View File

@@ -0,0 +1,16 @@
xml.instruct! :xml, :version => "1.0"
xml.rss :version => "2.0" do
xml.channel do
xml.title "Growstuff - Recently added crops"
xml.link crops_url
for crop in @new_crops
xml.item do
xml.title crop.system_name
xml.pubDate crop.created_at.to_s(:rfc822)
xml.link crop_url(crop)
xml.guid crop_url(crop)
end
end
end
end

View File

@@ -1,5 +1,11 @@
- content_for :title, "New crop"
= render 'form'
- if user_signed_in?
= render 'form'
%p
= link_to 'Show', @crop, { :class => 'btn' }
= link_to 'Back', crops_path, { :class => 'btn' }
- else
%div.alert You're not logged in. Only logged in users can do this.
= link_to 'Back', crops_path

View File

@@ -1,10 +1,28 @@
- content_for :title, @crop.system_name
%p
%b More information:
= link_to @crop.en_wikipedia_url, @crop.en_wikipedia_url
.row-fluid
.span9
%ul.thumbnails
- (1..4).each do
%li.span3
.thumbnail
= image_tag('http://placehold.it/200x200', :alt => '', :class => 'img-rounded')
%ul.link-list
- if user_signed_in?
%li= link_to 'Edit', edit_crop_path(@crop), { :class => 'button' }
%li= link_to 'Destroy', @crop, method: :delete, data: { confirm: 'Are you sure?', :class => 'button' }
%h2 Who's growing this?
- (1..5).each do
.well
%h4 Some person
%p These blocks would contain recent updates from members who are growing this crop.
.span3
%h3 Scientific names:
%ul
- @crop.scientific_names.each do |sn|
%li= sn.scientific_name
%h3 More information:
%ul
%li= link_to 'Wikipedia (English)', @crop.en_wikipedia_url
%p
- if user_signed_in?
= link_to 'Edit', edit_crop_path(@crop), { :class => 'btn' }
= link_to 'Destroy', @crop, method: :delete, data: { confirm: 'Are you sure?' }, :class => 'btn'

View File

@@ -1,5 +1,42 @@
%p
Growstuff is a community of food gardeners working together to build an open source platform to track, share, and discuss edible gardens and sustainable lifestyles. You can join us right now and be part of growing our website, from seed to harvest. We welcome you regardless of your experience, and invite you to be part of our development process.
.hero-unit
%h1
Growstuff
%small development site
%p
= link_to "Crops", crops_path
%p Growstuff is a community of food gardeners working together to build an open source platform to track, share, and discuss edible gardens and sustainable lifestyles. You can join us right now and be part of growing our website, from seed to harvest. We welcome you regardless of your experience, and invite you to be part of our development process.
%p= link_to 'Learn more', 'http://wiki.growstuff.org/', :class => 'btn btn-primary btn-large'
.row
.span3
%h2 Track
%p
Track your garden, your
= link_to 'crops', crops_path
, and everything to do with them. |
Remember what you planted or harvested, and plan for what you want to do next. |
Import and export your data to a spreadsheet or other format.
.span3
%h2 Connect
%p
Connect with friends, people who live in your area, or others |
who share your gardening interests. Show off your crops and |
harvests, share updates and tips, and
= link_to 'see', updates_path
what everyone else is doing, too.
.span3
%h2 Learn
%p
Browse our
= link_to 'crops', crops_path
database and learn about food plants for your
climate and garden type. Read other
= link_to "members' updates", updates_path
and tips, or post questions and discuss food gardening issues in our forums.
.span3
%h2 Trade
%p
Use Growstuff as a marketplace for everything related to food
gardens. Buy and sell, trade, or give away anything from seeds
to garden supplies, or find events and businesses in your area.

View File

@@ -0,0 +1,29 @@
.hero-unit
%h1
Growstuff
%small development site
<<<<<<< HEAD
%p Growstuff is a community of food gardeners working together to build an open source platform to track, share, and discuss edible gardens and sustainable lifestyles. You can join us right now and be part of growing our website, from seed to harvest. We welcome you regardless of your experience, and invite you to be part of our development process.
%p= link_to 'Learn more', 'http://wiki.growstuff.org/', :class => 'btn btn-primary btn-large'
.row
.span3
%h2 Track
%p Donec id elit non mi porta gravida at eget metus. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Etiam porta sem malesuada magna mollis euismod. Donec sed odio dui.
.span3
%h2 Connect
%p Donec id elit non mi porta gravida at eget metus. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Etiam porta sem malesuada magna mollis euismod. Donec sed odio dui.
.span3
%h2 Learn
%p Donec id elit non mi porta gravida at eget metus. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Etiam porta sem malesuada magna mollis euismod. Donec sed odio dui.
.span3
%h2 Trade
%p Donec id elit non mi porta gravida at eget metus. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Etiam porta sem malesuada magna mollis euismod. Donec sed odio dui.
=======
%ul
%li= link_to "Crops", crops_path
%li= link_to "Members", members_path
%li= link_to "Recent updates", updates_path
>>>>>>> 9f70027f872c93cae57f68f0124f0fff222cdeee

View File

@@ -1,15 +1,10 @@
.row
.ten.columns
%ul.link-list
%li
= link_to "About", "http://wiki.growstuff.org"
%li
= link_to "License", "https://github.com/Growstuff/growstuff/blob/dev/LICENSE.txt"
%li
= link_to "Github", "https://github.com/Growstuff/"
%li
= link_to "Wiki", "http://wiki.growstuff.org"
%li
= link_to "Mailing list", "http://lists.growstuff.org/mailman/listinfo/discuss"
%li
= link_to "Community Guidelines", "https://github.com/Growstuff/policy/blob/master/community-guidelines.md"
.container
.navbar.navbar-fixed-bottom
.navbar-inner
%ul.nav
%li= link_to "About", "http://wiki.growstuff.org"
%li= link_to "License", "https://github.com/Growstuff/growstuff/blob/dev/LICENSE.txt"
%li= link_to "Github", "https://github.com/Growstuff/"
%li= link_to "Wiki", "http://wiki.growstuff.org"
%li= link_to "Mailing list", "http://lists.growstuff.org/mailman/listinfo/discuss"
%li= link_to "Community Guidelines", "https://github.com/Growstuff/policy/blob/master/community-guidelines.md"

View File

@@ -1,23 +1,22 @@
.row
.ten.columns
- if user_signed_in?
%ul.link-list
%li
You are signed in as
= current_user.email + "."
%li
= link_to("Log out", destroy_user_session_path, :method => :delete)
- else
%ul.link-list
%li
= link_to('Sign up', new_user_registration_path)
%li
= link_to('Log in', new_user_session_path)
.row
.ten.columns
%h1
= link_to('Growstuff', root_path)
%small
development site
.navbar.navbar-static-top
.navbar-inner
.container
%a.btn.btn-navbar(data-target=".nav-collapse" data-toggle="collapse")
%span.icon-bar
%span.icon-bar
%span.icon-bar
%a.brand(href=root_path) Growstuff (development site)
.container.nav-collapse
%ul.nav
%li= link_to "Crops", crops_path
%li= link_to "Members", members_path
%li= link_to "Updates", updates_path
- if user_signed_in?
%li= link_to("Post an update", new_update_path)
%li.divider-vertical
%li= link_to current_user.username, member_path(current_user)
%li= link_to "Log out", destroy_user_session_path, :method => :delete
- else
%li.divider-vertical
%li.pull-right= link_to 'Sign up', new_user_registration_path
%li.pull-right= link_to 'Log in', new_user_session_path

View File

@@ -2,9 +2,23 @@
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link href='http://fonts.googleapis.com/css?family=Sevillana' rel='stylesheet' type='text/css'>
- if (content_for?(:member_rss_username) && content_for(:member_rss_slug))
= auto_discovery_link_tag(:rss, { :controller => "/members", :action => 'show', :format => "rss", :id => yield(:member_rss_slug) }, { :title => "Growstuff - #{yield(:member_rss_username)}'s updates" })
= auto_discovery_link_tag(:rss, { :controller => "/updates", :format => "rss" }, { :title => "Growstuff - Recent updates from all members" })
= auto_discovery_link_tag(:rss, { :controller => "/crops", :format => "rss" }, { :title => "Growstuff - Recently added crops" })
%title
= content_for?(:title) ? yield(:title) + " - Growstuff" : "Growstuff"
= stylesheet_link_tag "application", :media => "all"
= javascript_include_tag "application"
= csrf_meta_tags
/ Le HTML5 shim, for IE6-8 support of HTML elements
/[if lt IE 9]
= javascript_include_tag "http://html5shim.googlecode.com/svn/trunk/html5.js"
= stylesheet_link_tag "application", :media => "all"
%link(href="images/apple-touch-icon-144x144.png" rel="apple-touch-icon-precomposed" sizes="144x144")
%link(href="images/apple-touch-icon-114x114.png" rel="apple-touch-icon-precomposed" sizes="114x114")
%link(href="images/apple-touch-icon-72x72.png" rel="apple-touch-icon-precomposed" sizes="72x72")
%link(href="images/apple-touch-icon.png" rel="apple-touch-icon-precomposed")
%link(href="images/favicon.ico" rel="shortcut icon")

View File

@@ -0,0 +1,39 @@
%head
<<<<<<< HEAD
%meta(charset="utf-8")
%meta(http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1")
%meta(name="viewport" content="width=device-width, initial-scale=1.0")
%title= content_for?(:title) ? yield(:title) + " - Growstuff" : "Growstuff"
=======
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link href='http://fonts.googleapis.com/css?family=Sevillana' rel='stylesheet' type='text/css'>
- if (content_for?(:member_rss_username) && content_for(:member_rss_slug))
= auto_discovery_link_tag(:rss, { :controller => "members", :action => 'show', :format => "rss", :id => yield(:member_rss_slug) }, { :title => "Growstuff - #{yield(:member_rss_username)}'s updates" })
= auto_discovery_link_tag(:rss, { :controller => "updates", :format => "rss" }, { :title => "Growstuff - Recent updates from all members" })
= auto_discovery_link_tag(:rss, { :controller => "crops", :format => "rss" }, { :title => "Growstuff - Recently added crops" })
%title
= content_for?(:title) ? yield(:title) + " - Growstuff" : "Growstuff"
= stylesheet_link_tag "application", :media => "all"
= javascript_include_tag "application"
= csrf_meta_tags
>>>>>>> 9f70027f872c93cae57f68f0124f0fff222cdeee
- if (content_for?(:member_rss_username) && content_for(:member_rss_slug))
= auto_discovery_link_tag(:rss, { :controller => "members", :action => 'show', :format => "rss", :id => yield(:member_rss_slug) }, { :title => "Growstuff - #{yield(:member_rss_username)}'s updates" })
= auto_discovery_link_tag(:rss, { :controller => "updates", :format => "rss" }, { :title => "Growstuff - Recent updates from all members" })
= auto_discovery_link_tag(:rss, { :controller => "crops", :format => "rss" }, { :title => "Growstuff - Recently added crops" })
= csrf_meta_tags
/ Le HTML5 shim, for IE6-8 support of HTML elements
/[if lt IE 9]
= javascript_include_tag "http://html5shim.googlecode.com/svn/trunk/html5.js"
= stylesheet_link_tag "application", :media => "all"
%link(href="images/apple-touch-icon-144x144.png" rel="apple-touch-icon-precomposed" sizes="144x144")
%link(href="images/apple-touch-icon-114x114.png" rel="apple-touch-icon-precomposed" sizes="114x114")
%link(href="images/apple-touch-icon-72x72.png" rel="apple-touch-icon-precomposed" sizes="72x72")
%link(href="images/apple-touch-icon.png" rel="apple-touch-icon-precomposed")
%link(href="images/favicon.ico" rel="shortcut icon")

View File

@@ -1,16 +1,26 @@
%html
!!! 5
%html(lang="en")
= render :partial => "layouts/meta"
%body
= render :partial => "layouts/header"
.row
.ten.columns
- if content_for?(:title)
%h2=yield(:title)
- if notice
%div.alert-box.success
= notice
- if alert
%div.alert-box.alert
= alert
= yield
= render :partial => "layouts/footer"
.container
.row
.span12
- if content_for?(:title)
%h1= yield(:title)
- if notice
%div.alert.alert-success
= notice
- if alert
%div.alert
= alert
= yield
%footer
= render :partial => "layouts/footer"
/
Javascripts
\==================================================
/ Placed at the end of the document so the pages load faster
= javascript_include_tag "application"

View File

@@ -0,0 +1,9 @@
= content_for :title, "Growstuff members"
%ul.thumbnails
- @members.each do |m|
%li.span2
.thumbnail
= image_tag('http://placehold.it/150x150', :alt => '', :class => 'img-rounded')
%h3= link_to m.username, member_path(m)

View File

@@ -0,0 +1,43 @@
- content_for :title, "#{@member.username}"
- content_for :member_rss_username, "#{@member.username}"
- content_for :member_rss_slug, "#{@member.slug}"
.row
.span3
=image_tag('http://placehold.it/150x150', :alt => '', :class => 'img-rounded')
%h4= @member.username
%p
= "Member since: #{@member.created_at.strftime("%B %d, %Y")}."
%p Location: Unknown
.span9
.tabbable
%ul.nav.nav-tabs
%li.active
= link_to 'My Garden', '#tab1', 'data-toggle' => 'tab'
%li
= link_to '2nd Garden', '#tab2', 'data-toggle' => 'tab'
%li
= link_to '3nd Garden', '#tab3', 'data-toggle' => 'tab'
.tab-content
.tab-pane.active#tab1
%ul.thumbnails
- (1..4).each do
%li.span2
.thumbnail
= image_tag('http://placehold.it/150x150', :alt => '', :class => 'img-rounded')
%h4 Some crop
%p Planted YYYY-MM-DD. 99 updates.
.tab-pane#tab2
Multiple gardens aren't supported yet. This is just to show how they could be tabbed.
.tab-pane#tab3
Multiple gardens aren't supported yet. This is just to show how they could be tabbed.
%h3 Updates
%table
- @member.updates.each do |update|
= render :partial => "updates/single", :locals => { :update => update, :subject => true }

View File

@@ -0,0 +1,18 @@
xml.instruct! :xml, :version => "1.0"
xml.rss :version => "2.0" do
xml.channel do
xml.title "Growstuff - #{@member.username}'s recent updates"
xml.link member_url(@member)
for update in @updates
xml.item do
xml.author member.username
xml.title update.subject
xml.description update.body
xml.pubDate update.created_at.to_s(:rfc822)
xml.link update_url(update)
xml.guid update_url(update)
end
end
end
end

View File

@@ -1,4 +0,0 @@
- content_for :title, "Profile for #{@user.username}"
%p
= "A Growstuff user since #{@user.created_at.strftime("%B %d, %Y")}."

View File

@@ -0,0 +1,16 @@
= form_for @scientific_name do |f|
- if @scientific_name.errors.any?
#error_explanation
%h2= "#{pluralize(@scientific_name.errors.count, "error")} prohibited this scientific_name from being saved:"
%ul
- @scientific_name.errors.full_messages.each do |msg|
%li= msg
.field
= f.label :scientific_name
= f.text_field :scientific_name
.field
= f.label :crop_id
= f.number_field :crop_id
.actions
= f.submit 'Save'

View File

@@ -0,0 +1,9 @@
%h1 Editing scientific_name
- if user_signed_in?
= render 'form'
%p
= link_to 'Show', @scientific_name, { :class => 'btn' }
= link_to 'Back', scientific_names_path, { :class => 'btn' }
- else
%div.alert You're not logged in. Only logged in users can do this.

View File

@@ -0,0 +1,21 @@
%h1 Listing scientific_names
%table
%tr
%th Scientific name
%th Crop
%th
%th
%th
- @scientific_names.each do |scientific_name|
%tr
%td= scientific_name.scientific_name
%td= scientific_name.crop_id
%td= link_to 'Show', scientific_name
%td= link_to 'Edit', edit_scientific_name_path(scientific_name)
%td= link_to 'Destroy', scientific_name, method: :delete, data: { confirm: 'Are you sure?' }
%br
= link_to 'New Scientific name', new_scientific_name_path

View File

@@ -0,0 +1,9 @@
%h1 New scientific_name
- if user_signed_in?
= render 'form'
%p
= link_to 'Show', @scientific_name, { :class => 'btn' }
= link_to 'Back', scientific_names_path, { :class => 'btn' }
- else
%div.alert You're not logged in. Only logged in users can do this.

View File

@@ -0,0 +1,12 @@
%p#notice= notice
%p
%b Scientific name:
= @scientific_name.scientific_name
%p
%b Crop:
= @scientific_name.crop_id
= link_to 'Edit', edit_scientific_name_path(@scientific_name)
\|
= link_to 'Back', scientific_names_path

View File

@@ -0,0 +1,19 @@
= form_for @update do |f|
- if @update.errors.any?
#error_explanation
%h2= "#{pluralize(@update.errors.count, "error")} prohibited this update from being saved:"
%ul
- @update.errors.full_messages.each do |msg|
%li= msg
.field
= f.label :user_id
= f.number_field :user_id
.field
= f.label :subject
= f.text_field :subject
.field
= f.label :body
= f.text_area :body
.actions
= f.submit 'Save'

View File

@@ -0,0 +1,20 @@
.well
%div.update
- if subject
%h3= link_to strip_tags(update.subject), update
%div.update-meta
Posted by
= link_to update.user.username, member_path(update.user)
at
= update.created_at
%div.update-body
:markdown
#{ strip_tags update.body }
- if current_user == update.user
%div.update-actions
= link_to 'Edit', edit_update_path(update), :class => 'btn'
= link_to 'Delete', update, method: :delete, |
data: { confirm: 'Are you sure?' }, :class => 'btn'

View File

@@ -0,0 +1,10 @@
= content_for :title, "Edit update"
- if user_signed_in?
= form_for @update do |f|
= label_tag :subject, "Subject"
= f.text_field :subject, :class => 'input-block-level'
= f.text_area :body, :rows => 12, :class => 'input-block-level'
= f.submit "Post"
- else
%div.alert You're not logged in. Only logged in users can do this.

View File

@@ -0,0 +1,6 @@
= content_for :title, "Recent Growstuff member updates"
- @updates.each do |update|
= render :partial => "single", :locals => { :update => update, :subject => true }
= link_to 'New Update', new_update_path

View File

@@ -0,0 +1,18 @@
xml.instruct! :xml, :version => "1.0"
xml.rss :version => "2.0" do
xml.channel do
xml.title "Growstuff - Recent updates from all members"
xml.link updates_url
for update in @recent_updates
xml.item do
xml.author update.user.username
xml.title update.subject
xml.description update.body
xml.pubDate update.created_at.to_s(:rfc822)
xml.link update_url(update)
xml.guid update_url(update)
end
end
end
end

View File

@@ -0,0 +1,14 @@
= content_for :title, "Post an update"
- if user_signed_in?
= form_for @update, :url => { :action => "create" } do |f|
%fieldset
= label_tag :update, "Subject"
= f.text_field :subject, :class => 'input-block-level'
= label_tag :body, "What's going on in your food garden?"
= f.text_area :body, :rows => 12, :class => 'input-block-level'
= f.submit "Post", :class => 'btn'
- else
%div.alert You're not logged in. Only logged in users can do this.
= link_to 'Back', updates_path

View File

@@ -0,0 +1,3 @@
= content_for :title, @update.subject
= render :partial => "single", :locals => { :update => @update, :subject => false }

View File

@@ -1,4 +1,3 @@
require 'zurb-foundation'
# Require any additional compass plugins here.
# Set this to the root of your project when deployed:

View File

@@ -1,8 +1,9 @@
Growstuff::Application.routes.draw do
resources :gardens
resources :crops, :profile
resources :updates
resources :scientific_names
resources :crops
resources :members
devise_for :users
get "home/index"

View File

@@ -3,7 +3,6 @@ class CreateCrops < ActiveRecord::Migration
create_table :crops do |t|
t.string :system_name
t.string :en_wikipedia_url
t.timestamps
end
end

View File

@@ -1,19 +0,0 @@
class SetupTestUsers < ActiveRecord::Migration
def up
if Rails.env.development? or Rails.env.test?
(1..3).each do |i|
@user = User.create(:username => "test#{i}", :email => "test#{i}@example.com", :password => "password#{i}")
@user.save!
end
end
end
def down
if Rails.env.development? or Rails.env.test?
(1..3).each do |i|
@user = User.find_by_username("test#{i}")
@user.try(:destroy)
end
end
end
end

View File

@@ -0,0 +1,6 @@
class AddSlugToUsers < ActiveRecord::Migration
def change
add_column :users, :slug, :string
add_index :users, :slug, unique: true
end
end

View File

@@ -0,0 +1,10 @@
class GiveOldMembersNewSlugs < ActiveRecord::Migration
def up
User.find_each(&:save)
end
# note: this is basically impossible to reverse without removing
# friendly_id, because friendly_id automatically updates the slug when
# you save the object.
end

View File

@@ -0,0 +1,10 @@
class CreateScientificNames < ActiveRecord::Migration
def change
create_table :scientific_names do |t|
t.string :scientific_name, :null => false
t.integer :crop_id, :null => false
t.timestamps
end
end
end

View File

@@ -0,0 +1,11 @@
class CreateUpdates < ActiveRecord::Migration
def change
create_table :updates do |t|
t.integer :user_id, :null => false
t.string :subject, :null => false
t.text :body, :null => false
t.timestamps
end
end
end

View File

@@ -0,0 +1,5 @@
class AddCreationIndexToUpdates < ActiveRecord::Migration
def change
add_index :updates, [:created_at, :user_id]
end
end

View File

@@ -11,7 +11,7 @@
#
# It's strongly recommended to check this file into your version control system.
ActiveRecord::Schema.define(:version => 20121105052119) do
ActiveRecord::Schema.define(:version => 20121109130033) do
create_table "crops", :force => true do |t|
t.string "system_name", :null => false
@@ -35,6 +35,23 @@ ActiveRecord::Schema.define(:version => 20121105052119) do
add_index "gardens", ["slug"], :name => "index_gardens_on_slug", :unique => true
add_index "gardens", ["user_id"], :name => "index_gardens_on_user_id"
create_table "scientific_names", :force => true do |t|
t.string "scientific_name", :null => false
t.integer "crop_id", :null => false
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
create_table "updates", :force => true do |t|
t.integer "user_id", :null => false
t.string "subject", :null => false
t.text "body", :null => false
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
add_index "updates", ["created_at", "user_id"], :name => "index_updates_on_created_at_and_user_id"
create_table "users", :force => true do |t|
t.string "email", :default => "", :null => false
t.string "encrypted_password", :default => "", :null => false
@@ -56,11 +73,13 @@ ActiveRecord::Schema.define(:version => 20121105052119) do
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.string "username"
t.string "slug"
end
add_index "users", ["confirmation_token"], :name => "index_users_on_confirmation_token", :unique => true
add_index "users", ["email"], :name => "index_users_on_email", :unique => true
add_index "users", ["reset_password_token"], :name => "index_users_on_reset_password_token", :unique => true
add_index "users", ["slug"], :name => "index_users_on_slug", :unique => true
add_index "users", ["unlock_token"], :name => "index_users_on_unlock_token", :unique => true
end

View File

@@ -5,3 +5,25 @@
#
# cities = City.create([{ name: 'Chicago' }, { name: 'Copenhagen' }])
# Mayor.create(name: 'Emanuel', city: cities.first)
# import crops from CSV
require 'csv'
puts "Loading crops..."
CSV.foreach(Rails.root.join('db', 'seeds', 'crops.csv')) do |row|
system_name,scientific_name,en_wikipedia_url = row
@crop = Crop.create(:system_name => system_name, :en_wikipedia_url => en_wikipedia_url)
@crop.scientific_names.create(:scientific_name => scientific_name)
end
puts "Finished loading crops"
puts "Loading test users..."
if Rails.env.development? or Rails.env.test?
(1..3).each do |i|
@user = User.create(:username => "test#{i}", :email => "test#{i}@example.com", :password => "password#{i}")
@user.confirm!
@user.save!
end
end
puts "Finished loading test users"

233
db/seeds/crops.csv Normal file
View File

@@ -0,0 +1,233 @@
achiote,Bixa orellana,https://en.wikipedia.org/wiki/Bixa_orellana
ackee,Blighia sapida,https://en.wikipedia.org/wiki/Ackee
acuyo,Piper auritum,https://en.wikipedia.org/wiki/Piper_auritum
alexanders,Smyrnium olusatrum,https://en.wikipedia.org/wiki/Alexanders
alfalfa,Medicago sativa,https://en.wikipedia.org/wiki/Alfalfa
allspice,Pimenta dioica,https://en.wikipedia.org/wiki/Allspice
almond,Prunus dulcis,https://en.wikipedia.org/wiki/Almond
amaranth,Amaranthus spp.,https://en.wikipedia.org/wiki/Amaranth
anise,Pimpinella anisum,https://en.wikipedia.org/wiki/Anise
apple,Malus domestica,https://en.wikipedia.org/wiki/Apple
apple mint,Mentha suaveolens,https://en.wikipedia.org/wiki/Apple_mint
apricot,Prunus armeniaca,https://en.wikipedia.org/wiki/Apricot
arrowroot,Maranta arundinacea,https://en.wikipedia.org/wiki/Maranta_arundinacea
artichoke,Cynara cardunculus,https://en.wikipedia.org/wiki/Artichoke
arugula,Eruca sativa,https://en.wikipedia.org/wiki/Arugula
asparagus,Asparagus officinalis,https://en.wikipedia.org/wiki/Asparagus
avocado,Persea americana,https://en.wikipedia.org/wiki/Avocado
banana,Musa spp.,https://en.wikipedia.org/wiki/Banana
barley,Hordeum vulgare,https://en.wikipedia.org/wiki/Barley
basil,Ocimum basilicum,https://en.wikipedia.org/wiki/Basil
bay,Laurus nobilis,https://en.wikipedia.org/wiki/Bay_Laurel
bean,Phaseolus vulgaris,https://en.wikipedia.org/wiki/Common_bean
beet,Beta vulgaris,https://en.wikipedia.org/wiki/Beet
bell pepper,Capsicum annuum,https://en.wikipedia.org/wiki/Bell_pepper
bitter melon,Momordica charantia,https://en.wikipedia.org/wiki/Bitter_melon
blackberry,Rubus fruticosus,https://en.wikipedia.org/wiki/Blackberry
blackcurrant,Ribes spp.,https://en.wikipedia.org/wiki/Ribes
borage,Borago officinalis,https://en.wikipedia.org/wiki/Borage
breadfruit,Artocarpus altilis,https://en.wikipedia.org/wiki/Breadfruit
broccoli,Brassica oleracea,https://en.wikipedia.org/wiki/Broccoli
Brussels sprout,Brassica oleracea,https://en.wikipedia.org/wiki/Brussels_sprout
buckwheat,Fagopyrum esculentum,https://en.wikipedia.org/wiki/Buckwheat
cabbage,Brassica oleracea,https://en.wikipedia.org/wiki/Cabbage
cape gooseberry,Physalis peruviana,https://en.wikipedia.org/wiki/Physalis_peruviana
caper,Capparis spinosa,https://en.wikipedia.org/wiki/Caper
cardoon,Cynara cardunculus,https://en.wikipedia.org/wiki/Cardoon
carrot,Daucus carota,https://en.wikipedia.org/wiki/Carrot
cassava,Manihot esculenta,https://en.wikipedia.org/wiki/Cassava
catnip,Nepeta cataria,https://en.wikipedia.org/wiki/Nepeta_cataria
cauliflower,Brassica oleracea,https://en.wikipedia.org/wiki/Cauliflower
cayenne pepper,Capsicum annuum,https://en.wikipedia.org/wiki/Cayenne_pepper
celeriac,Apium graveolens var. rapaceum,https://en.wikipedia.org/wiki/Celeriac
celery,Apium graveolens,https://en.wikipedia.org/wiki/Celery
chamomile,Matricaria chamomila,https://en.wikipedia.org/wiki/Matricaria_recutita
chaya,Cnidoscolus aconitifolius,https://en.wikipedia.org/wiki/Cnidoscolus_aconitifolius
chayote,Sechium edule,https://en.wikipedia.org/wiki/Chayote
cherry,Prunus avium,https://en.wikipedia.org/wiki/Cherry
chervil,Anthriscus cerefolium,https://en.wikipedia.org/wiki/Chervil
chestnut,Castanea spp.,https://en.wikipedia.org/wiki/Chestnut
chickpeas,Cicer arietinum,https://en.wikipedia.org/wiki/Chickpea
chickweed,Stellaria,https://en.wikipedia.org/wiki/Stellaria
chicory,Cichorium intybus,https://en.wikipedia.org/wiki/Chicory
chinese cabbage,Brassica rapa (pekinensis),https://en.wikipedia.org/wiki/Chinese_cabbage
chives,Allium schoenoprasum,https://en.wikipedia.org/wiki/Chives
cicely,Myrrhis odorata,https://en.wikipedia.org/wiki/Cicely
citron,Citrus medica,https://en.wikipedia.org/wiki/Citron
coconut,Cocos nucifera,https://en.wikipedia.org/wiki/Coconut
collard greens,Brassica oleracea (acephala),https://en.wikipedia.org/wiki/Collard_greens
comfrey,Symphytum officinale,https://en.wikipedia.org/wiki/Comfrey
coriander,Coriandrum sativum,https://en.wikipedia.org/wiki/Coriander
corn,Zea mays,https://en.wikipedia.org/wiki/Corn
corn salad,Valerianella locusta,https://en.wikipedia.org/wiki/Corn_salad
cress,Lepidium sativum,https://en.wikipedia.org/wiki/Garden_cress
cucumber,Cucumis sativus,https://en.wikipedia.org/wiki/Cucumbers
cumin,Cuminum cyminum,https://en.wikipedia.org/wiki/Cumin
cumquat,Citrus japonica,https://en.wikipedia.org/wiki/Kumquat
curry leaf,Murraya koenigii,https://en.wikipedia.org/wiki/Curry-leaf_Tree
curry plant,Helichrysum italicum,https://en.wikipedia.org/wiki/Helichrysum_italicum
daikon,Raphanus sativus Longipinnatus group,https://en.wikipedia.org/wiki/Daikon
dandelion,Taraxacum officinale,https://en.wikipedia.org/wiki/Dandelion
dates,Phoenix dactylifera,https://en.wikipedia.org/wiki/Date_%28fruit%29
desert lime,Citrus glauca,https://en.wikipedia.org/wiki/Citrus_glauca
dill,Anethum graveolens,https://en.wikipedia.org/wiki/Dill
dog rose,Rosa canina,https://en.wikipedia.org/wiki/Rosa_canina
durian,Durio,https://en.wikipedia.org/wiki/Durian
eggplant,Solanum melongena,https://en.wikipedia.org/wiki/Eggplant
elderberry,Sambucus nigra,https://en.wikipedia.org/wiki/Sambucus_nigra
endive,Cichorium endivia,https://en.wikipedia.org/wiki/Endive
epazote,Dysphania ambrosioides,https://en.wikipedia.org/wiki/Epazote
fava bean,Vicia faba,https://en.wikipedia.org/wiki/Vicia_faba
feijoa,Acca sellowiana,https://en.wikipedia.org/wiki/Acca_sellowiana
fennel,Foeniculum vulgare,https://en.wikipedia.org/wiki/Fennel
fenugreek,Trigonella foenum-graecum,https://en.wikipedia.org/wiki/Fenugreek
fiddlehead,Pteridium aquilinum,https://en.wikipedia.org/wiki/Fiddlehead
fig,Ficus carica,https://en.wikipedia.org/wiki/Common_fig
flax,Linum usitatissimum,https://en.wikipedia.org/wiki/Flax
garlic,Allium sativum,https://en.wikipedia.org/wiki/Garlic
garlic chives,Allium tuberosum,https://en.wikipedia.org/wiki/Garlic_chives
ginger,Zingiber officinale,https://en.wikipedia.org/wiki/Ginger
gooseberry,Ribes uva-crispa,https://en.wikipedia.org/wiki/Gooseberry
grapefruit,Citrus paradisi,https://en.wikipedia.org/wiki/Grapefruit
grapes,Vitis spp.,https://en.wikipedia.org/wiki/Grape
guava,Psidium spp.,https://en.wikipedia.org/wiki/Guava
habanero,Capsicum chinense,https://en.wikipedia.org/wiki/Habanero
hibiscus,Hibiscus,https://en.wikipedia.org/wiki/Hibiscus
horseradish,Armoracia rusticana,https://en.wikipedia.org/wiki/Horseradish
jasmine,Jasminum officinale,https://en.wikipedia.org/wiki/Jasmine
Jerusalem artichoke,Helianthus tuberosus,https://en.wikipedia.org/wiki/Jerusalem_artichoke
jicama,Pachyrhizus erosus,https://en.wikipedia.org/wiki/Jicama
juniper berry,Juniperus communis,https://en.wikipedia.org/wiki/Juniper_berry
kaffir lime,Citrus x hystrix,https://en.wikipedia.org/wiki/Kaffir_lime
kale,Brassica oleracea (acephala),https://en.wikipedia.org/wiki/Kale
kava,Piper methysticum,https://en.wikipedia.org/wiki/Kava
kohlrabi,Brassica oleracea (gongylodes),https://en.wikipedia.org/wiki/Kohlrabi
lavender,Lavandula spp.,https://en.wikipedia.org/wiki/Lavender
leek,Allium ampeloprasum var. porrum,https://en.wikipedia.org/wiki/Leeks
lemon,Citrus limon,https://en.wikipedia.org/wiki/Lemon
lemon balm,Melissa officinalis,https://en.wikipedia.org/wiki/Lemon_balm
lemon myrtle,Backhousia citriodora,https://en.wikipedia.org/wiki/Backhousia_citriodora
lemon verbena,Aloysia citrodora,https://en.wikipedia.org/wiki/Aloysia_citrodora
lemongrass,Cymbopogon spp.,https://en.wikipedia.org/wiki/Lemongrass
lentils,Lens culinaris,https://en.wikipedia.org/wiki/Lentil
lettuce,Lactuca sativa,https://en.wikipedia.org/wiki/Lettuce
licorice,Glycyrrhiza glabra,https://en.wikipedia.org/wiki/Licorice
lillipilli,Syzygium luehmannii,https://en.wikipedia.org/wiki/Syzygium_luehmannii
lima bean,Phaseolus lunatus,https://en.wikipedia.org/wiki/Phaseolus_lunatus
lime,Citrus spp.,https://en.wikipedia.org/wiki/Lime_%28fruit%29
lovage,Levisticum officinale,https://en.wikipedia.org/wiki/Lovage
luffa,Luffa cylindrica,https://en.wikipedia.org/wiki/Luffa
lupin bean,Lupinus luteus,https://en.wikipedia.org/wiki/Lupin_bean
macadamia,Macadamia,https://en.wikipedia.org/wiki/Macadamia
Malabar spinach,Basella alba,https://en.wikipedia.org/wiki/Basella_alba
mandarin,Citrus reticulata,https://en.wikipedia.org/wiki/Mandarin_orange
mango,Mangifera spp.,https://en.wikipedia.org/wiki/Mango
maracuja,Passiflora edulis,https://en.wikipedia.org/wiki/Maracuja
marjoram,Origanum majorana,https://en.wikipedia.org/wiki/Marjoram
marshmallow,Althaea officinalis,https://en.wikipedia.org/wiki/Althaea_officinalis
medlar,Mespilus germanica,https://en.wikipedia.org/wiki/Mespilus_germanica
melon,Cucumis melo,https://en.wikipedia.org/wiki/Melon
miner's lettuce,Claytonia perfoliata,https://en.wikipedia.org/wiki/Claytonia_perfoliata
mint,Mentha spicata,https://en.wikipedia.org/wiki/Mentha_spicata
mung bean,Vigna radiata,https://en.wikipedia.org/wiki/Mung_bean
mustard,Brassica juncea,https://en.wikipedia.org/wiki/Mustard_plant
nasturtium,Tropaeloum spp.,https://en.wikipedia.org/wiki/Tropaeolum
New Zealand spinach,Tetragonia tetragonioides,https://en.wikipedia.org/wiki/Tetragonia
nigella,Nigella sativa,https://en.wikipedia.org/wiki/Nigella_sativa
oats,Avena sativa,https://en.wikipedia.org/wiki/Oats
okra,Abelmoschus esculentus,https://en.wikipedia.org/wiki/Okra
olive,Olea europaea,https://en.wikipedia.org/wiki/Olive
onion,Allium cepa,https://en.wikipedia.org/wiki/Onions
orange,Citrus sinensis,https://en.wikipedia.org/wiki/Orange_%28fruit%29
oregano,Origanum vulgare,https://en.wikipedia.org/wiki/Oregano
parsley,Petroselinum hortense,https://en.wikipedia.org/wiki/Parsley
parsnip,Pastinaca sativa,https://en.wikipedia.org/wiki/Parsnip
passion fruit,Passiflora edulis,https://en.wikipedia.org/wiki/Passionfruit
pea,Pisum sativum,https://en.wikipedia.org/wiki/Pea
peach,Prunus persica,https://en.wikipedia.org/wiki/Peach
peach,Prunus persica,https://en.wikipedia.org/wiki/Peach
peanut,Arachis hypogaea,https://en.wikipedia.org/wiki/Peanut
pear,Pyrus spp.,https://en.wikipedia.org/wiki/Pear
pearl millet,Pennisetum glaucum,https://en.wikipedia.org/wiki/Pearl_millet
pecan,Carya illinoinensis,https://en.wikipedia.org/wiki/Pecan
peppermint,Mentha x piperita,https://en.wikipedia.org/wiki/Peppermint
Persian lime,Citrus latifolia,https://en.wikipedia.org/wiki/Persian_lime
persimmon,Diospyros spp.,https://en.wikipedia.org/wiki/Persimmon
pigeon pea,Cajanus cajan,https://en.wikipedia.org/wiki/Pigeon_pea
pigface,Carpobrotus glaucescens,https://en.wikipedia.org/wiki/Carpobrotus_glaucescens
pineapple,Ananas comosus,https://en.wikipedia.org/wiki/Pineapple
pistachio,Pistacia vera,https://en.wikipedia.org/wiki/Pistachio
plantain,Musa spp.,https://en.wikipedia.org/wiki/Plantain
plum,Prunus spp.,https://en.wikipedia.org/wiki/Plum
pomegranate,Punica granatum,https://en.wikipedia.org/wiki/Pomegranate
pomelo,Citrus maxima,https://en.wikipedia.org/wiki/Pomelo
potato,Solanum tuberosum,https://en.wikipedia.org/wiki/Potatoes
prickly pear,Opuntia,https://en.wikipedia.org/wiki/Opuntia
pumpkin,Cucurbita spp.,https://en.wikipedia.org/wiki/Pumpkin
purslane,Portulaca oleracea,https://en.wikipedia.org/wiki/Portulaca_oleracea
quandong,Santalum acuminatum,https://en.wikipedia.org/wiki/Santalum_acuminatum
quince,Cydonia oblonga,https://en.wikipedia.org/wiki/Quince
quinoa,Chenopodium quinoa,https://en.wikipedia.org/wiki/Quinoa
radicchio,Cichorium intybus,https://en.wikipedia.org/wiki/Radicchio
radish,Raphanus sativus,https://en.wikipedia.org/wiki/Radish
rapeseed,Brassica napus,https://en.wikipedia.org/wiki/Rapeseed
raspberry,Rubus idaeus,https://en.wikipedia.org/wiki/Rubus_idaeus
rhubarb,Rheum rhabarbarum,https://en.wikipedia.org/wiki/Rhubarb
rice,Oryza sativa,https://en.wikipedia.org/wiki/Rice
rice bean,Vigna umbellata,https://en.wikipedia.org/wiki/Ricebean
rose,Rosa,https://en.wikipedia.org/wiki/Rose
roselle,Hibiscus sabdariffa,https://en.wikipedia.org/wiki/Roselle_%28plant%29
rosemary,Rosmarinus officinalis,https://en.wikipedia.org/wiki/Rosemary
rue,Ruta graveolens,https://en.wikipedia.org/wiki/Common_Rue
runner bean,Phaseolus coccineus,https://en.wikipedia.org/wiki/Runner_bean
rutabaga,Brassica napus Napobrassica group,https://en.wikipedia.org/wiki/Rutabaga
rye,Secale cereale,https://en.wikipedia.org/wiki/Rye
safflower,Carthamus tinctorius,https://en.wikipedia.org/wiki/Safflower
saffron,Crocus sativus,https://en.wikipedia.org/wiki/Saffron
sage,Salvia officinalis,https://en.wikipedia.org/wiki/Salvia_officinalis
salad burnet,Sanguisorba minor,https://en.wikipedia.org/wiki/Salad_burnet
salsify,Tragopogon porrifolius,https://en.wikipedia.org/wiki/Salsify
samphire,Crithmum maritimum,https://en.wikipedia.org/wiki/Rock_samphire
sassafras,Sassafras albidum,https://en.wikipedia.org/wiki/Sassafras_albidum
sesame,Sesamum indicum,https://en.wikipedia.org/wiki/Sesame
shallot,Allium cepa var. aggregatum,https://en.wikipedia.org/wiki/Shallot
sorghum,Sorghum spp.,https://en.wikipedia.org/wiki/Sorghum
sorrel,Rumex acetosa,https://en.wikipedia.org/wiki/Sorrel
soursop,Annona muricata,https://en.wikipedia.org/wiki/Soursop
soybean,Glycine max,https://en.wikipedia.org/wiki/Soybean
spearmint,Mentha spicata,https://en.wikipedia.org/wiki/Mentha_spicata
spinach,Spinacia oleracea,https://en.wikipedia.org/wiki/Spinach
star anise,Illicium verum,https://en.wikipedia.org/wiki/Star_anise
starfruit,Averrhoa carambola,https://en.wikipedia.org/wiki/Starfruit
stevia,Stevia rebaudiana,https://en.wikipedia.org/wiki/Stevia
strawberry,Fragaria ananassa,https://en.wikipedia.org/wiki/Strawberry
summer savory,Satureja hortensis,https://en.wikipedia.org/wiki/Summer_savory
sunflowers,Helianthus annuus,https://en.wikipedia.org/wiki/Sunflower
sweet potato,Ipomoea batatas,https://en.wikipedia.org/wiki/Sweet_potato
Swiss chard,Beta vulgaris var. cicla,https://en.wikipedia.org/wiki/Swiss_chard
tamarillo,Solanum betaceum ,https://en.wikipedia.org/wiki/Tamarillo
tamarind,Tamarindus indica,https://en.wikipedia.org/wiki/Tamarind
tangerine,Citrus tangerina,https://en.wikipedia.org/wiki/Tangerine
tansy,Tanacetum vulgare,https://en.wikipedia.org/wiki/Tansy
taro,Colocasia esculenta,https://en.wikipedia.org/wiki/Taro
tarragon,Artemisia dracunculus,https://en.wikipedia.org/wiki/Tarragon
thyme,Thymus mongolicus,https://en.wikipedia.org/wiki/Thyme
tomatillo,Physalis philadelphica,https://en.wikipedia.org/wiki/Tomatillo
tomato,Solanum lycopersicum,https://en.wikipedia.org/wiki/Tomato
turmeric,Curcuma longa,https://en.wikipedia.org/wiki/Turmeric
turnip,Brassica rapa var. rapa,https://en.wikipedia.org/wiki/Turnip
urad bean,Vigna mungo,https://en.wikipedia.org/wiki/Urad_(bean)
valerian,Valeriana officinalis,https://en.wikipedia.org/wiki/Valerian_%28plant%29
vanilla,Vanilla planifolia,https://en.wikipedia.org/wiki/Vanilla
walnut,Juglans spp.,https://en.wikipedia.org/wiki/Walnut
wasabi,Wasabia japonica,https://en.wikipedia.org/wiki/Wasabi
watermelon,Citrullus lanatus,https://en.wikipedia.org/wiki/Watermelon
wheat,Triticum spp.,https://en.wikipedia.org/wiki/Wheat
winter savory,Satureja montana,https://en.wikipedia.org/wiki/Winter_savory
wormwood,Artemisia absinthium,https://en.wikipedia.org/wiki/Artemisia_absinthium
yam,Dioscorea spp.,https://en.wikipedia.org/wiki/Yam_(vegetable)
yardlong bean,Vigna unguiculata (sesquipedalis),https://en.wikipedia.org/wiki/Yardlong_bean
yarrow,Achillea millefolium,https://en.wikipedia.org/wiki/Achillea_millefolium
zucchini,Cucurbita pepo.,https://en.wikipedia.org/wiki/Zucchini
coffee,Coffea,https://en.wikipedia.org/wiki/Coffee
tea,Camellia sinensis,https://en.wikipedia.org/wiki/Tea
1 achiote Bixa orellana https://en.wikipedia.org/wiki/Bixa_orellana
2 ackee Blighia sapida https://en.wikipedia.org/wiki/Ackee
3 acuyo Piper auritum https://en.wikipedia.org/wiki/Piper_auritum
4 alexanders Smyrnium olusatrum https://en.wikipedia.org/wiki/Alexanders
5 alfalfa Medicago sativa https://en.wikipedia.org/wiki/Alfalfa
6 allspice Pimenta dioica https://en.wikipedia.org/wiki/Allspice
7 almond Prunus dulcis https://en.wikipedia.org/wiki/Almond
8 amaranth Amaranthus spp. https://en.wikipedia.org/wiki/Amaranth
9 anise Pimpinella anisum https://en.wikipedia.org/wiki/Anise
10 apple Malus domestica https://en.wikipedia.org/wiki/Apple
11 apple mint Mentha suaveolens https://en.wikipedia.org/wiki/Apple_mint
12 apricot Prunus armeniaca https://en.wikipedia.org/wiki/Apricot
13 arrowroot Maranta arundinacea https://en.wikipedia.org/wiki/Maranta_arundinacea
14 artichoke Cynara cardunculus https://en.wikipedia.org/wiki/Artichoke
15 arugula Eruca sativa https://en.wikipedia.org/wiki/Arugula
16 asparagus Asparagus officinalis https://en.wikipedia.org/wiki/Asparagus
17 avocado Persea americana https://en.wikipedia.org/wiki/Avocado
18 banana Musa spp. https://en.wikipedia.org/wiki/Banana
19 barley Hordeum vulgare https://en.wikipedia.org/wiki/Barley
20 basil Ocimum basilicum https://en.wikipedia.org/wiki/Basil
21 bay Laurus nobilis https://en.wikipedia.org/wiki/Bay_Laurel
22 bean Phaseolus vulgaris https://en.wikipedia.org/wiki/Common_bean
23 beet Beta vulgaris https://en.wikipedia.org/wiki/Beet
24 bell pepper Capsicum annuum https://en.wikipedia.org/wiki/Bell_pepper
25 bitter melon Momordica charantia https://en.wikipedia.org/wiki/Bitter_melon
26 blackberry Rubus fruticosus https://en.wikipedia.org/wiki/Blackberry
27 blackcurrant Ribes spp. https://en.wikipedia.org/wiki/Ribes
28 borage Borago officinalis https://en.wikipedia.org/wiki/Borage
29 breadfruit Artocarpus altilis https://en.wikipedia.org/wiki/Breadfruit
30 broccoli Brassica oleracea https://en.wikipedia.org/wiki/Broccoli
31 Brussels sprout Brassica oleracea https://en.wikipedia.org/wiki/Brussels_sprout
32 buckwheat Fagopyrum esculentum https://en.wikipedia.org/wiki/Buckwheat
33 cabbage Brassica oleracea https://en.wikipedia.org/wiki/Cabbage
34 cape gooseberry Physalis peruviana https://en.wikipedia.org/wiki/Physalis_peruviana
35 caper Capparis spinosa https://en.wikipedia.org/wiki/Caper
36 cardoon Cynara cardunculus https://en.wikipedia.org/wiki/Cardoon
37 carrot Daucus carota https://en.wikipedia.org/wiki/Carrot
38 cassava Manihot esculenta https://en.wikipedia.org/wiki/Cassava
39 catnip Nepeta cataria https://en.wikipedia.org/wiki/Nepeta_cataria
40 cauliflower Brassica oleracea https://en.wikipedia.org/wiki/Cauliflower
41 cayenne pepper Capsicum annuum https://en.wikipedia.org/wiki/Cayenne_pepper
42 celeriac Apium graveolens var. rapaceum https://en.wikipedia.org/wiki/Celeriac
43 celery Apium graveolens https://en.wikipedia.org/wiki/Celery
44 chamomile Matricaria chamomila https://en.wikipedia.org/wiki/Matricaria_recutita
45 chaya Cnidoscolus aconitifolius https://en.wikipedia.org/wiki/Cnidoscolus_aconitifolius
46 chayote Sechium edule https://en.wikipedia.org/wiki/Chayote
47 cherry Prunus avium https://en.wikipedia.org/wiki/Cherry
48 chervil Anthriscus cerefolium https://en.wikipedia.org/wiki/Chervil
49 chestnut Castanea spp. https://en.wikipedia.org/wiki/Chestnut
50 chickpeas Cicer arietinum https://en.wikipedia.org/wiki/Chickpea
51 chickweed Stellaria https://en.wikipedia.org/wiki/Stellaria
52 chicory Cichorium intybus https://en.wikipedia.org/wiki/Chicory
53 chinese cabbage Brassica rapa (pekinensis) https://en.wikipedia.org/wiki/Chinese_cabbage
54 chives Allium schoenoprasum https://en.wikipedia.org/wiki/Chives
55 cicely Myrrhis odorata https://en.wikipedia.org/wiki/Cicely
56 citron Citrus medica https://en.wikipedia.org/wiki/Citron
57 coconut Cocos nucifera https://en.wikipedia.org/wiki/Coconut
58 collard greens Brassica oleracea (acephala) https://en.wikipedia.org/wiki/Collard_greens
59 comfrey Symphytum officinale https://en.wikipedia.org/wiki/Comfrey
60 coriander Coriandrum sativum https://en.wikipedia.org/wiki/Coriander
61 corn Zea mays https://en.wikipedia.org/wiki/Corn
62 corn salad Valerianella locusta https://en.wikipedia.org/wiki/Corn_salad
63 cress Lepidium sativum https://en.wikipedia.org/wiki/Garden_cress
64 cucumber Cucumis sativus https://en.wikipedia.org/wiki/Cucumbers
65 cumin Cuminum cyminum https://en.wikipedia.org/wiki/Cumin
66 cumquat Citrus japonica https://en.wikipedia.org/wiki/Kumquat
67 curry leaf Murraya koenigii https://en.wikipedia.org/wiki/Curry-leaf_Tree
68 curry plant Helichrysum italicum https://en.wikipedia.org/wiki/Helichrysum_italicum
69 daikon Raphanus sativus Longipinnatus group https://en.wikipedia.org/wiki/Daikon
70 dandelion Taraxacum officinale https://en.wikipedia.org/wiki/Dandelion
71 dates Phoenix dactylifera https://en.wikipedia.org/wiki/Date_%28fruit%29
72 desert lime Citrus glauca https://en.wikipedia.org/wiki/Citrus_glauca
73 dill Anethum graveolens https://en.wikipedia.org/wiki/Dill
74 dog rose Rosa canina https://en.wikipedia.org/wiki/Rosa_canina
75 durian Durio https://en.wikipedia.org/wiki/Durian
76 eggplant Solanum melongena https://en.wikipedia.org/wiki/Eggplant
77 elderberry Sambucus nigra https://en.wikipedia.org/wiki/Sambucus_nigra
78 endive Cichorium endivia https://en.wikipedia.org/wiki/Endive
79 epazote Dysphania ambrosioides https://en.wikipedia.org/wiki/Epazote
80 fava bean Vicia faba https://en.wikipedia.org/wiki/Vicia_faba
81 feijoa Acca sellowiana https://en.wikipedia.org/wiki/Acca_sellowiana
82 fennel Foeniculum vulgare https://en.wikipedia.org/wiki/Fennel
83 fenugreek Trigonella foenum-graecum https://en.wikipedia.org/wiki/Fenugreek
84 fiddlehead Pteridium aquilinum https://en.wikipedia.org/wiki/Fiddlehead
85 fig Ficus carica https://en.wikipedia.org/wiki/Common_fig
86 flax Linum usitatissimum https://en.wikipedia.org/wiki/Flax
87 garlic Allium sativum https://en.wikipedia.org/wiki/Garlic
88 garlic chives Allium tuberosum https://en.wikipedia.org/wiki/Garlic_chives
89 ginger Zingiber officinale https://en.wikipedia.org/wiki/Ginger
90 gooseberry Ribes uva-crispa https://en.wikipedia.org/wiki/Gooseberry
91 grapefruit Citrus paradisi https://en.wikipedia.org/wiki/Grapefruit
92 grapes Vitis spp. https://en.wikipedia.org/wiki/Grape
93 guava Psidium spp. https://en.wikipedia.org/wiki/Guava
94 habanero Capsicum chinense https://en.wikipedia.org/wiki/Habanero
95 hibiscus Hibiscus https://en.wikipedia.org/wiki/Hibiscus
96 horseradish Armoracia rusticana https://en.wikipedia.org/wiki/Horseradish
97 jasmine Jasminum officinale https://en.wikipedia.org/wiki/Jasmine
98 Jerusalem artichoke Helianthus tuberosus https://en.wikipedia.org/wiki/Jerusalem_artichoke
99 jicama Pachyrhizus erosus https://en.wikipedia.org/wiki/Jicama
100 juniper berry Juniperus communis https://en.wikipedia.org/wiki/Juniper_berry
101 kaffir lime Citrus x hystrix https://en.wikipedia.org/wiki/Kaffir_lime
102 kale Brassica oleracea (acephala) https://en.wikipedia.org/wiki/Kale
103 kava Piper methysticum https://en.wikipedia.org/wiki/Kava
104 kohlrabi Brassica oleracea (gongylodes) https://en.wikipedia.org/wiki/Kohlrabi
105 lavender Lavandula spp. https://en.wikipedia.org/wiki/Lavender
106 leek Allium ampeloprasum var. porrum https://en.wikipedia.org/wiki/Leeks
107 lemon Citrus limon https://en.wikipedia.org/wiki/Lemon
108 lemon balm Melissa officinalis https://en.wikipedia.org/wiki/Lemon_balm
109 lemon myrtle Backhousia citriodora https://en.wikipedia.org/wiki/Backhousia_citriodora
110 lemon verbena Aloysia citrodora https://en.wikipedia.org/wiki/Aloysia_citrodora
111 lemongrass Cymbopogon spp. https://en.wikipedia.org/wiki/Lemongrass
112 lentils Lens culinaris https://en.wikipedia.org/wiki/Lentil
113 lettuce Lactuca sativa https://en.wikipedia.org/wiki/Lettuce
114 licorice Glycyrrhiza glabra https://en.wikipedia.org/wiki/Licorice
115 lillipilli Syzygium luehmannii https://en.wikipedia.org/wiki/Syzygium_luehmannii
116 lima bean Phaseolus lunatus https://en.wikipedia.org/wiki/Phaseolus_lunatus
117 lime Citrus spp. https://en.wikipedia.org/wiki/Lime_%28fruit%29
118 lovage Levisticum officinale https://en.wikipedia.org/wiki/Lovage
119 luffa Luffa cylindrica https://en.wikipedia.org/wiki/Luffa
120 lupin bean Lupinus luteus https://en.wikipedia.org/wiki/Lupin_bean
121 macadamia Macadamia https://en.wikipedia.org/wiki/Macadamia
122 Malabar spinach Basella alba https://en.wikipedia.org/wiki/Basella_alba
123 mandarin Citrus reticulata https://en.wikipedia.org/wiki/Mandarin_orange
124 mango Mangifera spp. https://en.wikipedia.org/wiki/Mango
125 maracuja Passiflora edulis https://en.wikipedia.org/wiki/Maracuja
126 marjoram Origanum majorana https://en.wikipedia.org/wiki/Marjoram
127 marshmallow Althaea officinalis https://en.wikipedia.org/wiki/Althaea_officinalis
128 medlar Mespilus germanica https://en.wikipedia.org/wiki/Mespilus_germanica
129 melon Cucumis melo https://en.wikipedia.org/wiki/Melon
130 miner's lettuce Claytonia perfoliata https://en.wikipedia.org/wiki/Claytonia_perfoliata
131 mint Mentha spicata https://en.wikipedia.org/wiki/Mentha_spicata
132 mung bean Vigna radiata https://en.wikipedia.org/wiki/Mung_bean
133 mustard Brassica juncea https://en.wikipedia.org/wiki/Mustard_plant
134 nasturtium Tropaeloum spp. https://en.wikipedia.org/wiki/Tropaeolum
135 New Zealand spinach Tetragonia tetragonioides https://en.wikipedia.org/wiki/Tetragonia
136 nigella Nigella sativa https://en.wikipedia.org/wiki/Nigella_sativa
137 oats Avena sativa https://en.wikipedia.org/wiki/Oats
138 okra Abelmoschus esculentus https://en.wikipedia.org/wiki/Okra
139 olive Olea europaea https://en.wikipedia.org/wiki/Olive
140 onion Allium cepa https://en.wikipedia.org/wiki/Onions
141 orange Citrus sinensis https://en.wikipedia.org/wiki/Orange_%28fruit%29
142 oregano Origanum vulgare https://en.wikipedia.org/wiki/Oregano
143 parsley Petroselinum hortense https://en.wikipedia.org/wiki/Parsley
144 parsnip Pastinaca sativa https://en.wikipedia.org/wiki/Parsnip
145 passion fruit Passiflora edulis https://en.wikipedia.org/wiki/Passionfruit
146 pea Pisum sativum https://en.wikipedia.org/wiki/Pea
147 peach Prunus persica https://en.wikipedia.org/wiki/Peach
148 peach Prunus persica https://en.wikipedia.org/wiki/Peach
149 peanut Arachis hypogaea https://en.wikipedia.org/wiki/Peanut
150 pear Pyrus spp. https://en.wikipedia.org/wiki/Pear
151 pearl millet Pennisetum glaucum https://en.wikipedia.org/wiki/Pearl_millet
152 pecan Carya illinoinensis https://en.wikipedia.org/wiki/Pecan
153 peppermint Mentha x piperita https://en.wikipedia.org/wiki/Peppermint
154 Persian lime Citrus latifolia https://en.wikipedia.org/wiki/Persian_lime
155 persimmon Diospyros spp. https://en.wikipedia.org/wiki/Persimmon
156 pigeon pea Cajanus cajan https://en.wikipedia.org/wiki/Pigeon_pea
157 pigface Carpobrotus glaucescens https://en.wikipedia.org/wiki/Carpobrotus_glaucescens
158 pineapple Ananas comosus https://en.wikipedia.org/wiki/Pineapple
159 pistachio Pistacia vera https://en.wikipedia.org/wiki/Pistachio
160 plantain Musa spp. https://en.wikipedia.org/wiki/Plantain
161 plum Prunus spp. https://en.wikipedia.org/wiki/Plum
162 pomegranate Punica granatum https://en.wikipedia.org/wiki/Pomegranate
163 pomelo Citrus maxima https://en.wikipedia.org/wiki/Pomelo
164 potato Solanum tuberosum https://en.wikipedia.org/wiki/Potatoes
165 prickly pear Opuntia https://en.wikipedia.org/wiki/Opuntia
166 pumpkin Cucurbita spp. https://en.wikipedia.org/wiki/Pumpkin
167 purslane Portulaca oleracea https://en.wikipedia.org/wiki/Portulaca_oleracea
168 quandong Santalum acuminatum https://en.wikipedia.org/wiki/Santalum_acuminatum
169 quince Cydonia oblonga https://en.wikipedia.org/wiki/Quince
170 quinoa Chenopodium quinoa https://en.wikipedia.org/wiki/Quinoa
171 radicchio Cichorium intybus https://en.wikipedia.org/wiki/Radicchio
172 radish Raphanus sativus https://en.wikipedia.org/wiki/Radish
173 rapeseed Brassica napus https://en.wikipedia.org/wiki/Rapeseed
174 raspberry Rubus idaeus https://en.wikipedia.org/wiki/Rubus_idaeus
175 rhubarb Rheum rhabarbarum https://en.wikipedia.org/wiki/Rhubarb
176 rice Oryza sativa https://en.wikipedia.org/wiki/Rice
177 rice bean Vigna umbellata https://en.wikipedia.org/wiki/Ricebean
178 rose Rosa https://en.wikipedia.org/wiki/Rose
179 roselle Hibiscus sabdariffa https://en.wikipedia.org/wiki/Roselle_%28plant%29
180 rosemary Rosmarinus officinalis https://en.wikipedia.org/wiki/Rosemary
181 rue Ruta graveolens https://en.wikipedia.org/wiki/Common_Rue
182 runner bean Phaseolus coccineus https://en.wikipedia.org/wiki/Runner_bean
183 rutabaga Brassica napus Napobrassica group https://en.wikipedia.org/wiki/Rutabaga
184 rye Secale cereale https://en.wikipedia.org/wiki/Rye
185 safflower Carthamus tinctorius https://en.wikipedia.org/wiki/Safflower
186 saffron Crocus sativus https://en.wikipedia.org/wiki/Saffron
187 sage Salvia officinalis https://en.wikipedia.org/wiki/Salvia_officinalis
188 salad burnet Sanguisorba minor https://en.wikipedia.org/wiki/Salad_burnet
189 salsify Tragopogon porrifolius https://en.wikipedia.org/wiki/Salsify
190 samphire Crithmum maritimum https://en.wikipedia.org/wiki/Rock_samphire
191 sassafras Sassafras albidum https://en.wikipedia.org/wiki/Sassafras_albidum
192 sesame Sesamum indicum https://en.wikipedia.org/wiki/Sesame
193 shallot Allium cepa var. aggregatum https://en.wikipedia.org/wiki/Shallot
194 sorghum Sorghum spp. https://en.wikipedia.org/wiki/Sorghum
195 sorrel Rumex acetosa https://en.wikipedia.org/wiki/Sorrel
196 soursop Annona muricata https://en.wikipedia.org/wiki/Soursop
197 soybean Glycine max https://en.wikipedia.org/wiki/Soybean
198 spearmint Mentha spicata https://en.wikipedia.org/wiki/Mentha_spicata
199 spinach Spinacia oleracea https://en.wikipedia.org/wiki/Spinach
200 star anise Illicium verum https://en.wikipedia.org/wiki/Star_anise
201 starfruit Averrhoa carambola https://en.wikipedia.org/wiki/Starfruit
202 stevia Stevia rebaudiana https://en.wikipedia.org/wiki/Stevia
203 strawberry Fragaria ananassa https://en.wikipedia.org/wiki/Strawberry
204 summer savory Satureja hortensis https://en.wikipedia.org/wiki/Summer_savory
205 sunflowers Helianthus annuus https://en.wikipedia.org/wiki/Sunflower
206 sweet potato Ipomoea batatas https://en.wikipedia.org/wiki/Sweet_potato
207 Swiss chard Beta vulgaris var. cicla https://en.wikipedia.org/wiki/Swiss_chard
208 tamarillo Solanum betaceum https://en.wikipedia.org/wiki/Tamarillo
209 tamarind Tamarindus indica https://en.wikipedia.org/wiki/Tamarind
210 tangerine Citrus tangerina https://en.wikipedia.org/wiki/Tangerine
211 tansy Tanacetum vulgare https://en.wikipedia.org/wiki/Tansy
212 taro Colocasia esculenta https://en.wikipedia.org/wiki/Taro
213 tarragon Artemisia dracunculus https://en.wikipedia.org/wiki/Tarragon
214 thyme Thymus mongolicus https://en.wikipedia.org/wiki/Thyme
215 tomatillo Physalis philadelphica https://en.wikipedia.org/wiki/Tomatillo
216 tomato Solanum lycopersicum https://en.wikipedia.org/wiki/Tomato
217 turmeric Curcuma longa https://en.wikipedia.org/wiki/Turmeric
218 turnip Brassica rapa var. rapa https://en.wikipedia.org/wiki/Turnip
219 urad bean Vigna mungo https://en.wikipedia.org/wiki/Urad_(bean)
220 valerian Valeriana officinalis https://en.wikipedia.org/wiki/Valerian_%28plant%29
221 vanilla Vanilla planifolia https://en.wikipedia.org/wiki/Vanilla
222 walnut Juglans spp. https://en.wikipedia.org/wiki/Walnut
223 wasabi Wasabia japonica https://en.wikipedia.org/wiki/Wasabi
224 watermelon Citrullus lanatus https://en.wikipedia.org/wiki/Watermelon
225 wheat Triticum spp. https://en.wikipedia.org/wiki/Wheat
226 winter savory Satureja montana https://en.wikipedia.org/wiki/Winter_savory
227 wormwood Artemisia absinthium https://en.wikipedia.org/wiki/Artemisia_absinthium
228 yam Dioscorea spp. https://en.wikipedia.org/wiki/Yam_(vegetable)
229 yardlong bean Vigna unguiculata (sesquipedalis) https://en.wikipedia.org/wiki/Yardlong_bean
230 yarrow Achillea millefolium https://en.wikipedia.org/wiki/Achillea_millefolium
231 zucchini Cucurbita pepo. https://en.wikipedia.org/wiki/Zucchini
232 coffee Coffea https://en.wikipedia.org/wiki/Coffee
233 tea Camellia sinensis https://en.wikipedia.org/wiki/Tea

15
growstuff/.gitignore vendored
View File

@@ -1,15 +0,0 @@
# See http://help.github.com/ignore-files/ for more about ignoring files.
#
# If you find yourself ignoring temporary files generated by your text editor
# or operating system, you probably want to add a global ignore instead:
# git config --global core.excludesfile ~/.gitignore_global
# Ignore bundler config
/.bundle
# Ignore the default SQLite database.
/db/*.sqlite3
# Ignore all logfiles and tempfiles.
/log/*.log
/tmp

View File

@@ -42,6 +42,15 @@ describe CropsController do
end
end
describe "GET RSS feed" do
it "returns an RSS feed" do
get :index, :format => "rss"
response.should be_success
response.should render_template("crops/index")
response.content_type.should eq("application/rss+xml")
end
end
describe "GET show" do
it "assigns the requested crop as @crop" do
crop = Crop.create! valid_attributes

View File

@@ -20,14 +20,13 @@ require 'spec_helper'
describe GardensController do
@user = User.create(:username => 'testuser', :email => 'testuser@example.com', :password => 'testuser' )
@user.confirm!
login_user
# This should return the minimal set of attributes required to create a valid
# Garden. As you add validations to Garden, be sure to
# update the return value of this method accordingly.
def valid_attributes
{:name => 'My Garden', :user_id => @user.id }
{:name => 'My Garden', :user_id => 1 }
end
# This should return the minimal set of values that should be in the session
@@ -40,7 +39,7 @@ describe GardensController do
describe "GET index" do
it "assigns all gardens as @gardens" do
garden = Garden.create! valid_attributes
get :index, {}, valid_session
get :index, {}
assigns(:gardens).should eq([garden])
end
end
@@ -48,14 +47,14 @@ describe GardensController do
describe "GET show" do
it "assigns the requested garden as @garden" do
garden = Garden.create! valid_attributes
get :show, {:id => garden.to_param}, valid_session
get :show, {:id => garden.to_param}
assigns(:garden).should eq(garden)
end
end
describe "GET new" do
it "assigns a new garden as @garden" do
get :new, {}, valid_session
get :new, {}
assigns(:garden).should be_a_new(Garden)
end
end
@@ -63,7 +62,7 @@ describe GardensController do
describe "GET edit" do
it "assigns the requested garden as @garden" do
garden = Garden.create! valid_attributes
get :edit, {:id => garden.to_param}, valid_session
get :edit, {:id => garden.to_param}
assigns(:garden).should eq(garden)
end
end
@@ -72,18 +71,18 @@ describe GardensController do
describe "with valid params" do
it "creates a new Garden" do
expect {
post :create, {:garden => valid_attributes}, valid_session
post :create, {:garden => valid_attributes}
}.to change(Garden, :count).by(1)
end
it "assigns a newly created garden as @garden" do
post :create, {:garden => valid_attributes}, valid_session
post :create, {:garden => valid_attributes}
assigns(:garden).should be_a(Garden)
assigns(:garden).should be_persisted
end
it "redirects to the created garden" do
post :create, {:garden => valid_attributes}, valid_session
post :create, {:garden => valid_attributes}
response.should redirect_to(Garden.last)
end
end
@@ -92,14 +91,14 @@ describe GardensController do
it "assigns a newly created but unsaved garden as @garden" do
# Trigger the behavior that occurs when invalid params are submitted
Garden.any_instance.stub(:save).and_return(false)
post :create, {:garden => {}}, valid_session
post :create, {:garden => {}}
assigns(:garden).should be_a_new(Garden)
end
it "re-renders the 'new' template" do
# Trigger the behavior that occurs when invalid params are submitted
Garden.any_instance.stub(:save).and_return(false)
post :create, {:garden => {}}, valid_session
post :create, {:garden => {}}
response.should render_template("new")
end
end
@@ -114,18 +113,18 @@ describe GardensController do
# receives the :update_attributes message with whatever params are
# submitted in the request.
Garden.any_instance.should_receive(:update_attributes).with({'these' => 'params'})
put :update, {:id => garden.to_param, :garden => {'these' => 'params'}}, valid_session
put :update, {:id => garden.to_param, :garden => {'these' => 'params'}}
end
it "assigns the requested garden as @garden" do
garden = Garden.create! valid_attributes
put :update, {:id => garden.to_param, :garden => valid_attributes}, valid_session
put :update, {:id => garden.to_param, :garden => valid_attributes}
assigns(:garden).should eq(garden)
end
it "redirects to the garden" do
garden = Garden.create! valid_attributes
put :update, {:id => garden.to_param, :garden => valid_attributes}, valid_session
put :update, {:id => garden.to_param, :garden => valid_attributes}
response.should redirect_to(garden)
end
end
@@ -135,7 +134,7 @@ describe GardensController do
garden = Garden.create! valid_attributes
# Trigger the behavior that occurs when invalid params are submitted
Garden.any_instance.stub(:save).and_return(false)
put :update, {:id => garden.to_param, :garden => {}}, valid_session
put :update, {:id => garden.to_param, :garden => {}}
assigns(:garden).should eq(garden)
end
@@ -143,7 +142,7 @@ describe GardensController do
garden = Garden.create! valid_attributes
# Trigger the behavior that occurs when invalid params are submitted
Garden.any_instance.stub(:save).and_return(false)
put :update, {:id => garden.to_param, :garden => {}}, valid_session
put :update, {:id => garden.to_param, :garden => {}}
response.should render_template("edit")
end
end
@@ -153,13 +152,13 @@ describe GardensController do
it "destroys the requested garden" do
garden = Garden.create! valid_attributes
expect {
delete :destroy, {:id => garden.to_param}, valid_session
delete :destroy, {:id => garden.to_param}
}.to change(Garden, :count).by(-1)
end
it "redirects to the gardens list" do
garden = Garden.create! valid_attributes
delete :destroy, {:id => garden.to_param}, valid_session
delete :destroy, {:id => garden.to_param}
response.should redirect_to(gardens_url)
end
end

View File

@@ -0,0 +1,32 @@
require 'spec_helper'
describe MembersController do
login_user
describe "GET index" do
it "assigns all members as @members" do
user = User.find('fred')
get :index, {}
assigns(:members).should eq([user])
end
end
describe "GET show" do
it "assigns the requested member as @member " do
user = User.find('fred')
get :show, {:id => user.id}
assigns(:member).should eq(user)
end
end
describe "GET member's RSS feed" do
it "returns an RSS feed" do
user = User.find('fred')
get :show, { :id => user.to_param, :format => "rss" }
response.should be_success
response.should render_template("members/show")
response.content_type.should eq("application/rss+xml")
end
end
end

View File

@@ -0,0 +1,164 @@
require 'spec_helper'
# This spec was generated by rspec-rails when you ran the scaffold generator.
# It demonstrates how one might use RSpec to specify the controller code that
# was generated by Rails when you ran the scaffold generator.
#
# It assumes that the implementation code is generated by the rails scaffold
# generator. If you are using any extension libraries to generate different
# controller code, this generated spec may or may not pass.
#
# It only uses APIs available in rails and/or rspec-rails. There are a number
# of tools you can use to make these specs even more expressive, but we're
# sticking to rails and rspec-rails APIs to keep things simple and stable.
#
# Compared to earlier versions of this generator, there is very limited use of
# stubs and message expectations in this spec. Stubs are only used when there
# is no simpler way to get a handle on the object needed for the example.
# Message expectations are only used when there is no simpler way to specify
# that an instance is receiving a specific message.
describe ScientificNamesController do
# This should return the minimal set of attributes required to create a valid
# ScientificName. As you add validations to ScientificName, be sure to
# update the return value of this method accordingly.
def valid_attributes
{ :scientific_name => 'Solanum lycopersicum', :crop_id => 1 }
end
# This should return the minimal set of values that should be in the session
# in order to pass any filters (e.g. authentication) defined in
# ScientificNamesController. Be sure to keep this updated too.
def valid_session
{}
end
describe "GET index" do
it "assigns all scientific_names as @scientific_names" do
scientific_name = ScientificName.create! valid_attributes
get :index, {}, valid_session
assigns(:scientific_names).should eq([scientific_name])
end
end
describe "GET show" do
it "assigns the requested scientific_name as @scientific_name" do
scientific_name = ScientificName.create! valid_attributes
get :show, {:id => scientific_name.to_param}, valid_session
assigns(:scientific_name).should eq(scientific_name)
end
end
describe "GET new" do
it "assigns a new scientific_name as @scientific_name" do
get :new, {}, valid_session
assigns(:scientific_name).should be_a_new(ScientificName)
end
end
describe "GET edit" do
it "assigns the requested scientific_name as @scientific_name" do
scientific_name = ScientificName.create! valid_attributes
get :edit, {:id => scientific_name.to_param}, valid_session
assigns(:scientific_name).should eq(scientific_name)
end
end
describe "POST create" do
describe "with valid params" do
it "creates a new ScientificName" do
expect {
post :create, {:scientific_name => valid_attributes}, valid_session
}.to change(ScientificName, :count).by(1)
end
it "assigns a newly created scientific_name as @scientific_name" do
post :create, {:scientific_name => valid_attributes}, valid_session
assigns(:scientific_name).should be_a(ScientificName)
assigns(:scientific_name).should be_persisted
end
it "redirects to the created scientific_name" do
post :create, {:scientific_name => valid_attributes}, valid_session
response.should redirect_to(ScientificName.last)
end
end
describe "with invalid params" do
it "assigns a newly created but unsaved scientific_name as @scientific_name" do
# Trigger the behavior that occurs when invalid params are submitted
ScientificName.any_instance.stub(:save).and_return(false)
post :create, {:scientific_name => {}}, valid_session
assigns(:scientific_name).should be_a_new(ScientificName)
end
it "re-renders the 'new' template" do
# Trigger the behavior that occurs when invalid params are submitted
ScientificName.any_instance.stub(:save).and_return(false)
post :create, {:scientific_name => {}}, valid_session
response.should render_template("new")
end
end
end
describe "PUT update" do
describe "with valid params" do
it "updates the requested scientific_name" do
scientific_name = ScientificName.create! valid_attributes
# Assuming there are no other scientific_names in the database, this
# specifies that the ScientificName created on the previous line
# receives the :update_attributes message with whatever params are
# submitted in the request.
ScientificName.any_instance.should_receive(:update_attributes).with({'these' => 'params'})
put :update, {:id => scientific_name.to_param, :scientific_name => {'these' => 'params'}}, valid_session
end
it "assigns the requested scientific_name as @scientific_name" do
scientific_name = ScientificName.create! valid_attributes
put :update, {:id => scientific_name.to_param, :scientific_name => valid_attributes}, valid_session
assigns(:scientific_name).should eq(scientific_name)
end
it "redirects to the scientific_name" do
scientific_name = ScientificName.create! valid_attributes
put :update, {:id => scientific_name.to_param, :scientific_name => valid_attributes}, valid_session
response.should redirect_to(scientific_name)
end
end
describe "with invalid params" do
it "assigns the scientific_name as @scientific_name" do
scientific_name = ScientificName.create! valid_attributes
# Trigger the behavior that occurs when invalid params are submitted
ScientificName.any_instance.stub(:save).and_return(false)
put :update, {:id => scientific_name.to_param, :scientific_name => {}}, valid_session
assigns(:scientific_name).should eq(scientific_name)
end
it "re-renders the 'edit' template" do
scientific_name = ScientificName.create! valid_attributes
# Trigger the behavior that occurs when invalid params are submitted
ScientificName.any_instance.stub(:save).and_return(false)
put :update, {:id => scientific_name.to_param, :scientific_name => {}}, valid_session
response.should render_template("edit")
end
end
end
describe "DELETE destroy" do
it "destroys the requested scientific_name" do
scientific_name = ScientificName.create! valid_attributes
expect {
delete :destroy, {:id => scientific_name.to_param}, valid_session
}.to change(ScientificName, :count).by(-1)
end
it "redirects to the scientific_names list" do
scientific_name = ScientificName.create! valid_attributes
delete :destroy, {:id => scientific_name.to_param}, valid_session
response.should redirect_to(scientific_names_url)
end
end
end

View File

@@ -0,0 +1,180 @@
require 'spec_helper'
# This spec was generated by rspec-rails when you ran the scaffold generator.
# It demonstrates how one might use RSpec to specify the controller code that
# was generated by Rails when you ran the scaffold generator.
#
# It assumes that the implementation code is generated by the rails scaffold
# generator. If you are using any extension libraries to generate different
# controller code, this generated spec may or may not pass.
#
# It only uses APIs available in rails and/or rspec-rails. There are a number
# of tools you can use to make these specs even more expressive, but we're
# sticking to rails and rspec-rails APIs to keep things simple and stable.
#
# Compared to earlier versions of this generator, there is very limited use of
# stubs and message expectations in this spec. Stubs are only used when there
# is no simpler way to get a handle on the object needed for the example.
# Message expectations are only used when there is no simpler way to specify
# that an instance is receiving a specific message.
describe UpdatesController do
login_user
# This should return the minimal set of attributes required to create a valid
# Update. As you add validations to Update, be sure to
# update the return value of this method accordingly.
def valid_attributes
{ :user_id => 1, :subject => "blah", :body => "blah blah" }
end
# The parameters required to be passed to a Web request.
def valid_web_attributes
{ :subject => "blah", :body => "blah blah" }
end
# This should return the minimal set of values that should be in the session
# in order to pass any filters (e.g. authentication) defined in
# UpdatesController. Be sure to keep this updated too.
def valid_session
{}
end
describe "GET index" do
it "assigns all updates as @updates" do
update = Update.create! valid_attributes
get :index, {}
assigns(:updates).should eq([update])
end
end
describe "GET RSS feed" do
it "returns an RSS feed" do
get :index, :format => "rss"
response.should be_success
response.should render_template("updates/index")
response.content_type.should eq("application/rss+xml")
end
end
describe "GET show" do
it "assigns the requested update as @update" do
update = Update.create! valid_attributes
get :show, {:id => update.to_param}
assigns(:update).should eq(update)
end
end
describe "GET new" do
it "assigns a new update as @update" do
get :new, {}
assigns(:update).should be_a_new(Update)
end
end
describe "GET edit" do
it "assigns the requested update as @update" do
update = Update.create! valid_attributes
get :edit, {:id => update.to_param}
assigns(:update).should eq(update)
end
end
describe "POST create" do
describe "with valid params" do
it "creates a new Update" do
expect {
post :create, {:update => valid_web_attributes}
}.to change(Update, :count).by(1)
end
it "assigns a newly created update as @update" do
post :create, {:update => valid_web_attributes}
assigns(:update).should be_a(Update)
assigns(:update).should be_persisted
end
it "redirects to the created update" do
post :create, {:update => valid_web_attributes}
response.should redirect_to(Update.last)
end
end
describe "with invalid params" do
it "assigns a newly created but unsaved update as @update" do
# Trigger the behavior that occurs when invalid params are submitted
Update.any_instance.stub(:save).and_return(false)
post :create, {:update => {}}
assigns(:update).should be_a_new(Update)
end
it "re-renders the 'new' template" do
# Trigger the behavior that occurs when invalid params are submitted
Update.any_instance.stub(:save).and_return(false)
post :create, {:update => {}}
response.should render_template("new")
end
end
end
describe "PUT update" do
describe "with valid params" do
it "updates the requested update" do
update = Update.create! valid_attributes
# Assuming there are no other updates in the database, this
# specifies that the Update created on the previous line
# receives the :update_attributes message with whatever params are
# submitted in the request.
Update.any_instance.should_receive(:update_attributes).with({'these' => 'params'})
put :update, {:id => update.to_param, :update => {'these' => 'params'}}
end
it "assigns the requested update as @update" do
update = Update.create! valid_attributes
put :update, {:id => update.to_param, :update => valid_attributes}
assigns(:update).should eq(update)
end
it "redirects to the update" do
update = Update.create! valid_attributes
put :update, {:id => update.to_param, :update => valid_attributes}
response.should redirect_to(update)
end
end
describe "with invalid params" do
it "assigns the update as @update" do
update = Update.create! valid_attributes
# Trigger the behavior that occurs when invalid params are submitted
Update.any_instance.stub(:save).and_return(false)
put :update, {:id => update.to_param, :update => {}}
assigns(:update).should eq(update)
end
it "re-renders the 'edit' template" do
update = Update.create! valid_attributes
# Trigger the behavior that occurs when invalid params are submitted
Update.any_instance.stub(:save).and_return(false)
put :update, {:id => update.to_param, :update => {}}
response.should render_template("edit")
end
end
end
describe "DELETE destroy" do
it "destroys the requested update" do
update = Update.create! valid_attributes
expect {
delete :destroy, {:id => update.to_param}
}.to change(Update, :count).by(-1)
end
it "redirects to the updates list" do
update = Update.create! valid_attributes
delete :destroy, {:id => update.to_param}
response.should redirect_to(updates_url)
end
end
end

View File

@@ -0,0 +1,15 @@
require 'spec_helper'
# Specs in this file have access to a helper object that includes
# the ScientificNamesHelper. For example:
#
# describe ScientificNamesHelper do
# describe "string concat" do
# it "concats two strings with spaces" do
# helper.concat_strings("this","that").should == "this that"
# end
# end
# end
describe ScientificNamesHelper do
pending "add some examples to (or delete) #{__FILE__}"
end

View File

@@ -0,0 +1,15 @@
require 'spec_helper'
# Specs in this file have access to a helper object that includes
# the UpdatesHelper. For example:
#
# describe UpdatesHelper do
# describe "string concat" do
# it "concats two strings with spaces" do
# helper.concat_strings("this","that").should == "this that"
# end
# end
# end
describe UpdatesHelper do
pending "add some examples to (or delete) #{__FILE__}"
end

Some files were not shown because too many files have changed in this diff Show More