piggybak_variants 0.0.17 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
 - data/README.md +5 -13
 - data/app/assets/javascripts/piggybak_variants/piggybak_variants-application.js +1 -0
 - data/app/assets/javascripts/piggybak_variants/piggybak_variants.js +68 -7
 - data/app/models/piggybak_variants/option.rb +1 -6
 - data/app/models/piggybak_variants/option_configuration.rb +0 -3
 - data/app/models/piggybak_variants/option_value.rb +1 -5
 - data/app/models/piggybak_variants/variant.rb +6 -6
 - data/app/views/piggybak_variants/cart/_dropdowns_form.html.erb +0 -2
 - data/app/views/piggybak_variants/cart/_radio_buttons_form.html.erb +1 -3
 - data/db/migrate/20140325195831_upgrade_piggybak_variants_tables.rb +9 -0
 - data/lib/acts_as_sellable_with_variants.rb +0 -2
 - data/lib/piggybak_variants/engine.rb +3 -3
 - data/lib/piggybak_variants/version.rb +1 -1
 - data/lib/piggybak_variants.rb +0 -1
 - metadata +39 -60
 - data/app/assets/javascripts/piggybak_variants/product_show.js +0 -66
 - data/app/assets/stylesheets/piggybak_variants/application.css +0 -13
 - data/lib/associated_bubbling_validator.rb +0 -21
 
    
        checksums.yaml
    ADDED
    
    | 
         @@ -0,0 +1,7 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            ---
         
     | 
| 
      
 2 
     | 
    
         
            +
            SHA1:
         
     | 
| 
      
 3 
     | 
    
         
            +
              metadata.gz: 21f091a2e1ce6be384810b86e9d320f0d6789aca
         
     | 
| 
      
 4 
     | 
    
         
            +
              data.tar.gz: cf94b7a11ed463e3d5199319ce3c91e9bb85eb38
         
     | 
| 
      
 5 
     | 
    
         
            +
            SHA512:
         
     | 
| 
      
 6 
     | 
    
         
            +
              metadata.gz: ef38a0103338568ca28187fd5d585f7059b86cb82a7e2e372caec305c92d313abd2bc7344222b626e1a0b525fae567f9ae098b88d03e0e77c24231bec5fb2626
         
     | 
| 
      
 7 
     | 
    
         
            +
              data.tar.gz: 029fdff18768f7254eff52decfc0546f44206bdb1cd3b0345d82d83b2f3b64e385cf88599a2c58f3d8c488edb125b6ec820865750e068ba06fee412b558e086a
         
     | 
    
        data/README.md
    CHANGED
    
    | 
         @@ -10,26 +10,18 @@ In your Gemfile add `gem "piggybak_variants"` 
     | 
|
| 
       10 
10 
     | 
    
         | 
| 
       11 
11 
     | 
    
         
             
            Run `bundle install`
         
     | 
| 
       12 
12 
     | 
    
         | 
| 
       13 
     | 
    
         
            -
            Run `rake piggybak_variants:install:migrations`
         
     | 
| 
      
 13 
     | 
    
         
            +
            Run `rake piggybak_variants:install:migrations` in your main Rails application.
         
     | 
| 
       14 
14 
     | 
    
         
             
            Migrate the DB `rake db:migrate`
         
     | 
| 
       15 
15 
     | 
    
         | 
| 
      
 16 
     | 
    
         
            +
            Add //= require piggybak_variants/piggybak_variants-application to your application.js
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
       16 
18 
     | 
    
         
             
            Add `acts_as_sellable_with_variants` to any model that should have variants. You may need to add appropriate attr_accessible settings in your model as well, depending on your attribute accessibility settings.
         
     | 
| 
       17 
19 
     | 
    
         | 
| 
       18 
20 
     | 
    
         
             
            In the admin, define option configurations and option values for each option, then create variants for your sellable instances.
         
     | 
| 
       19 
21 
     | 
    
         | 
| 
       20 
     | 
    
         
            -
            Finally, add `<%= variant_cart_form(@instance) %>` to your sellable item's show page to render the cart form.
         
     | 
| 
       21 
     | 
    
         
            -
             
     | 
| 
       22 
     | 
    
         
            -
            OPTION:  `<%= variant_cart_form(@instance, :controls => 'dropdowns') %>` to render dropdowns instead of radio buttons.
         
     | 
| 
       23 
     | 
    
         
            -
             
     | 
| 
       24 
     | 
    
         
            -
            So either add that line, or if you already have it enabled just add `piggybak_variants/piggybak_variants.js` to the array of values.
         
     | 
| 
       25 
     | 
    
         
            -
             
     | 
| 
       26 
     | 
    
         
            -
            TODO
         
     | 
| 
       27 
     | 
    
         
            -
            ========
         
     | 
| 
       28 
     | 
    
         
            -
             
     | 
| 
       29 
     | 
    
         
            -
            * Notes specified in variant.rb
         
     | 
| 
       30 
     | 
    
         
            -
             
     | 
| 
      
 22 
     | 
    
         
            +
            Finally, add `<%= variant_cart_form(@instance) %>` to your sellable item's show page to render the cart form. To use dropdowns instead of radio buttons, call `<%= variant_cart_form(@instance, :controls => 'dropdowns') %>`
         
     | 
| 
       31 
23 
     | 
    
         | 
| 
       32 
24 
     | 
    
         
             
            Copyright
         
     | 
| 
       33 
25 
     | 
    
         
             
            ========
         
     | 
| 
       34 
26 
     | 
    
         | 
| 
       35 
     | 
    
         
            -
            Copyright (c)  
     | 
| 
      
 27 
     | 
    
         
            +
            Copyright (c) 2014 End Point. See LICENSE for further details.
         
     | 
| 
         @@ -0,0 +1 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            //= require piggybak_variants/piggybak_variants
         
     | 
| 
         @@ -1,7 +1,68 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
             
     | 
| 
       2 
     | 
    
         
            -
             
     | 
| 
       3 
     | 
    
         
            -
             
     | 
| 
       4 
     | 
    
         
            -
             
     | 
| 
       5 
     | 
    
         
            -
             
     | 
| 
       6 
     | 
    
         
            -
             
     | 
| 
       7 
     | 
    
         
            -
             
     | 
| 
      
 1 
     | 
    
         
            +
            var piggybak_variants = {
         
     | 
| 
      
 2 
     | 
    
         
            +
            	refreshControls : function(data) {
         
     | 
| 
      
 3 
     | 
    
         
            +
            		if(data.all_selected) { // if all selected
         
     | 
| 
      
 4 
     | 
    
         
            +
            			var selected_key = data.selected.sort().join('_');
         
     | 
| 
      
 5 
     | 
    
         
            +
            			if(variant_map[selected_key]) {
         
     | 
| 
      
 6 
     | 
    
         
            +
            				$('.variant_options form').show();
         
     | 
| 
      
 7 
     | 
    
         
            +
            				$('#sellable_id').val(variant_map[selected_key].id);
         
     | 
| 
      
 8 
     | 
    
         
            +
            				$('#variant_price span').html(variant_map[selected_key].price);
         
     | 
| 
      
 9 
     | 
    
         
            +
            			} else { // if variant not available
         
     | 
| 
      
 10 
     | 
    
         
            +
            				$('.variant_options form').hide();
         
     | 
| 
      
 11 
     | 
    
         
            +
            				$('.unavailable').show();
         
     | 
| 
      
 12 
     | 
    
         
            +
            			}
         
     | 
| 
      
 13 
     | 
    
         
            +
            		} else { // if not all selected
         
     | 
| 
      
 14 
     | 
    
         
            +
            			$('.all_selected').show();
         
     | 
| 
      
 15 
     | 
    
         
            +
            			$('.variant_options form').hide();
         
     | 
| 
      
 16 
     | 
    
         
            +
            		}
         
     | 
| 
      
 17 
     | 
    
         
            +
            	},
         
     | 
| 
      
 18 
     | 
    
         
            +
            	extractRadioButtonValues: function() {
         
     | 
| 
      
 19 
     | 
    
         
            +
            		var all_selected = true;
         
     | 
| 
      
 20 
     | 
    
         
            +
            		var selected = new Array();
         
     | 
| 
      
 21 
     | 
    
         
            +
            		$.each($('.option'), function(i, j) {
         
     | 
| 
      
 22 
     | 
    
         
            +
            			var option_id = $(j).attr('id');
         
     | 
| 
      
 23 
     | 
    
         
            +
            			if($('input[name=' + option_id + ']:checked').length) {
         
     | 
| 
      
 24 
     | 
    
         
            +
            				selected.push($('input[name=' + option_id + ']:checked').val());
         
     | 
| 
      
 25 
     | 
    
         
            +
            			} else {
         
     | 
| 
      
 26 
     | 
    
         
            +
            				all_selected = false;	
         
     | 
| 
      
 27 
     | 
    
         
            +
            			}
         
     | 
| 
      
 28 
     | 
    
         
            +
            		});					
         
     | 
| 
      
 29 
     | 
    
         
            +
            		return { all_selected: all_selected, selected: selected };
         
     | 
| 
      
 30 
     | 
    
         
            +
            	},
         
     | 
| 
      
 31 
     | 
    
         
            +
            	extractDropdownValues: function() {
         
     | 
| 
      
 32 
     | 
    
         
            +
            		var all_selected = true;
         
     | 
| 
      
 33 
     | 
    
         
            +
            		// TODO: Nice to see if easier way to select by value, but select[value=""] doesn't work
         
     | 
| 
      
 34 
     | 
    
         
            +
            		$('.variant_options select').each(function() {
         
     | 
| 
      
 35 
     | 
    
         
            +
            			if ($(this).val() == '') {
         
     | 
| 
      
 36 
     | 
    
         
            +
            				all_selected = false;
         
     | 
| 
      
 37 
     | 
    
         
            +
            			}
         
     | 
| 
      
 38 
     | 
    
         
            +
            		});
         
     | 
| 
      
 39 
     | 
    
         
            +
            		if(!all_selected) {
         
     | 
| 
      
 40 
     | 
    
         
            +
            			return { all_selected: false, selected: '' };
         
     | 
| 
      
 41 
     | 
    
         
            +
            		}
         
     | 
| 
      
 42 
     | 
    
         
            +
            		
         
     | 
| 
      
 43 
     | 
    
         
            +
            		var selected = new Array();
         
     | 
| 
      
 44 
     | 
    
         
            +
            		$.each($('.variant_options .option select'), function(i, j) {
         
     | 
| 
      
 45 
     | 
    
         
            +
            			selected.push($(this).val());
         
     | 
| 
      
 46 
     | 
    
         
            +
            		});
         
     | 
| 
      
 47 
     | 
    
         
            +
            		return { all_selected: true, selected: selected};
         
     | 
| 
      
 48 
     | 
    
         
            +
            	},
         
     | 
| 
      
 49 
     | 
    
         
            +
            	toggleVariantForm: function() {
         
     | 
| 
      
 50 
     | 
    
         
            +
            		$('.unavailable, .all_selected').hide();
         
     | 
| 
      
 51 
     | 
    
         
            +
            		var data;
         
     | 
| 
      
 52 
     | 
    
         
            +
            		if ($('.variant_options input[type=radio]').length > 0){
         
     | 
| 
      
 53 
     | 
    
         
            +
            			data = piggybak_variants.extractRadioButtonValues();
         
     | 
| 
      
 54 
     | 
    
         
            +
            		} else { 
         
     | 
| 
      
 55 
     | 
    
         
            +
            			data = piggybak_variants.extractDropdownValues();
         
     | 
| 
      
 56 
     | 
    
         
            +
            		};
         
     | 
| 
      
 57 
     | 
    
         
            +
            		piggybak_variants.refreshControls(data);
         
     | 
| 
      
 58 
     | 
    
         
            +
            	}
         
     | 
| 
      
 59 
     | 
    
         
            +
            }
         
     | 
| 
      
 60 
     | 
    
         
            +
             
     | 
| 
      
 61 
     | 
    
         
            +
            $(function() {
         
     | 
| 
      
 62 
     | 
    
         
            +
            	$('.variant_options input[type=radio]').click(function() { piggybak_variants.toggleVariantForm(); });
         
     | 
| 
      
 63 
     | 
    
         
            +
            	$('.variant_options select').change(function() { piggybak_variants.toggleVariantForm(); });
         
     | 
| 
      
 64 
     | 
    
         
            +
            	if($('.variant_options').size() > 0) {
         
     | 
| 
      
 65 
     | 
    
         
            +
            		piggybak_variants.toggleVariantForm();
         
     | 
| 
      
 66 
     | 
    
         
            +
            	}
         
     | 
| 
      
 67 
     | 
    
         
            +
            });
         
     | 
| 
      
 68 
     | 
    
         
            +
             
     | 
| 
         @@ -1,17 +1,12 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            module PiggybakVariants
         
     | 
| 
       2 
2 
     | 
    
         
             
              class Option < ActiveRecord::Base
         
     | 
| 
       3 
     | 
    
         
            -
                 
     | 
| 
       4 
     | 
    
         
            -
             
     | 
| 
       5 
     | 
    
         
            -
                attr_accessible :name, :position
         
     | 
| 
       6 
     | 
    
         
            -
                has_many :option_values, :dependent => :destroy
         
     | 
| 
      
 3 
     | 
    
         
            +
                has_many :option_values, :dependent => :destroy, order: 'position ASC'
         
     | 
| 
       7 
4 
     | 
    
         
             
                has_many :option_configurations, :dependent => :destroy
         
     | 
| 
       8 
5 
     | 
    
         | 
| 
       9 
6 
     | 
    
         
             
                default_scope :order => "position ASC"
         
     | 
| 
       10 
7 
     | 
    
         | 
| 
       11 
8 
     | 
    
         
             
                accepts_nested_attributes_for :option_values, :allow_destroy => true
         
     | 
| 
       12 
     | 
    
         
            -
                attr_accessible :option_values_attributes, :allow_destroy => true
         
     | 
| 
       13 
9 
     | 
    
         | 
| 
       14 
10 
     | 
    
         
             
                accepts_nested_attributes_for :option_configurations, :allow_destroy => true
         
     | 
| 
       15 
     | 
    
         
            -
                attr_accessible :option_configurations_attributes, :allow_destroy => true
         
     | 
| 
       16 
11 
     | 
    
         
             
              end
         
     | 
| 
       17 
12 
     | 
    
         
             
            end
         
     | 
| 
         @@ -1,13 +1,9 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            module PiggybakVariants
         
     | 
| 
       2 
2 
     | 
    
         
             
              class OptionValue < ActiveRecord::Base
         
     | 
| 
       3 
     | 
    
         
            -
                self.table_name = "option_values"
         
     | 
| 
       4 
     | 
    
         
            -
             
     | 
| 
       5 
     | 
    
         
            -
                attr_accessible :name, :position
         
     | 
| 
       6 
3 
     | 
    
         
             
                has_and_belongs_to_many :variants
         
     | 
| 
       7 
4 
     | 
    
         
             
                belongs_to :option, :inverse_of => :option_values
         
     | 
| 
       8 
5 
     | 
    
         | 
| 
       9 
     | 
    
         
            -
                scope : 
     | 
| 
       10 
     | 
    
         
            -
                scope :hash_ordered, :include => :option, :order => "options.position ASC, option_values.position ASC"
         
     | 
| 
      
 6 
     | 
    
         
            +
                scope :hash_ordered, -> { includes(:option).order("piggybak_variants_options.position ASC, piggybak_variants_option_values.position ASC") }
         
     | 
| 
       11 
7 
     | 
    
         | 
| 
       12 
8 
     | 
    
         
             
                def admin_label
         
     | 
| 
       13 
9 
     | 
    
         
             
                  "#{self.option.name}: #{self.name}"
         
     | 
| 
         @@ -1,22 +1,22 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            module PiggybakVariants
         
     | 
| 
       2 
2 
     | 
    
         
             
              class Variant < ActiveRecord::Base
         
     | 
| 
       3 
     | 
    
         
            -
                self.table_name = "variants"
         
     | 
| 
       4 
     | 
    
         
            -
             
     | 
| 
       5 
3 
     | 
    
         
             
                acts_as_sellable
         
     | 
| 
       6 
4 
     | 
    
         
             
                belongs_to :item, :polymorphic => true
         
     | 
| 
       7 
5 
     | 
    
         
             
                has_and_belongs_to_many :option_values
         
     | 
| 
       8 
6 
     | 
    
         | 
| 
       9 
     | 
    
         
            -
                 
     | 
| 
       10 
     | 
    
         
            -
             
     | 
| 
       11 
     | 
    
         
            -
                scope :available, joins(:piggybak_sellable).where(["sellables.active = ? AND (sellables.quantity > 0 OR sellables.unlimited_inventory = ?)",true,true]) 
         
     | 
| 
      
 7 
     | 
    
         
            +
                scope :available, joins(:piggybak_sellable).where(["piggybak_sellables.active = ? AND (piggybak_sellables.quantity > 0 OR piggybak_sellables.unlimited_inventory = ?)",true,true]) 
         
     | 
| 
       12 
8 
     | 
    
         
             
                validate :option_value_validation
         
     | 
| 
      
 9 
     | 
    
         
            +
                validate :require_item
         
     | 
| 
       13 
10 
     | 
    
         | 
| 
       14 
11 
     | 
    
         
             
                def admin_label
         
     | 
| 
       15 
12 
     | 
    
         
             
                  "#{self.piggybak_sellable.sku}: #{self.piggybak_sellable.price}"
         
     | 
| 
       16 
13 
     | 
    
         
             
                end
         
     | 
| 
       17 
14 
     | 
    
         | 
| 
      
 15 
     | 
    
         
            +
                def require_item
         
     | 
| 
      
 16 
     | 
    
         
            +
                  self.errors.add(:piggybak_sellable, "You must have foo") if self.piggybak_sellable.nil?
         
     | 
| 
      
 17 
     | 
    
         
            +
                end
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
       18 
19 
     | 
    
         
             
                def option_value_validation
         
     | 
| 
       19 
     | 
    
         
            -
                  # TODO: Figure out why this validation is only being called sometime
         
     | 
| 
       20 
20 
     | 
    
         
             
                  # TODO: Add verification to prevent duplicate option value sets
         
     | 
| 
       21 
21 
     | 
    
         | 
| 
       22 
22 
     | 
    
         
             
                  klass = self.item.class
         
     | 
| 
         @@ -1,6 +1,4 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            <% if object.reflections.keys.include?(:variants) -%>
         
     | 
| 
       2 
     | 
    
         
            -
            	<%= javascript_include_tag "piggybak_variants/piggybak_variants" %>
         
     | 
| 
       3 
     | 
    
         
            -
             
     | 
| 
       4 
2 
     | 
    
         
             
            	<script type="text/javascript">
         
     | 
| 
       5 
3 
     | 
    
         
             
            		var variant_map = <%= raw variant_map(object) %>;
         
     | 
| 
       6 
4 
     | 
    
         
             
            	</script>
         
     | 
| 
         @@ -9,7 +7,7 @@ 
     | 
|
| 
       9 
7 
     | 
    
         
             
            		<% options_for_klass(object.class).each do |option| -%>
         
     | 
| 
       10 
8 
     | 
    
         
             
            		<div class="option" id="option_<%= option.id %>">
         
     | 
| 
       11 
9 
     | 
    
         
             
            		<h4><%= option.name %></h4>
         
     | 
| 
       12 
     | 
    
         
            -
            		<% option.option_values. 
     | 
| 
      
 10 
     | 
    
         
            +
            		<% option.option_values.each do |option_value| -%>
         
     | 
| 
       13 
11 
     | 
    
         
             
            			<input type="radio" name="option_<%= option.id %>" value="<%= option_value.id %>" />
         
     | 
| 
       14 
12 
     | 
    
         
             
            			<%= option_value.name %><br />
         
     | 
| 
       15 
13 
     | 
    
         
             
            		<% end -%>
         
     | 
| 
         @@ -0,0 +1,9 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            class UpgradePiggybakVariantsTables < ActiveRecord::Migration
         
     | 
| 
      
 2 
     | 
    
         
            +
              def change
         
     | 
| 
      
 3 
     | 
    
         
            +
                rename_table :variants, :piggybak_variants_variants
         
     | 
| 
      
 4 
     | 
    
         
            +
                rename_table :options, :piggybak_variants_options
         
     | 
| 
      
 5 
     | 
    
         
            +
                rename_table :option_values, :piggybak_variants_option_values
         
     | 
| 
      
 6 
     | 
    
         
            +
                rename_table :option_values_variants, :piggybak_variants_option_values_variants
         
     | 
| 
      
 7 
     | 
    
         
            +
                rename_table :option_configurations, :piggybak_variants_option_configurations
         
     | 
| 
      
 8 
     | 
    
         
            +
              end
         
     | 
| 
      
 9 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -7,8 +7,6 @@ module Piggybak 
     | 
|
| 
       7 
7 
     | 
    
         
             
                    has_many :variants, :dependent => :destroy, :class_name => "::PiggybakVariants::Variant", :as => :item
         
     | 
| 
       8 
8 
     | 
    
         | 
| 
       9 
9 
     | 
    
         
             
                    accepts_nested_attributes_for :variants, :allow_destroy => true
         
     | 
| 
       10 
     | 
    
         
            -
                    attr_accessible :variants_attributes #, :allow_destroy => true
         
     | 
| 
       11 
     | 
    
         
            -
                    validates_associated_bubbling :variants
         
     | 
| 
       12 
10 
     | 
    
         | 
| 
       13 
11 
     | 
    
         
             
                    ::PiggybakVariants::OptionConfiguration::VARIANT_CLASSES << self.to_s
         
     | 
| 
       14 
12 
     | 
    
         
             
                  end      
         
     | 
| 
         @@ -19,10 +19,10 @@ module PiggybakVariants 
     | 
|
| 
       19 
19 
     | 
    
         
             
                  end
         
     | 
| 
       20 
20 
     | 
    
         
             
                end
         
     | 
| 
       21 
21 
     | 
    
         | 
| 
       22 
     | 
    
         
            -
                initializer "piggybak_variants. 
     | 
| 
       23 
     | 
    
         
            -
                  app.config.assets.precompile += ['piggybak_variants/piggybak_variants.js']
         
     | 
| 
      
 22 
     | 
    
         
            +
                initializer "piggybak_variants.assets.precompile" do |app|
         
     | 
| 
      
 23 
     | 
    
         
            +
                  app.config.assets.precompile += ['piggybak_variants/piggybak_variants-application.js']
         
     | 
| 
       24 
24 
     | 
    
         
             
                end
         
     | 
| 
       25 
     | 
    
         
            -
             
     | 
| 
      
 25 
     | 
    
         
            +
                
         
     | 
| 
       26 
26 
     | 
    
         
             
                # TODO: Figure out of we can have this only in to_prepare or here 
         
     | 
| 
       27 
27 
     | 
    
         
             
                initializer "piggybak_variants.add_helper" do |app| 
         
     | 
| 
       28 
28 
     | 
    
         
             
                  ApplicationController.class_eval do
         
     | 
    
        data/lib/piggybak_variants.rb
    CHANGED
    
    
    
        metadata
    CHANGED
    
    | 
         @@ -1,44 +1,27 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            --- !ruby/object:Gem::Specification
         
     | 
| 
       2 
2 
     | 
    
         
             
            name: piggybak_variants
         
     | 
| 
       3 
3 
     | 
    
         
             
            version: !ruby/object:Gem::Version
         
     | 
| 
       4 
     | 
    
         
            -
              version: 0.0 
     | 
| 
       5 
     | 
    
         
            -
              prerelease: 
         
     | 
| 
      
 4 
     | 
    
         
            +
              version: 0.1.0
         
     | 
| 
       6 
5 
     | 
    
         
             
            platform: ruby
         
     | 
| 
       7 
6 
     | 
    
         
             
            authors:
         
     | 
| 
       8 
7 
     | 
    
         
             
            - Tim Case, Steph Skardal
         
     | 
| 
       9 
8 
     | 
    
         
             
            autorequire: 
         
     | 
| 
       10 
9 
     | 
    
         
             
            bindir: bin
         
     | 
| 
       11 
10 
     | 
    
         
             
            cert_chain: []
         
     | 
| 
       12 
     | 
    
         
            -
            date:  
     | 
| 
       13 
     | 
    
         
            -
            dependencies:
         
     | 
| 
       14 
     | 
    
         
            -
             
     | 
| 
       15 
     | 
    
         
            -
              name: rails
         
     | 
| 
       16 
     | 
    
         
            -
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
       17 
     | 
    
         
            -
                none: false
         
     | 
| 
       18 
     | 
    
         
            -
                requirements:
         
     | 
| 
       19 
     | 
    
         
            -
                - - ~>
         
     | 
| 
       20 
     | 
    
         
            -
                  - !ruby/object:Gem::Version
         
     | 
| 
       21 
     | 
    
         
            -
                    version: 3.2.3
         
     | 
| 
       22 
     | 
    
         
            -
              type: :runtime
         
     | 
| 
       23 
     | 
    
         
            -
              prerelease: false
         
     | 
| 
       24 
     | 
    
         
            -
              version_requirements: !ruby/object:Gem::Requirement
         
     | 
| 
       25 
     | 
    
         
            -
                none: false
         
     | 
| 
       26 
     | 
    
         
            -
                requirements:
         
     | 
| 
       27 
     | 
    
         
            -
                - - ~>
         
     | 
| 
       28 
     | 
    
         
            -
                  - !ruby/object:Gem::Version
         
     | 
| 
       29 
     | 
    
         
            -
                    version: 3.2.3
         
     | 
| 
       30 
     | 
    
         
            -
            description: ! 'Adds variant support to Piggybak. Variants are options for a product
         
     | 
| 
       31 
     | 
    
         
            -
              (i.e. small, medium, large, red, blue, green)    variants can be configured to display
         
     | 
| 
       32 
     | 
    
         
            -
              as either radio btns or selects '
         
     | 
| 
      
 11 
     | 
    
         
            +
            date: 2014-03-27 00:00:00.000000000 Z
         
     | 
| 
      
 12 
     | 
    
         
            +
            dependencies: []
         
     | 
| 
      
 13 
     | 
    
         
            +
            description: Advanced variant support for Piggybak.
         
     | 
| 
       33 
14 
     | 
    
         
             
            email:
         
     | 
| 
       34 
15 
     | 
    
         
             
            - piggybak@endpoint.com
         
     | 
| 
       35 
16 
     | 
    
         
             
            executables: []
         
     | 
| 
       36 
17 
     | 
    
         
             
            extensions: []
         
     | 
| 
       37 
18 
     | 
    
         
             
            extra_rdoc_files: []
         
     | 
| 
       38 
19 
     | 
    
         
             
            files:
         
     | 
| 
      
 20 
     | 
    
         
            +
            - MIT-LICENSE
         
     | 
| 
      
 21 
     | 
    
         
            +
            - README.md
         
     | 
| 
      
 22 
     | 
    
         
            +
            - Rakefile
         
     | 
| 
      
 23 
     | 
    
         
            +
            - app/assets/javascripts/piggybak_variants/piggybak_variants-application.js
         
     | 
| 
       39 
24 
     | 
    
         
             
            - app/assets/javascripts/piggybak_variants/piggybak_variants.js
         
     | 
| 
       40 
     | 
    
         
            -
            - app/assets/javascripts/piggybak_variants/product_show.js
         
     | 
| 
       41 
     | 
    
         
            -
            - app/assets/stylesheets/piggybak_variants/application.css
         
     | 
| 
       42 
25 
     | 
    
         
             
            - app/controllers/piggybak_variants/application_controller.rb
         
     | 
| 
       43 
26 
     | 
    
         
             
            - app/helpers/piggybak_variants_helper.rb
         
     | 
| 
       44 
27 
     | 
    
         
             
            - app/models/piggybak_variants/option.rb
         
     | 
| 
         @@ -54,19 +37,19 @@ files: 
     | 
|
| 
       54 
37 
     | 
    
         
             
            - db/migrate/20121016153016_create_option_values.rb
         
     | 
| 
       55 
38 
     | 
    
         
             
            - db/migrate/20121016161156_create_option_values_variants.rb
         
     | 
| 
       56 
39 
     | 
    
         
             
            - db/migrate/20121022205428_create_option_configurations.rb
         
     | 
| 
      
 40 
     | 
    
         
            +
            - db/migrate/20140325195831_upgrade_piggybak_variants_tables.rb
         
     | 
| 
       57 
41 
     | 
    
         
             
            - lib/acts_as_sellable_with_variants.rb
         
     | 
| 
       58 
     | 
    
         
            -
            - lib/ 
     | 
| 
      
 42 
     | 
    
         
            +
            - lib/piggybak_variants.rb
         
     | 
| 
       59 
43 
     | 
    
         
             
            - lib/piggybak_variants/engine.rb
         
     | 
| 
       60 
44 
     | 
    
         
             
            - lib/piggybak_variants/version.rb
         
     | 
| 
       61 
     | 
    
         
            -
            -  
     | 
| 
       62 
     | 
    
         
            -
            -  
     | 
| 
       63 
     | 
    
         
            -
            - Rakefile
         
     | 
| 
       64 
     | 
    
         
            -
            - README.md
         
     | 
| 
      
 45 
     | 
    
         
            +
            - test/dummy/README.rdoc
         
     | 
| 
      
 46 
     | 
    
         
            +
            - test/dummy/Rakefile
         
     | 
| 
       65 
47 
     | 
    
         
             
            - test/dummy/app/assets/javascripts/application.js
         
     | 
| 
       66 
48 
     | 
    
         
             
            - test/dummy/app/assets/stylesheets/application.css
         
     | 
| 
       67 
49 
     | 
    
         
             
            - test/dummy/app/controllers/application_controller.rb
         
     | 
| 
       68 
50 
     | 
    
         
             
            - test/dummy/app/helpers/application_helper.rb
         
     | 
| 
       69 
51 
     | 
    
         
             
            - test/dummy/app/views/layouts/application.html.erb
         
     | 
| 
      
 52 
     | 
    
         
            +
            - test/dummy/config.ru
         
     | 
| 
       70 
53 
     | 
    
         
             
            - test/dummy/config/application.rb
         
     | 
| 
       71 
54 
     | 
    
         
             
            - test/dummy/config/boot.rb
         
     | 
| 
       72 
55 
     | 
    
         
             
            - test/dummy/config/database.yml
         
     | 
| 
         @@ -82,70 +65,66 @@ files: 
     | 
|
| 
       82 
65 
     | 
    
         
             
            - test/dummy/config/initializers/wrap_parameters.rb
         
     | 
| 
       83 
66 
     | 
    
         
             
            - test/dummy/config/locales/en.yml
         
     | 
| 
       84 
67 
     | 
    
         
             
            - test/dummy/config/routes.rb
         
     | 
| 
       85 
     | 
    
         
            -
            - test/dummy/config.ru
         
     | 
| 
       86 
68 
     | 
    
         
             
            - test/dummy/public/404.html
         
     | 
| 
       87 
69 
     | 
    
         
             
            - test/dummy/public/422.html
         
     | 
| 
       88 
70 
     | 
    
         
             
            - test/dummy/public/500.html
         
     | 
| 
       89 
71 
     | 
    
         
             
            - test/dummy/public/favicon.ico
         
     | 
| 
       90 
     | 
    
         
            -
            - test/dummy/Rakefile
         
     | 
| 
       91 
     | 
    
         
            -
            - test/dummy/README.rdoc
         
     | 
| 
       92 
72 
     | 
    
         
             
            - test/dummy/script/rails
         
     | 
| 
       93 
73 
     | 
    
         
             
            - test/integration/navigation_test.rb
         
     | 
| 
       94 
74 
     | 
    
         
             
            - test/piggybak_variants_test.rb
         
     | 
| 
       95 
75 
     | 
    
         
             
            - test/test_helper.rb
         
     | 
| 
       96 
76 
     | 
    
         
             
            homepage: http://www.piggybak.org
         
     | 
| 
       97 
77 
     | 
    
         
             
            licenses: []
         
     | 
| 
      
 78 
     | 
    
         
            +
            metadata: {}
         
     | 
| 
       98 
79 
     | 
    
         
             
            post_install_message: 
         
     | 
| 
       99 
80 
     | 
    
         
             
            rdoc_options: []
         
     | 
| 
       100 
81 
     | 
    
         
             
            require_paths:
         
     | 
| 
       101 
82 
     | 
    
         
             
            - lib
         
     | 
| 
       102 
83 
     | 
    
         
             
            required_ruby_version: !ruby/object:Gem::Requirement
         
     | 
| 
       103 
     | 
    
         
            -
              none: false
         
     | 
| 
       104 
84 
     | 
    
         
             
              requirements:
         
     | 
| 
       105 
     | 
    
         
            -
              - -  
     | 
| 
      
 85 
     | 
    
         
            +
              - - ">="
         
     | 
| 
       106 
86 
     | 
    
         
             
                - !ruby/object:Gem::Version
         
     | 
| 
       107 
87 
     | 
    
         
             
                  version: '0'
         
     | 
| 
       108 
88 
     | 
    
         
             
            required_rubygems_version: !ruby/object:Gem::Requirement
         
     | 
| 
       109 
     | 
    
         
            -
              none: false
         
     | 
| 
       110 
89 
     | 
    
         
             
              requirements:
         
     | 
| 
       111 
     | 
    
         
            -
              - -  
     | 
| 
      
 90 
     | 
    
         
            +
              - - ">="
         
     | 
| 
       112 
91 
     | 
    
         
             
                - !ruby/object:Gem::Version
         
     | 
| 
       113 
92 
     | 
    
         
             
                  version: '0'
         
     | 
| 
       114 
93 
     | 
    
         
             
            requirements: []
         
     | 
| 
       115 
94 
     | 
    
         
             
            rubyforge_project: 
         
     | 
| 
       116 
     | 
    
         
            -
            rubygems_version:  
     | 
| 
      
 95 
     | 
    
         
            +
            rubygems_version: 2.2.2
         
     | 
| 
       117 
96 
     | 
    
         
             
            signing_key: 
         
     | 
| 
       118 
     | 
    
         
            -
            specification_version:  
     | 
| 
      
 97 
     | 
    
         
            +
            specification_version: 4
         
     | 
| 
       119 
98 
     | 
    
         
             
            summary: Advanced variant support for Piggybak.
         
     | 
| 
       120 
99 
     | 
    
         
             
            test_files:
         
     | 
| 
       121 
     | 
    
         
            -
            - test/ 
     | 
| 
       122 
     | 
    
         
            -
            - test/ 
     | 
| 
      
 100 
     | 
    
         
            +
            - test/integration/navigation_test.rb
         
     | 
| 
      
 101 
     | 
    
         
            +
            - test/piggybak_variants_test.rb
         
     | 
| 
      
 102 
     | 
    
         
            +
            - test/test_helper.rb
         
     | 
| 
      
 103 
     | 
    
         
            +
            - test/dummy/script/rails
         
     | 
| 
      
 104 
     | 
    
         
            +
            - test/dummy/Rakefile
         
     | 
| 
      
 105 
     | 
    
         
            +
            - test/dummy/README.rdoc
         
     | 
| 
       123 
106 
     | 
    
         
             
            - test/dummy/app/controllers/application_controller.rb
         
     | 
| 
      
 107 
     | 
    
         
            +
            - test/dummy/app/assets/stylesheets/application.css
         
     | 
| 
      
 108 
     | 
    
         
            +
            - test/dummy/app/assets/javascripts/application.js
         
     | 
| 
       124 
109 
     | 
    
         
             
            - test/dummy/app/helpers/application_helper.rb
         
     | 
| 
       125 
110 
     | 
    
         
             
            - test/dummy/app/views/layouts/application.html.erb
         
     | 
| 
       126 
     | 
    
         
            -
            - test/dummy/config/ 
     | 
| 
       127 
     | 
    
         
            -
            - test/dummy/config/boot.rb
         
     | 
| 
       128 
     | 
    
         
            -
            - test/dummy/config/database.yml
         
     | 
| 
      
 111 
     | 
    
         
            +
            - test/dummy/config/locales/en.yml
         
     | 
| 
       129 
112 
     | 
    
         
             
            - test/dummy/config/environment.rb
         
     | 
| 
       130 
     | 
    
         
            -
            - test/dummy/config/ 
     | 
| 
      
 113 
     | 
    
         
            +
            - test/dummy/config/routes.rb
         
     | 
| 
       131 
114 
     | 
    
         
             
            - test/dummy/config/environments/production.rb
         
     | 
| 
       132 
115 
     | 
    
         
             
            - test/dummy/config/environments/test.rb
         
     | 
| 
       133 
     | 
    
         
            -
            - test/dummy/config/ 
     | 
| 
       134 
     | 
    
         
            -
            - test/dummy/config/initializers/ 
     | 
| 
       135 
     | 
    
         
            -
            - test/dummy/config/initializers/mime_types.rb
         
     | 
| 
      
 116 
     | 
    
         
            +
            - test/dummy/config/environments/development.rb
         
     | 
| 
      
 117 
     | 
    
         
            +
            - test/dummy/config/initializers/wrap_parameters.rb
         
     | 
| 
       136 
118 
     | 
    
         
             
            - test/dummy/config/initializers/secret_token.rb
         
     | 
| 
      
 119 
     | 
    
         
            +
            - test/dummy/config/initializers/mime_types.rb
         
     | 
| 
       137 
120 
     | 
    
         
             
            - test/dummy/config/initializers/session_store.rb
         
     | 
| 
       138 
     | 
    
         
            -
            - test/dummy/config/initializers/ 
     | 
| 
       139 
     | 
    
         
            -
            - test/dummy/config/ 
     | 
| 
       140 
     | 
    
         
            -
            - test/dummy/config/ 
     | 
| 
       141 
     | 
    
         
            -
            - test/dummy/config. 
     | 
| 
       142 
     | 
    
         
            -
            - test/dummy/ 
     | 
| 
       143 
     | 
    
         
            -
            - test/dummy/public/422.html
         
     | 
| 
      
 121 
     | 
    
         
            +
            - test/dummy/config/initializers/backtrace_silencers.rb
         
     | 
| 
      
 122 
     | 
    
         
            +
            - test/dummy/config/initializers/inflections.rb
         
     | 
| 
      
 123 
     | 
    
         
            +
            - test/dummy/config/boot.rb
         
     | 
| 
      
 124 
     | 
    
         
            +
            - test/dummy/config/application.rb
         
     | 
| 
      
 125 
     | 
    
         
            +
            - test/dummy/config/database.yml
         
     | 
| 
       144 
126 
     | 
    
         
             
            - test/dummy/public/500.html
         
     | 
| 
      
 127 
     | 
    
         
            +
            - test/dummy/public/422.html
         
     | 
| 
       145 
128 
     | 
    
         
             
            - test/dummy/public/favicon.ico
         
     | 
| 
       146 
     | 
    
         
            -
            - test/dummy/ 
     | 
| 
       147 
     | 
    
         
            -
            - test/dummy/ 
     | 
| 
       148 
     | 
    
         
            -
            - test/dummy/script/rails
         
     | 
| 
       149 
     | 
    
         
            -
            - test/integration/navigation_test.rb
         
     | 
| 
       150 
     | 
    
         
            -
            - test/piggybak_variants_test.rb
         
     | 
| 
       151 
     | 
    
         
            -
            - test/test_helper.rb
         
     | 
| 
      
 129 
     | 
    
         
            +
            - test/dummy/public/404.html
         
     | 
| 
      
 130 
     | 
    
         
            +
            - test/dummy/config.ru
         
     | 
| 
         @@ -1,66 +0,0 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            var piggybak_variants = {
         
     | 
| 
       2 
     | 
    
         
            -
            	refreshControls : function(data) {
         
     | 
| 
       3 
     | 
    
         
            -
            		if(data.all_selected) { // if all selected
         
     | 
| 
       4 
     | 
    
         
            -
            			var selected_key = data.selected.sort().join('_');
         
     | 
| 
       5 
     | 
    
         
            -
            			if(variant_map[selected_key]) {
         
     | 
| 
       6 
     | 
    
         
            -
            				$('.variant_options form').show();
         
     | 
| 
       7 
     | 
    
         
            -
            				$('#sellable_id').val(variant_map[selected_key].id);
         
     | 
| 
       8 
     | 
    
         
            -
            				$('#variant_price span').html(variant_map[selected_key].price);
         
     | 
| 
       9 
     | 
    
         
            -
            			} else { // if variant not available
         
     | 
| 
       10 
     | 
    
         
            -
            				$('.variant_options form').hide();
         
     | 
| 
       11 
     | 
    
         
            -
            				$('.unavailable').show();
         
     | 
| 
       12 
     | 
    
         
            -
            			}
         
     | 
| 
       13 
     | 
    
         
            -
            		} else { // if not all selected
         
     | 
| 
       14 
     | 
    
         
            -
            			$('.all_selected').show();
         
     | 
| 
       15 
     | 
    
         
            -
            			$('.variant_options form').hide();
         
     | 
| 
       16 
     | 
    
         
            -
            		}
         
     | 
| 
       17 
     | 
    
         
            -
            	},
         
     | 
| 
       18 
     | 
    
         
            -
            	extractRadioButtonValues: function() {
         
     | 
| 
       19 
     | 
    
         
            -
            		var all_selected = true;
         
     | 
| 
       20 
     | 
    
         
            -
            		var selected = new Array();
         
     | 
| 
       21 
     | 
    
         
            -
            		$.each($('.option'), function(i, j) {
         
     | 
| 
       22 
     | 
    
         
            -
            			var option_id = $(j).attr('id');
         
     | 
| 
       23 
     | 
    
         
            -
            			if($('input[name=' + option_id + ']:checked').length) {
         
     | 
| 
       24 
     | 
    
         
            -
            				selected.push($('input[name=' + option_id + ']:checked').val());
         
     | 
| 
       25 
     | 
    
         
            -
            			} else {
         
     | 
| 
       26 
     | 
    
         
            -
            				all_selected = false;	
         
     | 
| 
       27 
     | 
    
         
            -
            			}
         
     | 
| 
       28 
     | 
    
         
            -
            		});					
         
     | 
| 
       29 
     | 
    
         
            -
            		return { all_selected: all_selected, selected: selected };
         
     | 
| 
       30 
     | 
    
         
            -
            	},
         
     | 
| 
       31 
     | 
    
         
            -
            	extractDropdownValues: function() {
         
     | 
| 
       32 
     | 
    
         
            -
            		var all_selected = true;
         
     | 
| 
       33 
     | 
    
         
            -
            		// TODO: Nice to see if easier way to select by value, but select[value=""] doesn't work
         
     | 
| 
       34 
     | 
    
         
            -
            		$('.variant_options select').each(function() {
         
     | 
| 
       35 
     | 
    
         
            -
            			if ($(this).val() == '') {
         
     | 
| 
       36 
     | 
    
         
            -
            				all_selected = false;
         
     | 
| 
       37 
     | 
    
         
            -
            			}
         
     | 
| 
       38 
     | 
    
         
            -
            		});
         
     | 
| 
       39 
     | 
    
         
            -
            		if(!all_selected) {
         
     | 
| 
       40 
     | 
    
         
            -
            			return { all_selected: false, selected: '' };
         
     | 
| 
       41 
     | 
    
         
            -
            		}
         
     | 
| 
       42 
     | 
    
         
            -
            		
         
     | 
| 
       43 
     | 
    
         
            -
            		var selected = new Array();
         
     | 
| 
       44 
     | 
    
         
            -
            		$.each($('.variant_options .option select'), function(i, j) {
         
     | 
| 
       45 
     | 
    
         
            -
            			selected.push($(this).val());
         
     | 
| 
       46 
     | 
    
         
            -
            		});
         
     | 
| 
       47 
     | 
    
         
            -
            		return { all_selected: true, selected: selected};
         
     | 
| 
       48 
     | 
    
         
            -
            	},
         
     | 
| 
       49 
     | 
    
         
            -
            	toggleVariantForm : function() {
         
     | 
| 
       50 
     | 
    
         
            -
            		$('.unavailable, .all_selected').hide();
         
     | 
| 
       51 
     | 
    
         
            -
            		var data;
         
     | 
| 
       52 
     | 
    
         
            -
            		if ($('.variant_options input[type=radio]').length > 0){
         
     | 
| 
       53 
     | 
    
         
            -
            			data = piggybak_variants.extractRadioButtonValues();
         
     | 
| 
       54 
     | 
    
         
            -
            		} else { 
         
     | 
| 
       55 
     | 
    
         
            -
            			data = piggybak_variants.extractDropdownValues();
         
     | 
| 
       56 
     | 
    
         
            -
            		};
         
     | 
| 
       57 
     | 
    
         
            -
            		piggybak_variants.refreshControls(data);
         
     | 
| 
       58 
     | 
    
         
            -
            	}
         
     | 
| 
       59 
     | 
    
         
            -
            }
         
     | 
| 
       60 
     | 
    
         
            -
             
     | 
| 
       61 
     | 
    
         
            -
            $(function() {
         
     | 
| 
       62 
     | 
    
         
            -
            	$('.variant_options input[type=radio]').click(function() { piggybak_variants.toggleVariantForm(); });
         
     | 
| 
       63 
     | 
    
         
            -
            	$('.variant_options select').change(function() { piggybak_variants.toggleVariantForm(); });
         
     | 
| 
       64 
     | 
    
         
            -
            	piggybak_variants.toggleVariantForm();
         
     | 
| 
       65 
     | 
    
         
            -
            });
         
     | 
| 
       66 
     | 
    
         
            -
             
     | 
| 
         @@ -1,13 +0,0 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            /*
         
     | 
| 
       2 
     | 
    
         
            -
             * This is a manifest file that'll be compiled into application.css, which will include all the files
         
     | 
| 
       3 
     | 
    
         
            -
             * listed below.
         
     | 
| 
       4 
     | 
    
         
            -
             *
         
     | 
| 
       5 
     | 
    
         
            -
             * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
         
     | 
| 
       6 
     | 
    
         
            -
             * or vendor/assets/stylesheets of plugins, if any, can be referenced here using a relative path.
         
     | 
| 
       7 
     | 
    
         
            -
             *
         
     | 
| 
       8 
     | 
    
         
            -
             * You're free to add application-wide styles to this file and they'll appear at the top of the
         
     | 
| 
       9 
     | 
    
         
            -
             * compiled file, but it's generally better to create a new file per style scope.
         
     | 
| 
       10 
     | 
    
         
            -
             *
         
     | 
| 
       11 
     | 
    
         
            -
             *= require_self
         
     | 
| 
       12 
     | 
    
         
            -
             *= require_tree .
         
     | 
| 
       13 
     | 
    
         
            -
            */
         
     | 
| 
         @@ -1,21 +0,0 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            module ActiveRecord
         
     | 
| 
       2 
     | 
    
         
            -
              module Validations
         
     | 
| 
       3 
     | 
    
         
            -
                class AssociatedBubblingValidator < ActiveModel::EachValidator
         
     | 
| 
       4 
     | 
    
         
            -
                  def validate_each(record, attribute, value)
         
     | 
| 
       5 
     | 
    
         
            -
                    (value.is_a?(Array) ? value : [value]).each do |v|
         
     | 
| 
       6 
     | 
    
         
            -
                      unless v.valid?
         
     | 
| 
       7 
     | 
    
         
            -
                        v.errors.full_messages.each do |msg|
         
     | 
| 
       8 
     | 
    
         
            -
                          record.errors.add(attribute, msg, options.merge(:value => value))
         
     | 
| 
       9 
     | 
    
         
            -
                        end
         
     | 
| 
       10 
     | 
    
         
            -
                      end
         
     | 
| 
       11 
     | 
    
         
            -
                    end
         
     | 
| 
       12 
     | 
    
         
            -
                  end
         
     | 
| 
       13 
     | 
    
         
            -
                end
         
     | 
| 
       14 
     | 
    
         
            -
             
     | 
| 
       15 
     | 
    
         
            -
                module ClassMethods
         
     | 
| 
       16 
     | 
    
         
            -
                  def validates_associated_bubbling(*attr_names)
         
     | 
| 
       17 
     | 
    
         
            -
                    validates_with AssociatedBubblingValidator, _merge_attributes(attr_names)
         
     | 
| 
       18 
     | 
    
         
            -
                  end
         
     | 
| 
       19 
     | 
    
         
            -
                end
         
     | 
| 
       20 
     | 
    
         
            -
              end
         
     | 
| 
       21 
     | 
    
         
            -
            end
         
     |