<file_sep>## boot cap libs
#
  load 'deploy' if respond_to?(:namespace) # cap2 differentiator
  Dir['vendor/plugins/*/recipes/*.rb'].each { |plugin| load(plugin) }

## multistage (require 'capistrano/ext/multistage')
#
  set :stages, %w( staging production )
  set :default_stage, "staging"
  set :normalize_asset_timestamps, false

  location = fetch(:stage_dir, "config/deploy")
  unless exists?(:stages)
    set :stages, Dir["#{location}/*.rb"].map { |f| File.basename(f, ".rb") }
  end
  stages.each do |name| 
    desc "Set the target stage to `#{name}'."
    task(name) do 
      set :stage, name.to_sym 
      load "#{location}/#{stage}" 
    end 
  end 
  namespace :multistage do
    desc "[internal] Ensure that a stage has been selected."
    task :ensure do
      if !exists?(:stage)
        if exists?(:default_stage)
          logger.important "Defaulting to `#{default_stage}'"
          find_and_execute_task(default_stage)
        else
          abort "No stage specified. Please specify one of: #{stages.join(', ')} (e.g. `cap #{stages.first} #{ARGV.last}')"
        end
      end 
    end
    desc "Stub out the staging config files."
    task :prepare do
      FileUtils.mkdir_p(location)
      stages.each do |name|
        file = File.join(location, name + ".rb")
        unless File.exists?(file)
          File.open(file, "w") do |f|
            f.puts "# #{name.upcase}-specific deployment configuration"
            f.puts "# please put general deployment config in config/deploy.rb"
          end
        end
      end
    end
  end
  on :start, "multistage:ensure", :except => stages + ['multistage:prepare']

## force a remote rebenv version iff a local one has been configured
#
  rails_root = File.expand_path(File.dirname(__FILE__))
  rbenv_version = File.join(rails_root, '.rbenv-version')
  if test(?e, rbenv_version)
    default_environment['RBENV_VERSION'] = IO.read(rbenv_version).strip
  end

## setup remote PATH.  it's important that this picks up rbenv!
#
  default_environment['PATH'] = (
    '/usr/local/rbenv/shims:/usr/local/rbenv/bin:' +
    default_environment.fetch('PATH', '') +
    '/bin:/usr/bin:/usr/local/bin:/sbin:/usr/sbin'
  )

## suck in some app settings - we'll use the identifier to configure tons of
# stuff
#
  load File.join(File.join(rails_root, 'lib/settings.rb'))
  set(:identifier, Settings.for('data/site.yml')['identifier'])

## make rake run in the proper environment
#
  set(:rake, "bundle exec rake")

## bundler (require 'bundler/capistrano.rb')
#
  namespace :bundle do
    task :symlinks, :roles => :app do
      shared_dir = File.join(shared_path, 'bundle')
      release_dir = File.join(current_release, '.bundle')
      run("mkdir -p #{shared_dir} && rm -rf #{release_dir} && ln -s -f -F #{shared_dir} #{release_dir}")
    end

    task :install, :except => { :no_release => true } do
      bundle_dir     = fetch(:bundle_dir,         "#{fetch(:shared_path)}/bundle")
      bundle_without = [*fetch(:bundle_without,   [:development, :test])].compact
      bundle_flags   = fetch(:bundle_flags, "--deployment --quiet")
      bundle_gemfile = fetch(:bundle_gemfile,     "Gemfile")
      bundle_cmd     = fetch(:bundle_cmd, "bundle")

      args = ["--gemfile #{fetch(:latest_release)}/#{bundle_gemfile}"]
      args << "--path #{bundle_dir}" unless bundle_dir.to_s.empty?
      args << bundle_flags.to_s
      args << "--without #{bundle_without.join(" ")}" unless bundle_without.empty?
      args << "--binstubs bin"

      run "#{bundle_cmd} install #{args.join(' ')}"
    end
  end
  after 'deploy:update_code', 'bundle:symlinks'
  after "deploy:update_code", "bundle:install"


## vomit noise into campfire
#
  namespace :notify do
    desc 'alert campfire of a deploy'
    task :campfire do
      user = `git config --global --get user.name 2>/dev/null`.strip
      if user.empty?
        user = ENV['USER']
      end
      application = fetch(:application)
      stage = fetch(:stage)

      domain = 'dojo4'
      token = 'f9831e567f7237563baa64b90e65a135f223100f'
      room = "Roboto's House of Wonders"

      begin
        require 'tinder'
        campfire = Tinder::Campfire.new(domain, :token => token)
        room = campfire.rooms.detect{|_| _.name == room}
        room.speak("#{ user } deployed #{ application } to #{ stage }")
      rescue LoadError
        warn "gem install tinder # to notify #{ domain }/#{ room } campfire..."
      end
    end
  end
  after "deploy", "notify:campfire"

  namespace :deploy do
    task :build do#, :roles => :app do
      run("cd #{ deploy_to }/current &&  ./bin/middleman build; true")
    end
  end
  after 'deploy:create_symlink', 'deploy:build'

## link vhost config
#
  namespace :deploy do
    task :link_vhost do
      run "sudo ln -s #{ deploy_to }/current/config/deploy/os_files/etc/apache2/sites-enabled/#{ stage }.conf /etc/apache2/sites-enabled/#{ identifier }.#{ stage }"
      run "if sudo apache2ctl configtest; then sudo apache2ctl restart; fi; true"
    end
  end
<file_sep>require 'bitballoon'
require 'yaml'

# this is currently experimental. DONT USE

BUILD_DIR = 'build'
CONFIG_FILE = 'config/bitballoon.yaml'
YOUR_SITE_NAME = 'Org Dev'

namespace :bitballoon do

  def load_config
    $config = YAML::load_file(CONFIG_FILE)
  end

  def save_config
    puts 'saving config...'
    if $config.nil?
      puts 'config is nil so not doing anything'
    else
      puts $config.inspect
      File.open(CONFIG_FILE, 'w') { |f| f.write $config.to_yaml }
      puts 'config saved.'
    end
  end

  def auth
    load_config
    if $config['account']['access_token'].nil?
      puts 'using client_id and client_secret to authenticate'
      bitballoon = BitBalloon::Client.new(:client_id => $config['account']['client_id'], :client_secret => $config['account']['client_secret'])
      bitballoon.authorize_from_credentials!
      $config['account']['access_token'] = bitballoon.access_token
      save_config
      bitballoon
    else
      puts 'using token to authenticate'
      bitballoon = BitBalloon::Client.new(:access_token => $config['account']['access_token'])
      begin
        bitballoon.request(:get, 'users')
        bitballoon
      rescue BitBalloon::Client::AuthenticationError
        puts 'token has been revoked or updated, so clearing & using creds to auth and get new token'
        $config['account']['access_token'] = nil
        save_config
        auth        
      end
    end
  end

  def notify_term(url)
    begin
      require 'terminal-notifier'
      system "terminal-notifier -title #{YOUR_SITE_NAME} -message 'Deploy completed successfully to #{ url }.' -sound default"
    rescue LoadError
    end
  end
  
  desc "deploy site to bitballoon"
  task :deploy => :'rake:build' do
    puts 'Deploying site...'

    # authenticate
    bitballoon = auth

    # actually deploy
    begin
      # if site exists, just update
      if $config['site']['id'].nil? && $config['site']['url'].nil?
        raise BitBalloon::Client::NotFoundError
      else
        site = bitballoon.sites.get($config['site']['id'] || $config['site']['url'])
        puts 'the site exists, so simply updating...'
        site.update(:dir => BUILD_DIR)
      end
    rescue BitBalloon::Client::NotFoundError
      # if site hasn't been created yet, create it
      puts 'the site does NOT exist, so creating it'
      site = bitballoon.sites.create(:dir => BUILD_DIR)
      $config['site']['id'] = site.id
      $config['site']['url'] = site.url
      save_config
    end

    # wait until the deploy is done...
    site.wait_for_ready

    # notify campfire and end.
    puts '...deploy finished!'
    puts('Site was deployed to: ' + $config['site']['url'])

    # use terminal notifier if it's available
    notify_term($config['site']['url'])
  end

  desc "list all sites on our account"
  task :list do
    bitballoon = auth
    bitballoon.sites.each do |s|
      puts('s.id = ' + s.id + '; s.url = ' + s.url)
    end
  end

  desc "destroy the site"
  task :destroy do
    bitballoon = auth
    begin
      # if site exists, just update
      site = bitballoon.sites.get($config['site']['id'] || $config['site']['url'])
      site.destroy!
    rescue BitBalloon::Client::NotFoundError
      puts "no site to destroy. so doing nothing."
    end
  end

  desc "destroy all of your sites DANGEROUS"
  task :destroyall do
    bitballoon = auth
    bitballoon.sites.each do |s|
      s.destroy!
    end
  end


end


<file_sep># we need to ensure we're running in bundler
begin
  Bundler
rescue
  abort("Make sure you're running 'bundle exec middleman'. If you are and still getting this error, config.rb needs attention.")
end

### 
# Compass
###

# Susy grids in Compass
# First: gem install compass-susy-plugin
# require 'susy'

# Change Compass configuration
# compass_config do |config|
#   config.output_style = :compact
# end

###
# Haml
###

# CodeRay syntax highlighting in Haml
# First: gem install haml-coderay
# require 'haml-coderay'

# CoffeeScript filters in Haml
# First: gem install coffee-filter
# require 'coffee-filter'

# Automatic image dimensions on image_tag helper
# activate :automatic_image_sizes

###
# Page command
###

# Per-page layout changes:
# 
# With no layout
# page "/path/to/file.html", :layout => false
# 
# With alternative layout
# page "/path/to/file.html", :layout => :otherlayout
# 
# A path which all have the same layout
# with_layout :admin do
#   page "/admin/*"
# end

# Proxy (fake) files
# page "/this-page-has-no-template.html", :proxy => "/template-file.html" do
#   @which_fake_page = "Rendering a fake page with a variable"
# end

###
# Helpers
###

# Methods defined in the helpers block are available in templates
helpers do
  def custom_or_default_content(thingy)
      if content_for?(thingy)
        yield_content(thingy)
      else
        data.site.send(thingy) || ''
      end
  end
end

activate :syntax

# Change the CSS directory
# set :css_dir, "alternative_css_directory"

# Change the JS directory
# set :js_dir, "alternative_js_directory"

# Change the images directory
# set :images_dir, "alternative_image_directory"

# Build-specific configuration
configure :build do
  # For example, change the Compass output style for deployment
   activate :minify_css
  
  # Minify Javascript on build
   activate :minify_javascript
  
  # Enable cache buster
   activate :cache_buster
  
  # Use relative URLs
  activate :relative_assets
  
  # Compress PNGs after build
  # First: gem install middleman-smusher
  # require "middleman-smusher"
  # activate :smusher
  
  # Or use a different image path
  # set :http_path, "/Content/images/"
end

activate :directory_indexes
page "/404.html", :directory_index => false

require 'susy'

# Methods defined in the helpers block are available in templates
helpers do
  # Calculate the years for a copyright
  def copyright_years(start_year)
    end_year = Date.today.year
    if start_year == end_year
      start_year.to_s
    else
      start_year.to_s + '-' + end_year.to_s
    end
  end
end

require 'lib/aws_buckets'

def sekrets
  @sekrets ||= (
    key = IO.read('.sekrets.key').strip rescue nil
    Sekrets.settings_for('./config/sekrets.yml.enc', :key => key)
  )
end

def settings
  @settings ||= (
    Map.for(sekrets.aws)
  )
end

begin
  AWS.config({
    :access_key_id     => settings.access_key_id,
    :secret_access_key => settings.secret_access_key,
    :region            => settings.region
  })

  bucket_name         = settings.bucket

  unless bucket_name.blank?
    AWSBuckets.create_unless_exists!(AWS::S3, bucket_name)

    #FIXME: configure bucket for static site hosting through API

    s3                  = AWS::S3.new(:s3_endpoint => 's3.amazonaws.com')
    location_constraint = s3.buckets[bucket_name].location_constraint
    endpoint            = ['s3', location_constraint].compact.join('-') + '.amazonaws.com'
    bucket              = AWS::S3.new(:s3_endpoint => endpoint).buckets[bucket_name]

    bucket.cors = {
      :allowed_origins => %w'*',
      :allowed_methods => %w'GET POST PUT',
      #:allowed_headers => %w'origin accept x-requested-with content-type',
      :allowed_headers => %w'*',
      #:max_age_seconds => 3600,
    }

    bucket.cors.each do |rule|
      #p rule
    end

    #object = bucket.objects['pages/assets.js']
  end
rescue Exception => e
  puts "Error initializing AWS: #{e}"
end

# Activate sync extension
activate :s3_sync do |sync|
  sync.bucket =  settings.bucket # Your bucket name
  sync.region = settings.region # The region your storage bucket is in (eg us-east-1, us-west-1, eu-west-1, ap-southeast-1 )
  sync.aws_access_key_id = settings.access_key_id # Your Amazon S3 access key
  sync.aws_secret_access_key = settings.secret_access_key # Your Amazon S3 access secret
  sync.delete = true # Do not delete when sync'ing
  sync.after_build = false # Disable sync to run after Middleman build ( defaults to true )
  sync.prefer_gzip = true
end

default_caching_policy max_age:(60 * 60 * 24 * 365)
caching_policy 'text/html', max_age:0, must_revalidate: true, no_cache: true
<file_sep>class AWSBuckets
  def AWSBuckets.create_unless_exists!(s3, bucket_name)
    bucket = s3::Bucket.new(bucket_name)
    unless bucket.exists?
      s3.new.buckets.create(bucket_name)
    end
  end
end
<file_sep>## How to bootstrap a Middleman site from this repo

1. <code>git clone <EMAIL>:dojo4/static_site.git</code>
2. Create a new repo under the dojo4 account on github.com
4. Switch the current directory to the new repo: <code>cd new_repo</code>
5. Remove the .git directory: <code>rm -rf .git</code>
6. Initialize the new git repo: <code>git init</code>
7. Add the github remote: <code>git remote add origin <EMAIL>:dojo4/new_repo_name
8. Remove vendor bundle <code>rm -rf ./vendor/bundle/ruby/</code>
9. Run <code>bundle install</code> to install the necessary gems.
10. Recrypt the sekrets config: <code>sekrets recrypt config/sekrets.yml.enc</code>
11. Create a new .sekrets.key with the new password you created above
12. Hack.

You can push to GitHub as needed from that point forward.

## How to run the middleman server locally for development

1. <code>bundle exec middleman</code>
2. point your browser at localhost:4567

## How to deploy

### Update AWS details like bucket names

<code>vi .sekrets.key</code>
<code>sekrets edit ./config/sekrets.yml.enc</code>
<code>rake deploy:staging</code> in the new folder will push the new site
to the server.

## How to browse to your site?

Point your browser to [http://static_site.site.dojo4.com](http://static_site.site.dojo4.com)

<file_sep># Loads the site specific rake tasks.
Dir.glob('lib/tasks/**/*.rake').each do |f|
  load f
end

<file_sep>identifier = fetch(:identifier)

set :application, identifier
set :repository,  "<EMAIL>:dojo4/#{ identifier }.git"
set :user, "dojo4"
set :deploy_to, "/ebs/sites/#{ identifier }"

set :scm, :git
set :deploy_via, :remote_cache

# be sure to run 'ssh-add' on your local machine
system "ssh-add 2>&1" unless ENV['NO_SSH_ADD']
ssh_options[:forward_agent] = true

set :deploy_via, :remote_cache
set :branch, "master" unless exists?(:branch)
set :use_sudo, false

ip = "d0.dojo4.com"
role :web, ip                          # Your HTTP server, Apache/etc
role :app, ip                          # This may be the same as your `Web` server
role :db,  ip, :primary => true # This is where Rails migrations will run
#role :db,  "your slave db-server here"

set(:url, "http://#{ identifier }.development.dojo4.com")
<file_sep>desc "Cleans up the build directory"
task :clean do
  unless system 'rm -rf build'
    fail "Couldn't clean up directory"
  end
end

desc "Runs the Middleman server"
task :server do
  system 'middleman server'
end

desc "Builds the Middleman site"
task :build do
  unless system 'middleman build'
    fail "Middleman build failed."
  end
end

desc "Set STAGE to staging"
task "set_staging_env" do
  ENV['STAGE'] = 'staging'
end

desc "Set STAGE to qa"
task "set_qa_env" do
  ENV['STAGE'] = 'qa'
end

desc "Set STAGE to production"
task "set_production_env" do
  ENV['STAGE'] = 'production'
end

namespace :deploy do
  desc "Deploy static site to staging"
  task :staging => [:set_staging_env, :clean, :build, 'deploy:sync'] do
    notify(":shipit: #{ user } deployed #{repo_name} to staging")
  end

  desc "Deploy static site to qa"
  task :qa => [:set_qa_env, :clean, :build, 'deploy:sync'] do
    notify(":shipit: #{ user } deployed #{repo_name} to qa")
  end

  desc "Confirm deploy static site to production"
  task :production_confirm do
    confirmation_string = "deploy to production"
    puts "Production deploy initiated!"
    puts "Please type '#{confirmation_string}' then press return to confirm."
    unless STDIN.gets.strip == confirmation_string
      fail "Production deploy canceled"
    end
  end

  desc "Deploy static site to production"
  task :production => [:production_confirm, :set_production_env, :clean, :build, 'deploy:sync'] do
    notify(":shipit: #{ user } deployed #{repo_name} to production")
  end

  desc "Syncs with S3"
  task :sync do
    retries = 5
    while retries > 0
      if system 'middleman s3_sync'
        puts "Sync to stage #{ENV['STAGE']} completed OK."
        break
      else
        retries -= 1
        puts "Sync error while syncing to stage: #{ENV['STAGE']}."
      end
    end
  end

  def notify(message)
    require 'flowdock'

    # create a new Flow object with target flow's api token and sender information
    flow = Flowdock::Flow.new(
              api_token: "7e1c8271ffb6351a6405237d73b83383",
              source: "Rake deployment",
              project: app_name,
              from: {name: "<NAME>", address: "<EMAIL>"}
           )

    # send message to the flow
    flow.push_to_team_inbox(
      format: "html", 
      subject: "#{ app_name } deployed to #{ ENV['STAGE'] }",
      content: message, 
      tags: ["deploy", app_name]
    )
  rescue LoadError
    warn "gem install flowdock # to notify dojo4 flowdock..."
  end

  def repo_name
    @repo_name ||= `git remote -v` =~ %r{/(.+)(\.git)? \(fetch\)} && $1.split('/').last
  end

  def app_name
    repo_name.sub('.git', '')
  end

  def user
    ENV['USER']
  end

  def root_dir
    @root_dir ||= Rake.application.original_dir
  end
end

namespace :test do
  desc "tests notifying flowdock of a message"
  task :notify do
    notify("this is a test")
  end
end
<file_sep>var initHooch = function(){
  hooch = {
    Emptier: Class.extend({
      init: function($emptier){
        $target = $($emptier.data('target'));
        $emptier.click(function(e){
          $target.empty();
        })
      }
    }),
    Toggler: Class.extend({
      init: function(jq_obj){
        this.jq_obj = jq_obj;
        this.label = jq_obj.data('toggler');
        this.value = jq_obj.val();
        this.targets = $('[data-toggle_trigger="' + this.label + '"]');
        this.targets.hide();
        this.targets.filter('[data-toggle_value="' + this.value + '"]').show();
      }
    }),
    HoverOverflow: Class.extend({
      init: function(jq_obj){
        this.old_border = jq_obj.css('border-right');
        this.old_z_index = jq_obj.css('z-index');
        var hoverable = this;
        jq_obj.bind('mouseover',function(){
          hoverable.jq_obj.css({'overflow':'visible','z-index':'10000','border-right':'1px solid white'});
        });
        jq_obj.bind('mouseout',function(){
          hoverable.jq_obj.css({'overflow':'hidden','z-index':hoverable.old_z_index,'border-right':hoverable.old_border});
        });
      }
    }),
    HoverReveal: Class.extend({
      init: function($hover_revealer){
        $revealable = $hover_revealer.data('revealable')
        jq_obj.bind('mouseover',function(){
          $revealable.show();
        });
        jq_obj.bind('mouseout',function(){
          $revealable.hide();
        });

      }
    }),
    HideyButton: Class.extend({
      init: function($hidey_button){
        $hidey_button.hide();
        this.form = $hidey_button.parents('form');
        this.$hidey_button = $hidey_button;
        this.bindInputs();
      },
      bindInputs: function(){
        this.inputs = this.form.find('input,select,textarea');
        var hidey_button = this;
        this.cache_input_values();
        this.inputs.each(function(){
          $(this).bind("propertychange keyup input paste datechange change",function(){
            if(hidey_button.form_changed()){
              hidey_button.$hidey_button.show();
            } else {
              hidey_button.$hidey_button.hide();
            }
          })
        });
      },
      cache_input_values: function(){
        this.inputs.each(function(){
          if($(this).is(":checkbox")){
            $(this).data('oldstate',$(this).is(':checked'));
          } else {
            $(this).data('oldval',$(this).val());
          }
        })
      },
      form_changed: function(){
        var changed = false;
        this.inputs.each(function(){
          if($(this).is(":checkbox")){
            if($(this).data('oldstate') != $(this).is(':checked')){
              changed = true;
              return false;
            }
          }else{
            if($(this).data('oldval') != $(this).val()){
              changed = true;
              return false;
            }
          }
        })
        return changed;
      }
    }),
    Expandable: Class.extend({
      init: function($expandable){
        this.$expandable = $expandable;
        $expandable.data('expandable',this);
        $collapser = $('[data-expand-id="' + $expandable.data('expand-id') + '"][data-collapser]');
        if($collapser.length > 0){
          this.collapser = new hooch.Collapser($collapser,this);
        }
        this.$expander = $('[data-expand-id="' + $expandable.data('expand-id') + '"][data-expander]');
        this.expander = new hooch.Expander(this.$expander,this);
        this.initial_state = $expandable.data('expand-state');
        if(this.initial_state == 'expanded'){
          this.expand();
        } else {
          this.collapse();
        }
      },
      expand: function(){
        if(this.collapser){
          this.expander.hide();
          this.collapser.show();
        }
        this.$expandable.show(10);
      },
      collapse: function(){
        if(this.collapser){
          this.collapser.hide();
          this.expander.show();
        }
        this.$expandable.hide(10);
      },
      toggle: function(){
        this.$expandable.toggle(10);
      }
    }),
    Expander: Class.extend({
      init: function($expander,target){
        this.$expander = $expander;
        if($expander.data('fake-dropdown')){
          target.$expandable.on('click',function(){
            target.toggle();
          })
          target.$expandable.on('mouseleave',function(){
            target.collapse();
          })
        }
        $expander.bind('click',function(){
          if(target.collapser){
            target.expand();
          } else {
            target.toggle();
          }
        })
      },
      hide: function(){
        this.$expander.hide();
      },
      show: function(){
        this.$expander.show();
      }
    }),
    Collapser: Class.extend({
      init: function($collapser,target){
        this.$collapser = $collapser;
        $collapser.bind('click',function(){
          target.collapse();
        })
      },
      hide: function(){
        this.$collapser.hide();
      },
      show: function(){
        this.$collapser.show();
      }
    }),
    DisableForms: Class.extend({
      init: function($disable_container){
        $disable_container.find('input, select').each(function(){
          $(this).prop('disabled',true);
        });
      }
    }),
    Revealer: Class.extend({
      init: function($revealer){
        var revealer = this;
        this.$revealer = $revealer;
        this.children_id = this.$revealer.data('revealer-children-id');
        this.$all_children = $('[data-revealer_id="' + this.children_id + '"]');
        $revealer.bind('change',function(){
          revealer.reveal();
        });
        revealer.reveal();
      },
      reveal: function(){
        var sanitized_value = this.$revealer.val();
        this.$children = [];
        var revealer = this;
        this.$all_children.each(function(){
          var triggers = $(this).data('revealer-triggers');
          if(triggers){
            var revelation_triggers = eval('(' + triggers + ')');
            if($.inArray(sanitized_value,revelation_triggers) > -1){
              revealer.$children.push($(this));
            }
          } else {
            if(sanitized_value == $(this).data('revealer-trigger')){
              revealer.$children.push($(this));
            }
          }
        })
        this.hideChildren();
        this.revealChosenOnes();
      },
      hideChildren: function(){
        this.$all_children.hide();
      },
      revealChosenOnes: function(){
        $.each(this.$children,function(){ $(this).show(); });
      }
    }),
    TabGroup: Class.extend({
      init: function($tab_group){
        this.$tab_group = $tab_group;
        this.getName();
        this.tab_triggers = [];
        this.tab_triggers_by_id = {};
        this.getTabTriggerClass();
        this.createTabs();
        this.getConentParent();
        this.hideAll();
        this.handleDefault();
        hooch.TabGroup.addGroup(this);
      },
      createTabs: function(){
        var tab_group = this;
        this.$tab_group.find("[data-tab-trigger]").each(function(){
          var new_tab = new tab_group.tab_trigger_class($(this),tab_group);
          tab_group.tab_triggers.push(new_tab);
          tab_group.tab_triggers_by_id[new_tab.tab_id] = new_tab;
        })
      },
      getTabByPushState: function(state_value){
        var selected_tab = null;
        $.each(this.tab_triggers,function(index,trigger){
          if(trigger.push_state == state_value){
            selected_tab = trigger;
          }
        })
        return selected_tab;
      },
      getName: function(){
        this.name = this.$tab_group.data('tab-group');
      },
      getConentParent: function(){
        this.$content_parent = this.tab_triggers[0].getParent();
      },
      handleDefault: function(){
        if(this.$tab_group.data('default-tab')){
          this.default_tab = this.tab_triggers_by_id[this.$tab_group.data('default-tab')];
          this.default_tab.toggleTarget('replace');
        }
      },
      hideAll: function(trigger){
        $.each(this.tab_triggers,function(){
          this.hideTarget();
        })
      },
      getTabTriggerClass: function(){
        this.tab_trigger_class = hooch.TabTrigger;
      },
      deactivateTabTriggers: function(){
        $.each(this.tab_triggers,function(){
          this.$tab_trigger.removeClass('active');
        })
      },
      setActiveTab: function(tab_trigger){
        if(this.active_tab){
          var parent_height = this.$content_parent.height();
          this.$content_parent.css({'height': parent_height, 'overflow': 'hidden'});
        }
        this.hideAll();
        this.deactivateTabTriggers();
        this.active_tab = tab_trigger;
        tab_trigger.revealTarget();
      },
      resize: function(){
        this.$content_parent.css({'height': 'auto', 'overflow': 'visible'});
      },
      getActiveTab: function(){
        return this.active_tab;
      }
    }),
    TabTrigger: Class.extend({
      init: function($tab_trigger,tab_group){
        this.$tab_trigger = $tab_trigger;
        this.tab_group = tab_group;
        this.tab_group_name = tab_group.name;
        this.tab_id = $tab_trigger.data('tab-target-id');
        this.getPushState();
        this.getTarget();
        var tab_trigger = this;
        $tab_trigger.on('click', function(e){
          e.preventDefault();
          tab_trigger.toggleTarget();
        })
      },
      getTarget: function(){
        this.$target = $('[data-tab-id="' + this.tab_id + '"]');
      },
      getPushState: function(){
        if(this.$tab_trigger.data('push-state') != null && this.$tab_trigger.data('push-state') != ""){
          this.push_state = this.$tab_trigger.data('push-state')
        }
      },
      toggleTarget: function(state_behavior){
        var was_visible = this.$target.is(':visible');
        if(!was_visible){
          this.tab_group.setActiveTab(this);
          this.resize();
          var change_history = true;
          var history_method = 'pushState'
          if('no history' == state_behavior){
            change_history = false
          } else if('replace' == state_behavior){
            history_method = 'replaceState'
          }
          if (this.push_state && change_history) {
            var current_state = new hooch.IhHistoryState(history.state)
            current_state.addState(this.tab_group_name, this.push_state);
            history[history_method](current_state.state, null, current_state.toUrl());
          }
        }
      },
      hideTarget: function(){
        this.$target.hide();
      },
      revealTarget: function(){
        this.$target.show();
        this.$tab_trigger.addClass('active');
      },
      getParent: function(){
        return this.$target.parent();
      },
      resize: function(){
        this.tab_group.resize();
      }
    }),
    IhHistoryState: Class.extend({
      init: function(state){
        this.state = jQuery.extend(true, {}, state);
      },
      toQueryString: function(){
        return $.param(this.state)
      },
      toUrl: function(){
        return [location.protocol, '//', location.host, location.pathname, '?', this.toQueryString()].join('');
      },
      addState: function(key,value){
        var new_state = {}
        new_state[key] = value
        this.state = $.extend(true, this.state, new_state);
      }
    }),
    GoProxy: Class.extend({
      init: function($proxy){
        this.first_submit = true;
        var go_proxy = this;
        go_proxy.$proxy = $proxy;
        go_proxy.target = go_proxy.getTarget();
        go_proxy.prevent_double_submit = $proxy.data('prevent-double-submit')
        switch($proxy.get(0).nodeName.toLowerCase()){
          case 'input':
            switch($proxy.attr('type')){
              case 'checkbox':
              default:
                $proxy.on('change',function(){
                  go_proxy.doItNow();
                })
              break;
            }
            break;
          case 'select':
            $proxy.on('change',function(){
              go_proxy.doItNow();
            })
          break;
          case 'a':
          default:
            $proxy.on('click',function(e){
              e.preventDefault();
              go_proxy.doItNow();
              return false;
            });
            break;
        }
      },
      doable: function(){
        return(this.first_submit || !this.prevent_double_submit)
      }
    }),
    FieldFiller: Class.extend({
      init: function($field_filler){
        this.$field_filler = $field_filler
        this.value = $field_filler.data('value');
        this.target = $($field_filler.data('target'));
        var field_filler = this
        this.$field_filler.bind('click', function(e){field_filler.fill(e)})
      },
      fill: function(e){
        e.preventDefault();
        this.target.val(this.value);
        return false;
      }
    }),
    Remover: Class.extend({
      init: function($remover){
        $target = $($remover.data('target'));
        $remover.click(function(e){
          $target.remove();
        })
      }
    }),
    Link: Class.extend({
      init: function($link){
        $link.click(function(){
          window.location = $link.attr('href');
        })
      }
    }),
    CheckboxHiddenProxy: Class.extend({
      init: function($checkbox){
        this.checked_value = $checkbox.data('checked-value');
        this.unchecked_value = $checkbox.data('unchecked-value');
        var target_selector = $checkbox.data('target');
        this.target = $(target_selector);
        var checkbox = this;
        $checkbox.click(function(){
          if ($(this).is(':checked')) {
            checkbox.target.val(checkbox.checked_value);
          } else {
            checkbox.target.val(checkbox.unchecked_value);
          }
        })
      }
    }),
    PreventDoubleSubmit: Class.extend({
      init: function($clickable){
        this.$clickable = $clickable;
        var double_click_preventer = this;
        switch($clickable.get(0).nodeName.toLowerCase()){
          case 'form':
            $clickable.submit(function(e){ double_click_preventer.preventItNow(); });
            break;
          case 'input':
            $clickable.click(function() {
              setTimeout(function(){
                $clickable.attr("disabled", "disabled");
              }, 10);
            });
            break;
        }
      },
      preventItNow: function(){
        this.$clickable.submit(function(e){ e.preventDefault(); return false; });
      }
    }),
    PreventDoubleLinkClick: Class.extend({
      init: function($clickable){
        $clickable.click(function(e) {
          if($clickable.data('clicked')) {
            e.preventDefault();
            return false;
          } else {
            $clickable.data('clicked',true);
            return true;
          }
        });
      }
    }),
    ReloadPage: Class.extend({
      init: function(reload_page){
        window.location.href = reload_page;
      }
    })
  };
  hooch.AjaxExpandable = hooch.Expandable.extend({
      expand: function(){
        if(!this.ajax_loaded){
          this.ajax_loaded = true;
          new thin_man.AjaxLinkSubmission(this.$expander);
        }
        this._super();
      }
  });
  hooch.FormFieldRevealer = hooch.Revealer.extend({
    init: function($revealer){
      this.children_id = $revealer.data('revealer-children-id');
      this.$revelation_target = $('[data-revealer-target="' + this.children_id + '"]');
      this._super($revealer);
    },
    hideChildren: function(){
      this._super();
      this.$form = this.$revealer.parents('form:first')
      if(this.$form.length > 0){
        this.$form.after(this.$all_children)
      }
    },
    revealChosenOnes: function(){
      this.$revelation_target.html(this.$children);
      this._super();
    }
  });
  hooch.AjaxTabGroup = hooch.TabGroup.extend({
    getTabTriggerClass: function(){
      this.tab_trigger_class = hooch.AjaxTabTrigger;
    }
  });
  hooch.AjaxTabTrigger = hooch.TabTrigger.extend({
    toggleTarget: function(pop){
      var tab_group = this.tab_group;
      if(!this.ajax_loaded){
        this.ajax_loaded = true;
        this.$tab_trigger.data('ajax-target','[data-tab-id="' + this.tab_id + '"]')
        new thin_man.AjaxLinkSubmission(this.$tab_trigger,{'on_complete': function(){tab_group.resize()}});
        this._super(pop);
      } else {
        this._super(pop);
        tab_group.resize()
      }
    },
    resize: function(){
      // noop
    }
  });
  hooch.ClickProxy = hooch.GoProxy.extend({
    getTarget: function(){
      if(this.$proxy.data('target')){
        return $(this.$proxy.data('target'));
      } else {
        return this.$proxy.siblings('a');
      }
    },
    doItNow: function(){
      if(this.doable()) {
        if(this.target.data('ajax-target')){
          this.target.click();
        }else if(this.target.attr('href')){
          window.location = this.target.attr('href');
        }
        this.first_submit = false;
      }
    }
  });
  hooch.SubmitProxy = hooch.GoProxy.extend({
    getTarget: function(){
      if(this.$proxy.data('target')){
        return $(this.$proxy.data('target'));
      } else {
        return this.$proxy.parents('form:first');
      }
    },
    doItNow: function(){
      if(this.doable()) {
        this.target.submit();
        this.first_submit = false;
      }
    }
  });
  hooch.TabGroup.addGroup = function(group){
    if(!hooch.TabGroup.all_groups){
      hooch.TabGroup.all_groups = [];
    }
    hooch.TabGroup.all_groups.push(group);
  };
  hooch.TabGroup.find = function(name){
    var selected_group = null;
    $.each(hooch.TabGroup.all_groups,function(index,group){
      if(group.name == name){
        selected_group = group;
      }
    });
    return selected_group;
  };
  hooch.loadClasses = function(){
    window.any_time_manager.registerListWithClasses({
      'expand-state' : 'Expandable', 'prevent-double-click' : 'PreventDoubleLinkClick'
    },'hooch');
    window.any_time_manager.registerList(
      ['hover_overflow','hidey_button','submit-proxy','click-proxy','field-filler','revealer',
        'checkbox-hidden-proxy','prevent-double-submit','prevent-double-link-click', 'tab-group',
        'hover-reveal', 'emptier', 'remover'],'hooch');
    window.any_time_manager.load();
  };
  $(document).ready(function(){
    if(typeof window.any_time_manager === "undefined" && typeof window.loading_any_time_manager === "undefined"){
      window.loading_any_time_manager = true;
      $.getScript("https://cdn.rawgit.com/edraut/anytime_manager/9f710d2280e68ea6156551728cb7e2d537a06ee6/anytime_manager.js",function(){
        window.loading_any_time_manager = false
        hooch.loadClasses();
      });
    }else if(typeof window.any_time_manager === "undefined"){
      if(typeof window.any_time_load_functions === 'undefined'){
        window.any_time_load_functions = []
      }
      window.any_time_load_functions.push(hooch.loadClasses)
    }else{
      hooch.loadClasses();
    };
    $(document).on('change','[data-toggler]',function(){
      new hooch.Toggler($(this));
    })
    $('[data-toggler]').each(function(){
      new hooch.Toggler($(this));
    })
    $('[data-disable_forms]').each(function(){
      new hooch.DisableForms($(this));
    })
    $('[data-link]').each(function(){
      new hooch.Link($(this));
    })
    // Initailizes auto complete for select inputs
    $('input,select,textarea').filter(':visible:enabled:first').each(function(){
      if(!$(this).data('date-picker')){
        $(this).focus();
      }
    });
  });
  $(window).bind("popstate", function(e){
    var previous_state = new hooch.IhHistoryState(e.originalEvent.state)
    $.each(previous_state.state, function(key,value){
      var tab_group = hooch.TabGroup.find(key)
      if(tab_group){
        var tab_trigger = tab_group.getTabByPushState(value)
        if(tab_trigger){
          tab_trigger.toggleTarget('no history');
        }
      }
    })
  });
}
if(typeof Class === "undefined"){
  $.getScript('https://rawgit.com/edraut/js_inheritance/a6c1e40986ecb276335b0a0b1792abd01f05ff6c/inheritance.js', function(){
    initHooch();
  });
}else{
  initHooch();
}<file_sep>source "http://rubygems.org"

gem "middleman", ">= 3"
gem "middleman-s3_sync"
gem "unf"
gem "aws-sdk"

#gem "middleman-livereload"

gem 'bitballoon'

gem "rb-fsevent"

gem "tagz"

gem "map"

# KSS related gems.
gem "kss", "~> 0.3.0"
gem "compass-susy-plugin"

gem 'capistrano'
gem 'rake'

# Bourbon.io
gem 'bourbon'
gem 'pygments.rb'
gem "middleman-syntax"

# Parses .netrc
gem 'net-netrc'

gem 'sekrets'

group :development do
  gem 'flowdock'
  gem 'pry'
  gem 'pry-nav'
  gem 'httparty'
end

