webpackJsonp([4],{

/***/ 0:
/***/ function(module, exports, __webpack_require__) {

	module.exports = __webpack_require__(1291);


/***/ },

/***/ 602:
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	exports.default = perks;
	
	var _perkDirectives = __webpack_require__(603);
	
	var _perkDirectives2 = _interopRequireDefault(_perkDirectives);
	
	var _perkFactory = __webpack_require__(610);
	
	var _perkFactory2 = _interopRequireDefault(_perkFactory);
	
	var _perkFromGonUsingIdService = __webpack_require__(611);
	
	var _perkFromGonUsingIdService2 = _interopRequireDefault(_perkFromGonUsingIdService);
	
	var _perkShareBannerDirective = __webpack_require__(612);
	
	var _perkShareBannerDirective2 = _interopRequireDefault(_perkShareBannerDirective);
	
	var _perkStoreCardDirective = __webpack_require__(614);
	
	var _perkStoreCardDirective2 = _interopRequireDefault(_perkStoreCardDirective);
	
	var _shipsToCountriesDirective = __webpack_require__(616);
	
	var _shipsToCountriesDirective2 = _interopRequireDefault(_shipsToCountriesDirective);
	
	function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
	
	function perks(angular) {
	  var perkModule = angular.module('perks', ['utils']);
	  (0, _perkDirectives2.default)(perkModule);
	  perkModule.factory('perkFactory', _perkFactory2.default).factory('perkFromGonUsingId', _perkFromGonUsingIdService2.default).directive('perkStoreCard', _perkStoreCardDirective2.default).directive('perkShareBanner', _perkShareBannerDirective2.default).directive('shipsToCountries', _shipsToCountriesDirective2.default);
	}

/***/ },

/***/ 603:
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	
	perk.$inject = ["browser", "i18n", "countriesService", "gon", "ga", "gogoEvents"];
	perkDescription.$inject = ["i18n", "gon"];
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	exports.default = perkDirectives;
	/*@ngInject*/
	function perk(browser, i18n, countriesService, gon, ga, gogoEvents) {
	
	  return {
	    restrict: 'E',
	    scope: {
	      perk: '=',
	      ctaLink: '@',
	      shippingNowCampaign: '=?',
	      preorderPerkCampaign: '=',
	      invalidYetLiveCampaign: '=',
	      indemandCampaign: '=',
	      allFundingExpired: '=',
	      showCta: '='
	    },
	    transclude: true,
	    template: __webpack_require__(604),
	    link: function link(scope) {
	      scope.shouldShowCtaLink = function () {
	        return !scope.invalidYetLiveCampaign && scope.ctaLink && (scope.preorderPerkCampaign || scope.shippingNowCampaign || scope.indemandCampaign || scope.perk.expanded && !browser.isTabletPlus() || scope.showCta) && !scope.allFundingExpired;
	      };
	
	      function currency() {
	        if (gon.campaign) {
	          return gon.campaign.currency;
	        }
	        if (gon.contribution) {
	          return gon.contribution.currency;
	        }
	      }
	
	      function clickPerkAction() {
	        if (!scope.perk.sold_out && !scope.allFundingExpired) {
	          if (scope.perk.collapsible) {
	            scope.perk.expanded = !scope.perk.expanded;
	          } else if (scope.ctaLink && !scope.invalidYetLiveCampaign) {
	            // track secret perk clicks from the campaign page (goes into contribution flow)
	            if (scope.perk.secret && scope.ctaLink.indexOf("contributions/new") >= 0) {
	              // TODO EVENTS: id=buy7o subsystem=campaign-page fixtype=none category=Campaign.Page action=Click.Secret.Perk name=campaign_page_click_secret_perk . combine
	              gogoEvents.track({
	                thetaName: 'campaign_page_click_secret_perk',
	                gaEventCategory: 'Campaign Page',
	                gaEventAction: 'Click Secret Perk'
	              });
	            }
	            browser.redirectTo(scope.ctaLink);
	          }
	        }
	      }
	
	      function perkBtnTxt() {
	        if (scope.shippingNowCampaign || scope.perk.shipping_now) {
	          return i18n.t('pre_order_page.buy_now');
	        } else {
	          return i18n.t('contribution_flow.get_this_perk');
	        }
	      }
	
	      scope.i18n = i18n;
	      scope.countries = countriesService;
	      scope.isShippingLabelDisplayed = scope.perk.isShippingLabelDisplayed();
	      scope.currency = currency();
	      scope.clickPerkAction = clickPerkAction;
	      scope.perkBtnTxt = perkBtnTxt();
	    }
	  };
	}
	
	function perkChange() {
	  return {
	    restrict: 'E',
	    template: __webpack_require__(605)
	  };
	}
	
	function perkTitle() {
	  return {
	    restrict: 'E',
	    template: __webpack_require__(606),
	    transclude: true
	  };
	}
	
	/*@ngInject*/
	function perkDescription(i18n, gon) {
	  return {
	    restrict: 'E',
	    template: __webpack_require__(607),
	    link: function link(scope) {
	      function perksClaimed() {
	        var numClaimed = scope.perk.number_claimed || 0;
	        if (scope.perk.number_available) {
	          return i18n.t('x_out_of_y_claimed_html', {
	            x: numClaimed,
	            y: scope.perk.number_available,
	            count: numClaimed
	          });
	        } else {
	          return i18n.t('x_claimed_html', {
	            number_claimed: numClaimed,
	            count: numClaimed
	          });
	        }
	      }
	      function currency() {
	        if (gon.campaign) {
	          return gon.campaign.currency;
	        }
	        if (gon.contribution) {
	          return gon.contribution.currency;
	        }
	      }
	      function non_tax_deductible_amount_with_currency() {
	        return currency().symbol + scope.perk.non_tax_deductible_amount;
	      }
	      function tax_deductible_message() {
	        if (!_.isNumber(scope.perk.non_tax_deductible_amount)) {
	          return "";
	        }
	        if (scope.perk.non_tax_deductible_amount > 0) {
	          return i18n.t('amount_over_x_is_tax_deductible', { non_tax_deductible_amount: non_tax_deductible_amount_with_currency() });
	        } else {
	          return i18n.t('fully_tax_deductible');
	        }
	      }
	
	      scope.perksClaimed = perksClaimed;
	      scope.tax_deductible_message = tax_deductible_message;
	      scope.i18n = i18n;
	    }
	  };
	}
	
	function amountWithCurrency() {
	  return {
	    restrict: 'E',
	    template: __webpack_require__(608)
	  };
	}
	
	function perkDiscount() {
	  return {
	    restrict: 'E',
	    template: __webpack_require__(609),
	    link: function perkDiscountLink(scope) {
	      function calculateDiscount(perk) {
	        perk = perk || scope.perk;
	        return perk.retail_amount && Math.floor((perk.retail_amount - perk.amount) / perk.retail_amount * 100);
	      }
	      scope.discountPercent = calculateDiscount();
	
	      scope.$on('perkUpdated', function (event, updatedPerk) {
	        if (updatedPerk.id == scope.perk.id) {
	          scope.discountPercent = calculateDiscount(updatedPerk);
	        }
	      });
	    }
	  };
	}
	
	function perkDirectives(perkModule) {
	  perkModule.directive('perk', perk).directive('perkChange', perkChange).directive('perkTitle', perkTitle).directive('perkDescription', perkDescription).directive('amountWithCurrency', [amountWithCurrency]).directive('perkDiscount', [perkDiscount]);
	}

/***/ },

/***/ 604:
/***/ function(module, exports) {

	module.exports = "<div class=\"perkItem open\" ng-disabled=\"perk.sold_out || allFundingExpired\" ng-click=\"clickPerkAction()\" ng-class=\"{ 'perkItem--secretPerk' : perk.secret }\" gogo-test=\"card\">\n  <div class=\"perkImageColumn\">\n    <div class=\"perkImageWrapper\">\n      <div class=\"perkImageOverlay\"></div>\n      <img ng-if=\"perk.perk_image_public_id\" class=\"perkImage\"\n           cl-image width=\"304\" height=\"230\" crop=\"fill\"\n           public-id=\"perk.perk_image_public_id\" alt=\"{{i18n.t('upload_an_image')}}\"/>\n    </div>\n  </div>\n  <div class=\"perkItem-contributewrap clearfix\">\n    <div class=\"i-perk-expand-toggle pull-right\" ng-if=\"perk.collapsible\">\n      <svg class=\"dropdownIcon\" ng-class=\"{open: perk.expanded}\"><use xlink:href=\"#down-caret\"></use></svg>\n    </div>\n\n    <div ng-if=\"perk.sold_out\" class=\"i-soldout-mask\">\n      <span class=\"i-text\">{{::i18n.t('sold_out')}}</span>\n    </div>\n\n    <div ng-class=\"{ 'secretPerk-banner' : true, 'secretPerk-banner-soldOut' : perk.sold_out }\" ng-if=\"perk.secret\">\n      <svg-icon icon=\"icon-icon-shades\" class=\"secretPerk-shades\"></svg-icon>\n      <span class=\"secretPerk-bannerText\">\n        {{::i18n.t('secret_perk.secret_perk')}}\n      </span>\n      <div ng-class=\"{ 'secretPerk-bannerFold' : true, 'secretPerk-bannerFold-soldOut' : perk.sold_out }\"></div>\n    </div>\n\n    <div ng-if=\"perk.has_callout_label\"\n         class=\"highlight bold top_perk i-top-perk perkItem-topPerk\">\n      {{::perk.callout_label}}\n    </div>\n    <amount-with-currency></amount-with-currency>\n    <perk-discount></perk-discount>\n    <div ng-transclude></div>\n    <div class=\"perkItem-getThisPerkButtonWrapper\" ng-if=\"shouldShowCtaLink()\">\n      <a ng-href=\"{{ctaLink}}\" class=\"i-cta-1 perkItem-getThisPerkButton\" gogo-test=\"cta\">\n        {{::perkBtnTxt}}\n      </a>\n    </div>\n  </div>\n</div>\n";

/***/ },

/***/ 605:
/***/ function(module, exports) {

	module.exports = "<a href=\"\" class=\"perkItem-changePerkLink\">\n  {{::i18n.t('contribution_flow.change_perk')}}\n</a>\n";

/***/ },

/***/ 606:
/***/ function(module, exports) {

	module.exports = "<div gogo-test=\"perk-label\" class=\"perkItem-title\">\n  {{perk.label}}\n  <span ng-transclude></span>\n</div>\n";

/***/ },

/***/ 607:
/***/ function(module, exports) {

	module.exports = "<div gogo-test=\"perk-description\">\n  <div class=\"perkItem-description\" ng-if=\"!perk.collapsible || perk.expanded\">{{perk.description}}</div>\n  <div class=\"perkItem-tax-info\" ng-if=\"perk.use_non_tax_deductible_amount\">\n    {{tax_deductible_message()}}\n  </div>\n  <span class=\"perkItem-lineItem-label availability\" ng-bind-html=\"perksClaimed()\"></span>\n  <div ng-if=\"perk.estimated_delivery_date\">\n    <span class=\"perkItem-lineItem-label\">{{::i18n.t('contribution_flow.line_items.estimated_delivery')}}</span>\n    <span class=\"perkItem-lineItem-value\">{{perk.estimated_delivery_date | date:'MMMM yyyy'}}</span>\n  </div>\n</div>\n";

/***/ },

/***/ 608:
/***/ function(module, exports) {

	module.exports = "<span class=\"perkItem-perkAmount\">{{currency.symbol}}{{perk.amount}}</span>\n<span class=\"perkItem-currencyAndLabeling\">{{currency.iso_code}}\n  <span ng-if=\"isShippingLabelDisplayed\"> + {{::i18n.t('contribution_flow.shipping')}}</span>\n</span>\n";

/***/ },

/***/ 609:
/***/ function(module, exports) {

	module.exports = "<div class=\"perkItem-discount\" ng-if=\"discountPercent\">\n  <span class=\"perkItem-retailAmount\">{{perk.retail_amount| currency:currency.symbol:0}}</span>\n  ({{discountPercent}}{{i18n.t('pre_order_page.percent_off')}})\n</div>\n";

/***/ },

/***/ 610:
/***/ function(module, exports) {

	"use strict";
	
	PerkFactory.$inject = ["$http", "$rootScope", "_", "countriesService", "i18n", "$log", "gon"];
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	
	var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol ? "symbol" : typeof obj; };
	
	exports.default = PerkFactory;
	/*@ngInject*/
	function PerkFactory($http, $rootScope, _, countriesService, i18n, $log, gon) {
	  var countries = countriesService;
	
	  /**
	   * TODO: list attributes explicitly as function arguments, rather than a single argument with docs
	   * @param attributes
	   *  REQUIRED
	   *    amount: positive int
	   *    label: string at most 30 long
	   *    description: string at most 500 long
	   *  OPTIONAL
	   *    number_available: positive int, null = unlimited i think
	   *    estimated_delivery_date:
	   *    shipping_address_required: true/false
	   *    retail_amount: positive int
	   *    perk_image_public_id: string
	   *    pre_orderable: true/false
	   *    shipping: object of form:
	   *       { fees: { <countrycode>: <fee> },
	   *         is_free_everywhere: true/false }
	   * @constructor
	   */
	
	  function syncShippingFees(perkAttributes) {
	    var hasShippingDotFees, hasShippingObj, hasShippingUnderscoreFees, updatedShippingDotFees, difference;
	    var self = perkAttributes ? perkAttributes : this;
	    self.wasShippingSetByDefault = false;
	
	    hasShippingObj = _.isObject(self.shipping);
	    hasShippingUnderscoreFees = _.isObject(self.shipping_fees);
	
	    if (hasShippingObj) {
	      hasShippingDotFees = _.isObject(self.shipping.fees);
	    } else {
	      self.shipping = { fees: {} };
	    }
	
	    // If it DOES HAVE shipping.fees
	    // but DOES NOT HAVE shipping_fees,
	    // build shipping_fees.
	    if (hasShippingDotFees && !hasShippingUnderscoreFees) {
	      var shipKeys = Object.keys(self.shipping.fees);
	      var updatedShippingUnderscoreFees = [];
	      _.each(shipKeys, function (shipKey) {
	        var shipFee = {};
	        shipFee.country_code = shipKey;
	        shipFee.fee = self.shipping.fees[shipKey];
	        updatedShippingUnderscoreFees.push(shipFee);
	      });
	      self.shipping_fees = updatedShippingUnderscoreFees;
	    }
	
	    // If it DOES NOT HAVE shipping.fees
	    // but DOES HAVE shipping_fees,
	    // build shipping.fees.
	    if (!hasShippingDotFees && hasShippingUnderscoreFees) {
	      updatedShippingDotFees = {};
	      _.each(self.shipping_fees, function (feeObj) {
	        updatedShippingDotFees[feeObj.country_code] = feeObj.fee;
	      });
	      self.shipping.fees = updatedShippingDotFees;
	    }
	
	    // If it has BOTH shipping.fees AND shipping_fees,
	    // make sure shipping.fees matches shipping_fees.
	    if (hasShippingDotFees && hasShippingUnderscoreFees) {
	      difference = _.difference(_.pluck(self.shipping_fees, "country_code"), Object.keys(self.shipping.fees));
	
	      // If shipping_fees and shipping.fees DO NOT MATCH
	      // set shipping.fees to match shipping_fees.
	      if (!_.isEmpty(difference)) {
	        updatedShippingDotFees = {};
	        _.each(self.shipping_fees, function (feeObj) {
	          updatedShippingDotFees[feeObj.country_code] = feeObj.fee;
	        });
	        self.shipping.fees = updatedShippingDotFees;
	      }
	    }
	
	    // If it has NEITHER shipping.fees nor shipping_fees,
	    // set default objects of everywhere for free for both.
	    if (!hasShippingDotFees && !hasShippingUnderscoreFees) {
	      self.wasShippingSetByDefault = true;
	      self.shipping = { is_free_everywhere: true, fees: { everywhere: 0 } };
	      self.shipping_fees = [{ country_code: "everywhere", fee: 0 }];
	    }
	  }
	
	  function Perk(attributes, options) {
	    attributes = this._processIncomingAttributes(attributes);
	    options = options || {};
	
	    if (angular.isUndefined(options.createDropdownCountryObjects)) {
	      options.createDropdownCountryObjects = true;
	    }
	
	    ///TODO: Check all required attributes AND VALUES are present
	
	    if (attributes.estimated_delivery_date) {
	      attributes.estimated_delivery_date = new Date(attributes.estimated_delivery_date);
	    }
	    attributes.shipping_address_required = attributes.shipping_address_required || false;
	    if (attributes.shipping_address_required) {
	      syncShippingFees(attributes);
	    }
	
	    _.merge(this, attributes);
	
	    // without this the mobile campaign page has big problems
	    // the default is to create the dropdown country objects,
	    // but there is the option to turn it off
	    if (options.createDropdownCountryObjects) {
	      this.dropdownCountryObjects = this._createDropdownCountryObjects();
	    }
	
	    this.sold_out = !!(this.number_available && this.number_claimed >= this.number_available);
	
	    //todo: refactor PerkFactory to get passed an attribute .campaign_shipping_now in the future. for now, this.campaign_shipping_now is used for testing.
	    this.campaign_shipping_now = this.campaign_shipping_now || gon.campaign && !!gon.campaign.is_shipping_now_campaign;
	    if (this.shipping_now && !this.campaign_shipping_now) {
	      this.callout_label = i18n.t('perk_store.shipping_now');
	    } else if (this.featured) {
	      this.callout_label = i18n.t('featured');
	    }
	    this.has_callout_label = !this.sold_out && !!this.callout_label;
	
	    var thisPerkID = 'perk' + this.id;
	    var objToRegister = {};
	    objToRegister[thisPerkID] = this;
	  }
	
	  Perk.prototype.syncShippingFees = syncShippingFees;
	
	  Perk.prototype._processIncomingAttributes = function (attributes) {
	    // create/edit page provides attributes in camel case
	    var dashed_attrs = {};
	    var self = this;
	    _.forEach(attributes, function (n, key) {
	      var ckey = self._snakeCase(key); // use _.snakeCase after lodash upgrade
	      dashed_attrs[ckey] = n;
	    });
	    if (dashed_attrs.shipping) {
	      if (_.has(dashed_attrs.shipping.fees, "europeanUnion")) {
	        dashed_attrs.shipping.fees.european_union = dashed_attrs.shipping.fees.europeanUnion;
	        delete dashed_attrs.shipping.fees.europeanUnion;
	      }
	    }
	    return dashed_attrs;
	  };
	
	  Perk.prototype._snakeCase = function (str) {
	    return str.replace(/([a-z\d])([A-Z])/g, '$1_$2').toLowerCase();
	  };
	
	  Perk.prototype.displayShippingCountries = function () {
	    if (!(this.shipping && _typeof(this.shipping_fees) === 'object')) {
	      return;
	    } else if (this._displayShippingCountries) {
	      return this._displayShippingCountries;
	    }
	
	    var perkShippingCountries = _.pluck(this.shipping_fees, 'country_code');
	    var countryList = [];
	    if (_.include(perkShippingCountries, "everywhere")) {
	      return [i18n.t('worldwide')];
	    } else if (_.include(perkShippingCountries, "european_union")) {
	      perkShippingCountries = _.difference(perkShippingCountries, countries.europeanUnion());
	      perkShippingCountries = _.difference(perkShippingCountries, ["european_union"]);
	      countryList.push(i18n.t("european_union"));
	    }
	    _.each(perkShippingCountries, function (cc) {
	      var currentCountry = countries.findByAlpha2(cc);
	      countryList.push(currentCountry.text);
	    });
	
	    this._displayShippingCountries = countryList.sort();
	    return this._displayShippingCountries;
	  };
	
	  Perk.prototype.hasShippingObject = function () {
	    if (_.isUndefined(this.shipping_address_required)) {
	      $log.error("hashShippingObject() called but shipping_address_required is undefined");
	    }
	    return !!this.shipping && !!this.shipping_address_required;
	  };
	
	  Perk.prototype.isShippingLabelDisplayed = function () {
	    if (this.hasShippingObject()) {
	      var shippingCountries = this.shipping.fees;
	      return !_.all(shippingCountries, function (fee) {
	        return fee === 0;
	      });
	    } else {
	      return false;
	    }
	  };
	
	  Perk.prototype.feeForCountry = function (country) {
	    if (!country) {
	      return null;
	    }
	    if (this.shipping && _typeof(this.shipping.fees) === 'object') {
	      var shippingCountries = Object.keys(this.shipping.fees);
	      var shipsToSpecificCountry = _.include(shippingCountries, country.country_code_alpha_2);
	      var shipsToEU = _.include(shippingCountries, "european_union");
	      var shipsWorldwide = _.include(shippingCountries, "everywhere");
	
	      if (shipsToSpecificCountry) {
	        return this.shipping.fees[country.country_code_alpha_2];
	      } else if (shipsToEU && _.include(country.tags, "european_union")) {
	        return this.shipping.fees.european_union;
	      } else if (shipsWorldwide) {
	        return this.shipping.fees.everywhere;
	      } else {
	        return null;
	      }
	    }
	    return null;
	  };
	
	  Perk.prototype.shipsWorldwide = function () {
	    var perkShippingCountryCodes = _.keys(this.shipping.fees);
	    return _.include(perkShippingCountryCodes, 'everywhere');
	  };
	
	  Perk.prototype.shipsToCountry = function (country) {
	    var perkShippingCountryCodes = null;
	    if (!this.shipping) {
	      return true;
	    }
	    if (!perkShippingCountryCodes) {
	      perkShippingCountryCodes = Object.keys(this.shipping.fees);
	    }
	    if (_.include(perkShippingCountryCodes, 'everywhere')) {
	      return !!country;
	    }
	
	    if (_.include(country.tags, "european_union") && _.include(perkShippingCountryCodes, 'european_union')) {
	      return true;
	    }
	    return _.include(perkShippingCountryCodes, country.country_code_alpha_2);
	  };
	
	  Perk.prototype.shipsToCode = function (twoLetterCtryCode) {
	    return this.shipsToCountry(countries.findByAlpha2(twoLetterCtryCode));
	  };
	
	  Perk.prototype._createDropdownCountryObjects = function () {
	    var self = this;
	    if (!this.shipping_address_required) {
	      return [];
	    }
	    if (self._modifiedCountries) {
	      return self._modifiedCountries;
	    }
	    self._modifiedCountries = _.cloneDeep(countries.asUiSelectItems());
	    _.map(self._modifiedCountries, function (ctry) {
	      var countryCode = ctry.country_code_alpha_2;
	      var labelForDropdown = ctry.text;
	      var shipsTo = self.shipsToCountry(ctry);
	      var fee = self.feeForCountry(ctry);
	
	      if (countryCode && !shipsTo) {
	        labelForDropdown += " – " + i18n.t('not_available');
	      }
	
	      ctry.label_for_dropdown = labelForDropdown;
	      ctry.ships_to = shipsTo;
	      ctry.fee = fee;
	    });
	
	    return self._modifiedCountries;
	  };
	
	  Perk.prototype.saveOrUpdatePerk = function saveOrUpdatePerk(campaignId, perkFieldsDisabled) {
	    var url,
	        method,
	        self = this;
	
	    function perkParams() {
	      var paramsList,
	          preOrderParams = ['perk_image_public_id', 'retail_amount'];
	      if (perkFieldsDisabled) {
	        paramsList = preOrderParams;
	      } else {
	        paramsList = gon.api_settings.campaign_perks_controller.permitted_params;
	      }
	      var params = _.pick(self, paramsList);
	      // TODO: when perkFormPreOrder sets it, it's publicId. But when we get it back, it's both. Maybe we should leave it as one?
	      params.perk_image_public_id = self.image && self.image.public_id;
	      return params;
	    }
	
	    if (self.id) {
	      url = '/private_api/campaigns/' + campaignId + '/perks/' + self.id;
	      method = 'PUT';
	    } else {
	      url = '/private_api/campaigns/' + campaignId + '/perks/';
	      method = 'POST';
	    }
	
	    var httpCall = $http({
	      method: method,
	      url: url,
	      data: { perk: perkParams() }
	    });
	
	    httpCall.success(function (data) {
	      if (method === 'PUT') {
	        self.syncShippingFees();
	        self.perk_image_public_id = data.response.perk_image_public_id;
	        self.retail_amount = data.response.retail_amount;
	        self._displayShippingCountries = null;
	        self._displayShippingCountries = self.displayShippingCountries();
	        $rootScope.$broadcast('perkUpdated', self);
	      }
	      if (method === 'POST') {
	        self.perk_image_public_id = data.response.perk_image_public_id;
	        self.retail_amount = data.response.retail_amount;
	        self.secret_perk_path = data.response.secret_perk_path;
	        self.syncShippingFees();
	        self.id = data.response.id;
	        $rootScope.$broadcast('perkCreated', self);
	      }
	    });
	
	    httpCall.error(function () {
	      $rootScope.$broadcast('perkSaveFailure');
	    });
	  };
	
	  Perk.prototype.deletePerk = function (campaignId) {
	    var self = this;
	    var url = '/private_api/campaigns/' + campaignId + '/perks/' + self.id;
	
	    $http({
	      method: 'DELETE',
	      url: url
	    }).success(function () {
	      $rootScope.$broadcast('perkDeleted', self);
	    }).error(function () {
	      $rootScope.$broadcast('perkDeleteFailure');
	    });
	  };
	
	  return Perk;
	}

/***/ },

/***/ 611:
/***/ function(module, exports) {

	"use strict";
	
	perkFromGonUsingId.$inject = ["gon", "perkFactory", "$log", "_"];
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	exports.default = perkFromGonUsingId;
	/*@ngInject*/
	function perkFromGonUsingId(gon, perkFactory, $log, _) {
	  var Perk = perkFactory;
	  return function findPerk(perkId) {
	    var perkAttr = _.find(gon.campaign.perks, function (perkAttrs) {
	      return perkAttrs.id === parseInt(perkId);
	    });
	    return new Perk(perkAttr);
	  };
	}

/***/ },

/***/ 612:
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	
	perkShareBanner.$inject = ["gon", "gogoEvents", "i18n", "fb", "twitter"];
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	exports.default = perkShareBanner;
	/*@ngInject*/
	function perkShareBanner(gon, gogoEvents, i18n, fb, twitter) {
	  return {
	    restrict: 'E',
	    scope: {},
	    template: __webpack_require__(613),
	    link: function link(scope) {
	      var analyticsOptions = {
	        pageLocation: 'perk'
	      };
	
	      scope.shareFacebook = function () {
	        var options = gon.current_account ? { account_id: gon.current_account.account_id } : {};
	        options.utm_query_string = gon.fb_utm_query_string;
	        fb.share(gon.share.canonical_url, options).then(function () {
	          // TODO EVENTS: id=eds01 fixtype=none category=campaign_page_share action=click_fb_share_perk_successful label=dynamic name=click_fb_share_successful vars=pageLocation .
	          gogoEvents.track(_.merge({
	            thetaName: 'click_fb_share_successful',
	            gaEventCategory: 'campaign_page_share',
	            gaEventAction: 'click_fb_share_perk_successful',
	            gaEventLabel: gon.ga_impression_data.category
	          }, analyticsOptions));
	        });
	        // TODO EVENTS: id=eds02 fixtype=none category=campaign_page_share action=click_fb_share_perk label=dynamic name=click_fb_share vars=pageLocation .
	        gogoEvents.track(_.merge({
	          thetaName: 'click_fb_share',
	          gaEventCategory: 'campaign_page_share',
	          gaEventAction: 'click_fb_share_perk',
	          gaEventLabel: gon.ga_impression_data.category
	        }, analyticsOptions));
	      };
	
	      scope.shareTwitter = function () {
	        var title = i18n.t('help_make_it_happen_twitter_tooltip', { project_title: gon.share.project_title });
	        twitter.shareTwitter(gon.share.twitter_url, title, gon.share.canonical_url);
	        // TODO EVENTS: id=eds03 fixtype=none category=campaign_page_share action=click_tw_share_perk label=dynamic name=click_tw_share vars=pageLocation .
	        gogoEvents.track(_.merge({
	          thetaName: 'click_tw_share',
	          gaEventCategory: 'campaign_page_share',
	          gaEventAction: 'click_tw_share_perk',
	          gaEventLabel: gon.ga_impression_data.category
	        }, analyticsOptions));
	      };
	    }
	  };
	}

/***/ },

/***/ 613:
/***/ function(module, exports) {

	module.exports = "<div class=\"perkItem-shareBanner\">\n  <div class=\"shareBanner\">\n    <svg-icon ng-click=\"shareFacebook()\" icon=\"icon-icon-facebook\" class=\"shareBanner-icon shareBanner-fb\"></svg-icon>\n  </div>\n  <div class=\"shareBanner\">\n    <svg-icon ng-click=\"shareTwitter()\" icon=\"icon-icon-twitter\" class=\"shareBanner-icon shareBanner-tw\"></svg-icon>\n  </div>\n</div>\n";

/***/ },

/***/ 614:
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	
	perkStoreCard.$inject = ["iggCurrencyFilter", "i18n", "$timeout", "gon"];
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	exports.default = perkStoreCard;
	/*@ngInject*/
	function perkStoreCard(iggCurrencyFilter, i18n, $timeout, gon) {
	  return {
	    replace: true,
	    scope: {
	      perk: '=',
	      iggref: '='
	    },
	    template: __webpack_require__(615),
	    link: function link(scope, element) {
	      scope.i18n = i18n;
	
	      scope.amountHtml = function () {
	        return iggCurrencyFilter(scope.perk.perk_amount, scope.perk.currency_iso_num, 'html');
	      };
	
	      scope.getIggref = function () {
	        if (!_.isUndefined(scope.iggref) && !_.isNull(scope.iggref)) {
	          return scope.iggref;
	        } else {
	          return gon.iggref;
	        }
	      };
	
	      if (scope.perk.ad_target_url) {
	        scope.sendToPath = scope.perk.ad_target_url;
	      } else {
	        scope.sendToPath = "/projects/" + scope.perk.campaign_slug + "/" + scope.getIggref();
	      }
	
	      $timeout(function () {
	        element.find('.perkCard-label').dotdotdot({
	          wrap: "letter",
	          watch: "window"
	        });
	      });
	    }
	  };
	}

/***/ },

/***/ 615:
/***/ function(module, exports) {

	module.exports = "<a ng-href=\"{{ ::sendToPath }}\" class=\"perkCard\">\n\n  <div ng-if=\"::perk.perk_name\">\n    <div class=\"perkCard-imageContainer\" ng-style=\"{'background-image': 'url(' + perk.perk_image_url +')'}\">\n      <div class=\"perkCard-duskify\"></div>\n\n      <div class=\"perkCard-hoverOverlay\">\n        <div class=\"i-cta-1 i-cta-1--ghostWhite i-cta-1--noHover\">\n          {{ ::i18n.t('see_details') }}\n        </div>\n      </div>\n    </div>\n\n    <div class=\"perkCard-details i-mobile-container--15\">\n      <div class=\"perkCard-label\">\n        {{ ::perk.perk_name }}\n        <span class=\"perkCard-description\">\n          {{ ::perk.short_description }}\n        </span>\n      </div>\n\n      <div class=\"perkCard-price\"\n           ng-bind-html=\"::amountHtml()\">\n      </div>\n\n    </div>\n  </div>\n\n  <div ng-if=\"::perk.ad_target_url\" class=\"perkStoreAd\">\n    <div class=\"perkStoreAd-slug\">\n      {{ ::i18n.t('share_wizard.did_you_know') }}\n    </div>\n    <div class=\"perkStoreAd-description\">\n      {{ ::i18n.t('perk_store.browsing_products') }}\n    </div>\n    <div class=\"perkStoreAd-cta\">\n      {{ ::i18n.t('learn_more') }}\n    </div>\n  </div>\n</a>\n";

/***/ },

/***/ 616:
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	
	shipsToCountries.$inject = ["i18n", "perkFactory", "$log", "perkFromGonUsingId"];
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	exports.default = shipsToCountries;
	/*@ngInject*/
	function shipsToCountries(i18n, perkFactory, $log, perkFromGonUsingId) {
	  var Perk = perkFactory;
	  return {
	    restrict: 'E',
	    scope: {
	      // one of the following options is required:
	      optionPerk: '=', // perkFactory baby
	      optionPerkId: '=', // perk ID (int)
	      optionPerkAttr: '=' // perk attributes for perkFactory
	    },
	    template: __webpack_require__(617),
	    link: function link(scope) {
	      var MAX_COUNTRY_COUNT = 5;
	      scope.labelText = '';
	      scope.i18n = i18n;
	      scope.andMoreClicked = false;
	
	      if (scope.optionPerkId) {
	        scope.perk = perkFromGonUsingId(scope.optionPerkId);
	      } else if (scope.optionPerkAttr) {
	        scope.perk = new Perk(scope.optionPerkAttr);
	      } else if (scope.optionPerk) {
	        scope.perk = scope.optionPerk;
	      } else {
	        $log.error("ships-to-countries directive incorrectly called");
	      }
	
	      function shipsWorldwide() {
	        return scope.perk.shipsWorldwide();
	      }
	      function moreThanFiveCountries() {
	        var countries = scope.perk.displayShippingCountries();
	        return countries.length > MAX_COUNTRY_COUNT;
	      }
	
	      scope.showCountries = function () {
	        return !shipsWorldwide() && !moreThanFiveCountries();
	      };
	
	      // Select Label
	      if (shipsWorldwide()) {
	        scope.labelText = i18n.t('contribution_flow.line_items.ships_worldwide');
	      } else if (moreThanFiveCountries()) {
	        scope.labelText = i18n.t('contribution_flow.line_items.ships_many');
	      } else {
	        scope.labelText = i18n.t('contribution_flow.line_items.ships_to');
	      }
	
	      scope.perkShippingCountries = scope.perk.displayShippingCountries();
	      scope.$on('perkUpdated', function (event, updatedPerk) {
	        if (updatedPerk.id === scope.perk.id) {
	          scope.perkShippingCountries = scope.perk.displayShippingCountries();
	        }
	      });
	    }
	  };
	}

/***/ },

/***/ 617:
/***/ function(module, exports) {

	module.exports = "<div>\n  <span class=\"shipsTo-label i-perkBottom-label\">{{::labelText}}</span>\n  <span class=\"shipsTo-value i-perkBottom-value\"\n        ng-if=\"showCountries()\" ng-repeat=\"country in perkShippingCountries\">\n    {{::country}}{{($last) ? '' : ', '}}\n  </span>\n</div>\n\n";

/***/ },

/***/ 936:
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	
	contributionsApi.$inject = ["$http", "$interpolate", "$httpParamSerializer", "gon"];
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	exports.default = contributionsApi;
	
	var _privateApi = __webpack_require__(186);
	
	/* @ngInject */
	function contributionsApi($http, $interpolate, $httpParamSerializer, gon) {
	  var urls = { index: null, indexCsv: null, show: null };
	
	  function validInteger(id) {
	    return !angular.isUndefined(id) && typeof id === 'number' && id > 0;
	  }
	
	  function requireUrl(key) {
	    if (!urls[key]) {
	      throw new Error(key + ' url is not defined');
	    }
	  }
	
	  return {
	    setUrls: function setUrls(newUrls) {
	      urls = newUrls;
	    },
	
	    getUrls: function getUrls() {
	      return urls;
	    },
	
	    getContributions: function getContributions(params) {
	      var url;
	      if (gon.campaign && gon.campaign.id) {
	        url = (0, _privateApi.privateApiCampaignContributionsPath)({ campaignId: gon.campaign.id });
	      } else {
	        requireUrl('index');
	        url = urls.index;
	      }
	
	      params = params || {};
	
	      if (angular.isUndefined(params.page)) {
	        params.page = 1;
	      }
	
	      return $http.get(url, { params: params });
	    },
	
	    getContribution: function getContribution(id) {
	      requireUrl('show');
	
	      var numericId = parseInt(id);
	      if (validInteger(numericId)) {
	        var url = $interpolate(urls.show)({ id: numericId });
	        return $http.get(url);
	      } else {
	        throw new Error('Invalid Pledge ID');
	      }
	    },
	
	    exportCsv: function exportCsv(params) {
	      // angular doesn't transform POST params using form-urlencoded properly, so transformation is needed
	      return $http({
	        method: 'POST',
	        url: urls.export,
	        headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
	        data: $httpParamSerializer(params)
	      });
	    }
	  };
	}

/***/ },

/***/ 1069:
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	
	campaignVideo.$inject = ["$sce", "youtube", "ga", "$interval", "$timeout", "froogaloop", "campaignAnalyticsService", "browser"];
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	exports.default = campaignVideo;
	/* global YT */
	/*@ngInject*/
	function campaignVideo($sce, youtube, ga, $interval, $timeout, froogaloop, campaignAnalyticsService, browser) {
	  return {
	    restrict: 'E',
	    scope: {
	      id: '@'
	    },
	    template: __webpack_require__(1070),
	    link: function link(scope, element, attrs) {
	      var player;
	      var vimeoReady = false;
	      var initialPlayEventRecorded;
	
	      scope.overlayUrl = attrs.overlayUrl;
	      scope.type = attrs.type;
	      scope.overlayHidden = false;
	
	      scope.vimeo_video_url = $sce.trustAsResourceUrl('//player.vimeo.com/video/' + attrs.id + '?api=1&amp;player_id=vimeoPlayer&amp;title=0&amp;byline=0&amp;portrait=0');
	
	      scope.isReadyToPlay = function () {
	        if (scope.type === 'youtube') {
	          return player && typeof player.playVideo == 'function';
	        } else if (scope.type === 'vimeo') {
	          return vimeoReady;
	        } else {
	          return false;
	        }
	      };
	
	      scope.playVideo = function () {
	        if (scope.type === 'youtube') {
	          player.playVideo();
	        } else if (scope.type === 'vimeo') {
	          player.api('play');
	        }
	      };
	
	      scope.overlayClicked = function () {
	        campaignAnalyticsService.sendVideoAnalyticsEvent('campaign_page_video', 'Play Video', { theta_name: 'campaign.video/video.play', player_type: scope.type });
	        var checkUntilReadyToPlay = $interval(function () {
	          if (scope.isReadyToPlay()) {
	            scope.playVideo();
	            $interval.cancel(checkUntilReadyToPlay);
	          }
	        }, 1);
	      };
	
	      scope.hideOverlay = function () {
	        scope.overlayHidden = true;
	      };
	
	      function removeOverlayForMobile() {
	        /* remove the overlay from the dom so user can see that video is loading */
	        if (browser.isMobile()) {
	          var overlay = element.find('.campaignVideo-overlay');
	          if (overlay) overlay.remove();
	        }
	      }
	
	      if (scope.type === 'youtube') {
	        youtube.onReady(function () {
	          $timeout(function () {
	            player = new YT.Player('campaignVideo-youtube', {
	              width: '100%',
	              height: '100%',
	              videoId: scope.id,
	              playerVars: {
	                rel: 0,
	                showinfo: 0,
	                modestbranding: 1,
	                fs: 0,
	                wmode: 'opaque'
	              },
	              events: {
	                onStateChange: onYTStateChange
	              }
	            });
	          }, 0);
	        });
	      } else if (scope.type === 'vimeo') {
	        $timeout(function () {
	          player = froogaloop(element.find('#vimeoPlayer')[0]);
	          player.addEvent('ready', function () {
	            vimeoReady = true;
	            player.addEvent('pause', onVimeoPause);
	
	            player.addEvent('play', function () {
	              scope.hideOverlay();
	              recordPlayEvent();
	            });
	          });
	        }, 0);
	      }
	
	      function onVimeoPause() {
	        player.api('getDuration', function (duration) {
	          player.api('getCurrentTime', function (timeElapsed) {
	            var percent = timeElapsed / duration;
	            if (percent > 0.99) {
	              campaignAnalyticsService.sendVideoAnalyticsEvent('campaign_page_video', 'Video Finished', { theta_name: 'campaign.video/video.finish', player_type: scope.type });
	            } else {
	              campaignAnalyticsService.sendVideoAnalyticsEvent('campaign_page_video', 'Video Paused', { theta_name: 'campaign.video/video.pause', player_type: scope.type });
	            }
	          });
	        });
	      }
	
	      function recordPlayEvent() {
	        if (initialPlayEventRecorded) {
	          campaignAnalyticsService.sendVideoAnalyticsEvent('campaign_page_video', 'Video Resumed', { theta_name: 'campaign.video/video.resume', player_type: scope.type });
	        } else {
	          initialPlayEventRecorded = true;
	          campaignAnalyticsService.sendVideoAnalyticsEvent('campaign_page_video', 'Video Playing', { theta_name: 'campaign.video/video.playing', player_type: scope.type });
	        }
	      }
	
	      function onYTStateChange(event) {
	        switch (event.data) {
	          case YT.PlayerState.UNSTARTED:
	            removeOverlayForMobile();
	            break;
	          case YT.PlayerState.PLAYING:
	            scope.hideOverlay();
	            recordPlayEvent();
	            break;
	          case YT.PlayerState.ENDED:
	            campaignAnalyticsService.sendVideoAnalyticsEvent('campaign_page_video', 'Video Finished', { theta_name: 'campaign.video/video.finish', player_type: scope.type });
	            break;
	          case YT.PlayerState.PAUSED:
	            campaignAnalyticsService.sendVideoAnalyticsEvent('campaign_page_video', 'Video Paused', { theta_name: 'campaign.video/video.pause', player_type: scope.type });
	            break;
	        }
	      }
	    }
	  };
	}

/***/ },

/***/ 1070:
/***/ function(module, exports) {

	module.exports = "<div gogo-test=\"video\">\n  <div class=\"campaignVideo-overlay\"\n    ng-if=\"overlayUrl\"\n    style=\"background-image: url({{overlayUrl}});\"\n    ng-class=\"[{'hidden--animated': overlayHidden}, 'campaignVideo-overlay--' + type ]\"\n    ng-click=\"overlayClicked()\"\n    gogo-test=\"overlay\">\n    <a class=\"campaignVideo-play\">\n      <svg><use xlink:href=\"#play\"></use></svg>\n    </a>\n  </div>\n\n  <!-- the YouTube API replaces the following div with an iframe -->\n  <div id=\"campaignVideo-youtube\" class=\"campaignVideo-youtube\" ng-if=\"type === 'youtube'\"></div>\n\n  <iframe\n    id=\"vimeoPlayer\"\n    class=\"campaignVideo-vimeo\"\n    src=\"{{vimeo_video_url}}\"\n    width=\"100%\"\n    frameborder=\"0\"\n    webkitallowfullscreen\n    mozallowfullscreen\n    allowfullscreen\n    ng-if=\"type === 'vimeo'\">\n  </iframe>\n</div>\n";

/***/ },

/***/ 1071:
/***/ function(module, exports) {

	'use strict';
	
	campaignVideoYoutubeAutoplay.$inject = ["$timeout", "youtube", "campaign", "campaignAnalyticsService"];
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	exports.default = campaignVideoYoutubeAutoplay;
	/* global YT */
	/*@ngInject*/
	function campaignVideoYoutubeAutoplay($timeout, youtube, campaign, campaignAnalyticsService) {
	  return {
	    restrict: 'E',
	    scope: {},
	    template: '\n      <div gogo-test="video_autoplay">\n        <div id="campaignVideo-youtube--autoplay" class="campaignVideo-youtube"></div>\n      </div>\n    ',
	    link: function link() {
	      var VIDEO_ID = 'campaignVideo-youtube--autoplay';
	      var player;
	      var initialPlayEventRecorded;
	
	      if (campaign.video_overlay_url) {
	        campaign.video_overlay_url = null;
	      }
	
	      youtube.onReady(function () {
	        $timeout(function () {
	          player = new YT.Player(VIDEO_ID, {
	            width: '100%',
	            height: '100%',
	            videoId: campaign.main_video_info.id,
	            playerVars: {
	              autoplay: 1,
	              rel: 0,
	              showinfo: 0,
	              modestbranding: 1,
	              fs: 0,
	              wmode: 'opaque'
	            },
	            events: {
	              onReady: onPlayerReady,
	              onStateChange: onStateChange
	            }
	          });
	        }, 0);
	      });
	
	      function onPlayerReady(event) {
	        event.target.playVideo();
	        player.mute();
	        campaignAnalyticsService.sendVideoAnalyticsEvent('campaign_page_video', 'Video Autoplay', {
	          theta_name: 'campaign.video/video.autoplay', player_type: 'youtube'
	        });
	      }
	
	      function onStateChange(event) {
	        switch (event.data) {
	          case YT.PlayerState.UNSTARTED:
	            break;
	          case YT.PlayerState.PLAYING:
	            recordPlayEvent();
	            break;
	          case YT.PlayerState.ENDED:
	            campaignAnalyticsService.sendVideoAnalyticsEvent('campaign_page_video', 'Video Finished', {
	              theta_name: 'campaign.video/video.finish', player_type: 'youtube'
	            });
	            break;
	          case YT.PlayerState.PAUSED:
	            campaignAnalyticsService.sendVideoAnalyticsEvent('campaign_page_video', 'Video Paused', {
	              theta_name: 'campaign.video/video.pause', player_type: 'youtube'
	            });
	            break;
	        }
	      }
	
	      function recordPlayEvent() {
	        if (initialPlayEventRecorded) {
	          campaignAnalyticsService.sendVideoAnalyticsEvent('campaign_page_video', 'Video Resumed', {
	            theta_name: 'campaign.video/video.resume', player_type: 'youtube'
	          });
	        } else {
	          initialPlayEventRecorded = true;
	          campaignAnalyticsService.sendVideoAnalyticsEvent('campaign_page_video', 'Video Playing', {
	            theta_name: 'campaign.video/video.playing', player_type: 'youtube'
	          });
	        }
	      }
	    }
	  };
	}

/***/ },

/***/ 1078:
/***/ function(module, exports) {

	'use strict';
	
	campaignGoalService.$inject = ["i18n", "campaign", "$filter", "$sce", "browser"];
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	exports.default = campaignGoalService;
	/* jshint expr: true */
	/*@ngInject*/
	function campaignGoalService(i18n, campaign, $filter, $sce, browser) {
	  return {
	    showsTechDesignRestyled: function showsTechDesignRestyled() {
	      return campaign.isTechDesignEligible() && browser.isTabletPlus();
	    },
	    fundingBlurb: function fundingBlurb() {
	      var goalReached = campaign.collected_funds >= campaign.goal;
	
	      if (campaign.state() === campaign.states.ended && goalReached) {
	        return i18n.t('flex_or_fixed_hit_goal_expired_blurb');
	      }
	
	      if (campaign.state() === campaign.states.ended) {
	        // Goal is not reached
	        if (campaign.funding_type === 'fixed') {
	          return i18n.t('fixed_didnt_hit_goal_expired_blurb', {
	            agent_show_goal: $filter('iggCurrency')(campaign.goal, campaign.currency.iso_num, null)
	          });
	        } else if (campaign.funding_type === 'flexible') {
	          return i18n.t('flex_or_fixed_hit_goal_expired_blurb');
	        }
	      } else {
	        if (campaign.funding_type === 'fixed') {
	          if (goalReached) {
	            return i18n.t('fixed_campaign_hit_goal_still_funding_blurb');
	          } else {
	            return i18n.t('fixed_still_funding_hasnt_hit_goal_blurb', {
	              agent_show_goal: $filter('iggCurrency')(campaign.goal, campaign.currency.iso_num, null)
	            });
	          }
	        } else if (campaign.funding_type === 'flexible') {
	          return i18n.t('flex_campaign_still_funding_blurb');
	        }
	      }
	    },
	    fundingType: function fundingType() {
	      return {
	        fixed: i18n.t("fixed_funding"),
	        flexible: i18n.t("flexible_funding")
	      }[campaign.funding_type];
	    },
	    fundingTypeGoalString: function fundingTypeGoalString() {
	      return {
	        fixed: i18n.t("fixed_goal"),
	        flexible: i18n.t("flexible_goal")
	      }[campaign.funding_type];
	    },
	    onDateText: function onDateText(date) {
	      var formattedDate = $filter('date')(date, 'MMMM d, yyyy');
	      return i18n.t('on_date', { date: formattedDate });
	    },
	    stringForNumberOfFunders: function stringForNumberOfFunders() {
	      return campaign.contributions_count == 1 ? i18n.t("project_card.backer") : i18n.t("project_card.backers");
	    },
	    fundsDaysRemaining: function fundsDaysRemaining() {
	      var timeDiff = moment(campaign.funding_ends_at).diff();
	      var timeRemaining = moment.duration(timeDiff);
	
	      function remainingText() {
	        if (i18n.locale === 'en') {
	          return '&nbsp;left';
	        } else {
	          return '';
	        }
	      }
	
	      if (timeDiff < 0) {
	        return i18n.t('no_time_left_html');
	      } else {
	        return $sce.trustAsHtml(timeRemaining.humanize().replace(/(\d+)/, function (match, $1) {
	          return '<em>' + $1 + '</em>';
	        }) + remainingText());
	      }
	    },
	    percentFunded: function percentFunded() {
	      return campaign.goal === 0 ? 0 : campaign.collected_funds / campaign.goal * 100;
	    },
	    percentFundedString: function percentFundedString() {
	      return $filter('number')(this.percentFunded(), 0) + '%';
	    },
	    percentFundedHtml: function percentFundedHtml() {
	      return $sce.trustAsHtml('<em>' + this.percentFundedString() + '</em> ' + i18n.t('funded'));
	    },
	    progressBarWidth: function progressBarWidth() {
	      var percent = this.percentFunded();
	      if (0 < percent && percent < 5) {
	        return 2;
	      } else {
	        var nearest_5_percent = Math.floor(percent / 5) * 5;
	        return Math.min(100, nearest_5_percent);
	      }
	    },
	    foreverFundingBlurb: function foreverFundingBlurb() {
	      var blurb;
	      if (campaign.is_external_campaign) {
	        var display_end_date = new Date(campaign.external_campaign_info.external_end_date);
	
	        blurb = i18n.t("funded_on_another_platform_on", {
	          "date": $filter('date')(display_end_date, 'MMMM d, yyyy')
	        });
	      } else {
	        blurb = i18n.t("percent_funded_on_end_date", {
	          "percent": this.percentFundedString(),
	          "end_date": $filter('date')(campaign.funding_ends_at, 'MMMM D, yyyy')
	        });
	      }
	      return blurb;
	    }
	  };
	}

/***/ },

/***/ 1088:
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	
	campaignPitchmedia.$inject = ["campaign", "gon"];
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	exports.default = campaignPitchmedia;
	/*@ngInject*/
	function campaignPitchmedia(campaign, gon) {
	  return {
	    restrict: 'E',
	    scope: {},
	    transclude: false,
	    replace: false,
	    template: __webpack_require__(1089),
	    link: function link(scope) {
	      scope.campaign = campaign;
	      scope.campaign_pitch_image = gon.urls.pitch_image_url || "";
	      scope.showYoutubeAutoplay = function () {
	        return campaign.main_video_info.type === 'youtube';
	      };
	      scope.showDefaultVideo = function () {
	        return !scope.showYoutubeAutoplay();
	      };
	    }
	  };
	}

/***/ },

/***/ 1089:
/***/ function(module, exports) {

	module.exports = "<div ng-if=\"campaign.main_video_info.type\">\n  <split experiment=\"campaign_video\" variant=\"control\">\n    <campaign-video\n      type=\"{{campaign.main_video_info.type}}\"\n      id=\"{{campaign.main_video_info.id}}\"\n      overlay_url=\"{{campaign.video_overlay_url}}\"\n      class=\"campaignVideo\">\n    </campaign-video>\n  </split>\n  <split experiment=\"campaign_video\" variant=\"experiment_autoplay\">\n    <campaign-video-youtube-autoplay\n      ng-if=\"showYoutubeAutoplay()\">\n    </campaign-video-youtube-autoplay>\n    <campaign-video\n      ng-if=\"showDefaultVideo()\"\n      type=\"{{campaign.main_video_info.type}}\"\n      id=\"{{campaign.main_video_info.id}}\"\n      overlay_url=\"{{campaign.video_overlay_url}}\"\n      class=\"campaignVideo\">\n    </campaign-video>\n  </split>\n</div>\n\n<img class=\"campaignPitchMedia-image\" ng-src=\"{{campaign_pitch_image}}\" ng-if=\"!campaign.main_video_info.type && campaign_pitch_image\">\n";

/***/ },

/***/ 1090:
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	
	campaignTags.$inject = ["gon", "i18n", "campaign", "$window"];
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	exports.default = campaignTags;
	/*@ngInject*/
	function campaignTags(gon, i18n, campaign, $window) {
	  return {
	    restrict: 'E',
	    scope: {},
	    template: __webpack_require__(1091),
	    link: function link(scope) {
	      scope.i18n = i18n;
	      scope.campaign = campaign;
	      scope.tagLink = function (tag) {
	        return '/search#/?q=' + $window.escape('#' + tag);
	      };
	    }
	  };
	}

/***/ },

/***/ 1091:
/***/ function(module, exports) {

	module.exports = "<a class=\"campaignTag\" ng-repeat=\"tag in campaign.non_blacklisted_tags\" href=\"{{tagLink(tag)}}\">\n  #{{tag}}\n</a>\n";

/***/ },

/***/ 1092:
/***/ function(module, exports) {

	"use strict";
	
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	
	exports.default = function () {
	  return {
	    link: function link(_, el) {
	      return el.fadeOut(500, el.remove);
	    }
	  };
	};

/***/ },

/***/ 1093:
/***/ function(module, exports) {

	'use strict';
	
	campaignAnalyticsService.$inject = ["gogoEvents", "browser", "campaign", "gon"];
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	exports.default = campaignAnalyticsService;
	/* jshint expr: true */
	/*@ngInject*/
	function campaignAnalyticsService(gogoEvents, browser, campaign, gon) {
	  return {
	    campaignType: function campaignType() {
	      return !!campaign.forever_funding_active ? 'indemand' : 'campaign';
	    },
	
	    defaultAnalyticsAttrs: function defaultAnalyticsAttrs() {
	      return {
	        screenBreakpoint: browser.getDevicefromScreenSize(),
	        projectCategory: campaign.category_name ? campaign.category_name.toLowerCase() : '',
	        projectId: campaign.project_id,
	        accountId: _.get(gon, 'user.id') || null,
	        inDemand: campaign.forever_funding_active
	      };
	    },
	    // TODO EVENTS: id=navid005 fixtype=safega+captureEvent subsystem=??? category=campaign_page_video action=[Video Paused, Video Resumed, Video Playing, Play Video, Video Finished, Video Autoplay] name=campaign_page_* .
	    sendVideoAnalyticsEvent: function sendVideoAnalyticsEvent(ga_category, ga_action, attributes) {
	      // example:
	      // ga_action = 'Video Paused'
	      // ga_category = 'campaign_page_video'
	      // thetaName = 'Video Paused'
	      // in doc 'event_type' == 'thetaName'
	      var eventAttrs = {
	        thetaName: attributes.theta_name,
	        gaEventCategory: ga_category,
	        gaEventAction: ga_action,
	        gaEventLabel: attributes.player_type
	      };
	      return gogoEvents.track(_.merge(eventAttrs, this.defaultAnalyticsAttrs()));
	    },
	
	    // TODO EVENTS: id=navid006 fixtype=safega+captureEvent subsystem=??? category=campaign_page_share action=[] name=campaign_page_share_*
	    sendShareEvent: function sendShareEvent(gaAttrs, thetaAttrs) {
	      var defaultAttrs = this.defaultAnalyticsAttrs();
	      var eventAttrs = {
	        thetaName: thetaAttrs.thetaName,
	        gaEventCategory: gaAttrs.gaEventCategory,
	        gaEventAction: gaAttrs.gaEventAction,
	        gaEventLabel: this.campaignType() + '_' + defaultAttrs.projectCategory
	      };
	      return gogoEvents.track(_.merge(eventAttrs, defaultAttrs));
	    },
	
	    // TODO EVENTS: id=navid007 fixtype=safega+captureEvent subsystem=??? category=campaign_page_contribute action=[] name=campaign/perk.click|contribute.click
	    sendPerkEvent: function sendPerkEvent(gaAttrs, thetaAttrs) {
	      var defaultAttrs = this.defaultAnalyticsAttrs();
	      var eventAttrs = {
	        thetaName: thetaAttrs.thetaName,
	        gaEventCategory: gaAttrs.gaEventCategory,
	        gaEventAction: gaAttrs.gaEventAction,
	        gaEventLabel: this.campaignType() + '_' + defaultAttrs.projectCategory,
	        perkId: thetaAttrs.perkId,
	        isSecret: thetaAttrs.isSecret,
	        isFeatured: thetaAttrs.isFeatured,
	        hasShipping: thetaAttrs.hasShipping
	      };
	      return gogoEvents.track(_.merge(eventAttrs, defaultAttrs));
	    },
	
	    // TODO EVENTS: id=Fd6nGB fixtype=safega+captureEvent name=campaign_page_show category=campaign_page_discovery action=collection_badge subsystem=campaign-page . review
	    sendOnCampaignLoadEvent: function sendOnCampaignLoadEvent(gaAttrs, thetaAttrs) {
	      var defaultAttrs = this.defaultAnalyticsAttrs();
	      var eventAttrs = {
	        thetaName: thetaAttrs.thetaName,
	        gaEventCategory: gaAttrs.gaEventCategory,
	        gaEventAction: gaAttrs.gaEventAction,
	        inCollection: thetaAttrs.inCollection,
	        videoType: thetaAttrs.videoType
	      };
	      return gogoEvents.track(_.merge(eventAttrs, defaultAttrs));
	    }
	  };
	}

/***/ },

/***/ 1102:
/***/ function(module, exports) {

	module.exports = "<div class=\"modal i-modal i-embed-lightbox\">\n  <div class=\"modal-dialog i-modal-wider\">\n    <div class=\"modal-content\">\n      <a class=\"modal-close\" ng-click=\"$hide()\" aria-hidden=\"true\"><svg><use xlink:href=\"#icon-icon-close\"></use></svg></a>\n      <div class=\"row\">\n        <div class=\"col-sm-8\">\n          <h3>{{ i18n.t('widget_embed.embed_this_card_in_your_website_or_blog') }}</h3>\n\n          <p>{{ i18n.t('widget_embed.copy_code_below') }}</p>\n          <textarea class=\"i-code-text\" readonly=\"true\" ng-click=\"selectTextarea()\" rows=\"8\">{{iframeString}}</textarea>\n        </div>\n        <div class=\"col-sm-4\" ng-bind-html=\"projectCardHtml\">\n        </div>\n      </div>\n    </div>\n  </div>\n</div>\n";

/***/ },

/***/ 1113:
/***/ function(module, exports) {

	'use strict';
	
	/* jshint expr: true */
	function campaignService($sce, $http, gon, i18n) {
	
	  var formatLocation = function formatLocation(campaign) {
	    var locationArray = [];
	    if (campaign.city) {
	      locationArray.push(campaign.city);
	    }
	    if (campaign.region) {
	      locationArray.push(campaign.region);
	    }
	    if (campaign.country) {
	      locationArray.push(campaign.country);
	    }
	
	    return locationArray.join(", ");
	  };
	
	  var postFollow = function postFollow(self, followUrl, newFollowState, callback) {
	    $http.post(followUrl, { params: {} }).success(function (data, status, headers, config) {
	      self.followed = newFollowState;
	      if (callback) callback(null);
	    }).error(function (data, status, headers, config) {
	      //TODO: Handle Error
	      if (callback) callback(status);
	    });
	  };
	
	  return {
	    id: null,
	    title: null,
	    image_types: null,
	    tagline: null,
	    category: null,
	    created_at: null,
	    updated_at: null,
	    funding_ends_at: null,
	    forever_funding_ends_at: null,
	    currency: null,
	    collected_funds: null,
	    external_campaign_info: null,
	    forever_funding_collected_funds: null,
	    forever_funding_combined_balance: null,
	    overview: null,
	    overview_image_url: null,
	    product_stage: null,
	    goal: null,
	    funding_type: null,
	    forever_funding_active: null,
	    funding_invalid_yet_live: false,
	    gallery_available: false,
	    perks_available: null,
	    location: null,
	    city: null,
	    description_html: null,
	    contributions_count: null,
	    comments_count: null,
	    updates_count: null,
	    followed: false,
	    main_video_info: {
	      type: null,
	      id: null,
	      thumbnail_url: null
	    },
	    video_overlay_url: null,
	    team_members: [],
	    perks: [],
	    facebook_friend_contributors: [],
	    partner_connected: false,
	    partner: {
	      visible: null,
	      name: null,
	      path: null,
	      square_logo_image_url: null,
	      square_logo_missing_image_url: null
	    },
	    partner_name: null,
	    partner_campaign_page_description: null,
	    partner_image_url: null,
	    nonprofit: false,
	    nonprofit_campaign_page_description: null,
	    affiliated_with_nonprofit: false,
	    status: null,
	    is_pre_order_campaign: null,
	    all_funding_expired: null,
	    visible: false,
	    project_id: null,
	    category_name: null,
	    collection: null,
	    project_sponsors: [],
	    setCampaignJson: function setCampaignJson(newCampaign) {
	      this.id = newCampaign.id;
	      this.external_campaign_info = newCampaign.external_campaign_info;
	      this.is_external_campaign = newCampaign.is_external_campaign;
	      this.title = newCampaign.title;
	      this.image_types = newCampaign.image_types;
	      this.tagline = newCampaign.tagline;
	      this.category = newCampaign.category && newCampaign.category.slug ? i18n.t(newCampaign.category.slug) : null;
	      this.created_at = new Date(newCampaign.created_at);
	      this.updated_at = new Date(newCampaign.updated_at);
	      this.funding_started_at = new Date(newCampaign.funding_started_at), this.funding_ends_at = newCampaign.funding_ends_at ? new Date(newCampaign.funding_ends_at) : null;
	      this.forever_funding_ends_at = newCampaign.forever_funding_ends_at ? new Date(newCampaign.forever_funding_ends_at) : null;
	      this.gallery_available = newCampaign.gallery_available;
	      this.overview = newCampaign.overview;
	      this.overview_image_url = newCampaign.overview_image_url;
	      this.product_stage = newCampaign.product_stage;
	      this.location = formatLocation(newCampaign);
	      this.city = newCampaign.city;
	      this.currency = newCampaign.currency;
	      this.collected_funds = newCampaign.collected_funds;
	      this.forever_funding_collected_funds = newCampaign.forever_funding_collected_funds;
	      this.forever_funding_combined_balance = newCampaign.forever_funding_combined_balance;
	      this.goal = newCampaign.goal;
	      this.funding_type = newCampaign.funding_type;
	      this.forever_funding_active = newCampaign.forever_funding_active;
	      this.funding_invalid_yet_live = newCampaign.funding_invalid_yet_live;
	      this.perks_available = newCampaign.perks_available;
	      this.description_html = $sce.trustAsHtml(newCampaign.description_html);
	      this.contributions_count = newCampaign.contributions_count;
	      this.comments_count = newCampaign.comments_count;
	      this.updates_count = newCampaign.updates_count;
	      this.main_video_info = newCampaign.main_video_info;
	      this.video_overlay_url = newCampaign.video_overlay_url;
	      this.facebook_friend_contributors = newCampaign.facebook_friend_contributors;
	      this.team_members = newCampaign.team_members;
	      this.perks = newCampaign.perks;
	      this.tag_list = newCampaign.tag_list;
	      this.non_blacklisted_tags = newCampaign.non_blacklisted_tags;
	      this.partner_connected = !!newCampaign.partner;
	      if (this.partner_connected) {
	        this.partner.visible = newCampaign.partner.visible;
	        this.partner.name = newCampaign.partner.name;
	        this.partner.path = newCampaign.partner.path;
	        this.partner.square_logo_image_url = newCampaign.partner.square_logo_image_url;
	        this.partner.square_logo_missing_image_url = newCampaign.partner.square_logo_missing_image_url;
	      }
	      this.partner_name = newCampaign.partner_name;
	      this.nonprofit = newCampaign.nonprofit;
	      this.status = newCampaign.status;
	      this.is_pre_order_campaign = newCampaign.is_pre_order_campaign;
	      this.is_shipping_now_campaign = newCampaign.is_shipping_now_campaign;
	      this.category_slug = newCampaign.category && newCampaign.category.slug || null;
	      this.category_icon_name = newCampaign.category && newCampaign.category.icon_name || null;
	      this.all_funding_expired = newCampaign.all_funding_expired;
	      this.visible = newCampaign.visible;
	      this.project_id = newCampaign.id;
	      if (newCampaign.category) {
	        this.category_name = newCampaign.category.name;
	      }
	      this.collection = newCampaign.collection;
	      this.project_sponsors = newCampaign.project_sponsors;
	    },
	    follow: function follow(callback) {
	      var newFollowState = true;
	      postFollow(this, gon.urls.campaign_follow_path, newFollowState, callback);
	    },
	    unfollow: function unfollow(callback) {
	      var newFollowState = false;
	      postFollow(this, gon.urls.campaign_unfollow_path, newFollowState, callback);
	    },
	    states: {
	      unknown: -1,
	      draft: 0,
	      published: 1,
	      ended: 2,
	      inDemand: 3,
	      inDemandEnded: 4
	    },
	    state: function state() {
	      if (this.status === 'draft') {
	        return this.states.draft;
	      } else if (this.status === 'published') {
	        if (this.forever_funding_active) {
	          return this.states.inDemand;
	        } else {
	          return this.states.published;
	        }
	      } else if (this.status === 'ended') {
	        if (this.forever_funding_ends_at) {
	          return this.states.inDemandEnded;
	        } else {
	          return this.states.ended;
	        }
	      }
	
	      return this.states.unknown;
	    },
	    isPublished: function isPublished() {
	      return this.status === 'published';
	    },
	    isEnded: function isEnded() {
	      return this.status === 'ended';
	    },
	    isInDemand: function isInDemand() {
	      return this.state() === this.states.inDemand || this.state() === this.states.inDemandEnded;
	    },
	    isTechDesignEligible: function isTechDesignEligible() {
	      return !this.isInDemand() && this.perks_available && /technology|design/.test(this.category_slug) && this.status !== 'ended';
	    },
	    sponsorsWhereLevelGreaterThan: function sponsorsWhereLevelGreaterThan(levelValue) {
	      var projectSponsors = _.filter(this.project_sponsors, function (pep) {
	        return pep.level.identifier > levelValue;
	      });
	      return _.map(projectSponsors, 'sponsor');
	    }
	  };
	}
	
	module.exports = ['$sce', '$http', 'gon', 'i18n', campaignService];

/***/ },

/***/ 1114:
/***/ function(module, exports) {

	'use strict';
	
	function trustPassportService(gon) {
	
	  var trust_passport = _.clone(gon.trust_passport);
	  var project = _.clone(trust_passport.project);
	  var owner = _.clone(trust_passport.owner);
	  var otherTeamMembers = _.reject(project.team_members, function (teamMember) {
	    return teamMember.is_owner;
	  });
	  var loggedIn = _.clone(gon.logged_in);
	  var loginUrl = _.clone(gon.login_url);
	
	  var idVerifiedEnabled = trust_passport.identity_verified_enabled;
	  var verifications = getVerifications(owner, idVerifiedEnabled);
	  var hasCampaigns = owner.campaigns_count > 0;
	  var hasComments = owner.comments_count > 0;
	  var hasContributions = owner.contributions_count > 0;
	  var hasImpacts = hasCampaigns || hasComments || hasContributions;
	  var hasVerifications = accountHasAnyVerifications(owner);
	
	  var recaptchaIdsReady = {};
	
	  var urlMatcher = new RegExp('https?://(?:www.)?(.*)');
	  var websites = _.map(project.websites, function (url) {
	    return {
	      url: url,
	      text: urlMatcher.exec(url)[1]
	    };
	  });
	
	  function accountHasAnyVerifications(account) {
	    return account.email_verified || account.facebook_verified || account.linkedin_verified || account.admin_verified;
	  }
	
	  function getVerifications(teamMember, idVerifiedEnabled) {
	    var verifications = [teamMember.email_verified, teamMember.facebook_verified, teamMember.linkedin_verified];
	
	    if (idVerifiedEnabled) {
	      verifications.push(teamMember.admin_verified);
	    }
	
	    return verifications;
	  }
	
	  return {
	    project: project,
	    owner: owner,
	    loggedIn: loggedIn,
	    loginUrl: loginUrl,
	    idVerifiedEnabled: idVerifiedEnabled,
	    verifications: verifications,
	    hasCampaigns: hasCampaigns,
	    hasComments: hasComments,
	    hasContributions: hasContributions,
	    hasImpacts: hasImpacts,
	    hasVerifications: hasVerifications,
	    otherTeamMembers: otherTeamMembers,
	    grecaptchaSiteKey: trust_passport.grecaptcha_site_key,
	    contactOwnerEndpointUrl: trust_passport.contact_owner_endpoint_url,
	    registerRecaptchaId: function registerRecaptchaId(id) {
	      recaptchaIdsReady[id] = true;
	    },
	    isRecaptchaReadyForId: function isRecaptchaReadyForId(id) {
	      if (_.isUndefined(id)) {
	        return false;
	      }
	      return recaptchaIdsReady[id];
	    },
	    websites: websites,
	    accountHasAnyVerifications: accountHasAnyVerifications,
	    getVerificationsForTeamMember: getVerifications
	  };
	}
	
	module.exports = ['gon', trustPassportService];

/***/ },

/***/ 1181:
/***/ function(module, exports, __webpack_require__) {

	"use strict";
	
	var pusher = __webpack_require__(1182);
	module.exports = pusher;

/***/ },

/***/ 1182:
/***/ function(module, exports) {

	/*** IMPORTS FROM imports-loader ***/
	(function() {
	
	/*!
	 * Pusher JavaScript Library v2.2.4
	 * http://pusher.com/
	 *
	 * Copyright 2014, Pusher
	 * Released under the MIT licence.
	 */
	
	;(function() {
	  function Pusher(app_key, options) {
	    checkAppKey(app_key);
	    options = options || {};
	
	    var self = this;
	
	    this.key = app_key;
	    this.config = Pusher.Util.extend(
	      Pusher.getGlobalConfig(),
	      options.cluster ? Pusher.getClusterConfig(options.cluster) : {},
	      options
	    );
	
	    this.channels = new Pusher.Channels();
	    this.global_emitter = new Pusher.EventsDispatcher();
	    this.sessionID = Math.floor(Math.random() * 1000000000);
	
	    this.timeline = new Pusher.Timeline(this.key, this.sessionID, {
	      cluster: this.config.cluster,
	      features: Pusher.Util.getClientFeatures(),
	      params: this.config.timelineParams || {},
	      limit: 50,
	      level: Pusher.Timeline.INFO,
	      version: Pusher.VERSION
	    });
	    if (!this.config.disableStats) {
	      this.timelineSender = new Pusher.TimelineSender(this.timeline, {
	        host: this.config.statsHost,
	        path: "/timeline/v2/jsonp"
	      });
	    }
	
	    var getStrategy = function(options) {
	      var config = Pusher.Util.extend({}, self.config, options);
	      return Pusher.StrategyBuilder.build(
	        Pusher.getDefaultStrategy(config), config
	      );
	    };
	
	    this.connection = new Pusher.ConnectionManager(
	      this.key,
	      Pusher.Util.extend(
	        { getStrategy: getStrategy,
	          timeline: this.timeline,
	          activityTimeout: this.config.activity_timeout,
	          pongTimeout: this.config.pong_timeout,
	          unavailableTimeout: this.config.unavailable_timeout
	        },
	        this.config,
	        { encrypted: this.isEncrypted() }
	      )
	    );
	
	    this.connection.bind('connected', function() {
	      self.subscribeAll();
	      if (self.timelineSender) {
	        self.timelineSender.send(self.connection.isEncrypted());
	      }
	    });
	    this.connection.bind('message', function(params) {
	      var internal = (params.event.indexOf('pusher_internal:') === 0);
	      if (params.channel) {
	        var channel = self.channel(params.channel);
	        if (channel) {
	          channel.handleEvent(params.event, params.data);
	        }
	      }
	      // Emit globaly [deprecated]
	      if (!internal) {
	        self.global_emitter.emit(params.event, params.data);
	      }
	    });
	    this.connection.bind('disconnected', function() {
	      self.channels.disconnect();
	    });
	    this.connection.bind('error', function(err) {
	      Pusher.warn('Error', err);
	    });
	
	    Pusher.instances.push(this);
	    this.timeline.info({ instances: Pusher.instances.length });
	
	    if (Pusher.isReady) {
	      self.connect();
	    }
	  }
	  var prototype = Pusher.prototype;
	
	  Pusher.instances = [];
	  Pusher.isReady = false;
	
	  // To receive log output provide a Pusher.log function, for example
	  // Pusher.log = function(m){console.log(m)}
	  Pusher.debug = function() {
	    if (!Pusher.log) {
	      return;
	    }
	    Pusher.log(Pusher.Util.stringify.apply(this, arguments));
	  };
	
	  Pusher.warn = function() {
	    var message = Pusher.Util.stringify.apply(this, arguments);
	    if (window.console) {
	      if (window.console.warn) {
	        window.console.warn(message);
	      } else if (window.console.log) {
	        window.console.log(message);
	      }
	    }
	    if (Pusher.log) {
	      Pusher.log(message);
	    }
	  };
	
	  Pusher.ready = function() {
	    Pusher.isReady = true;
	    for (var i = 0, l = Pusher.instances.length; i < l; i++) {
	      Pusher.instances[i].connect();
	    }
	  };
	
	  prototype.channel = function(name) {
	    return this.channels.find(name);
	  };
	
	  prototype.allChannels = function() {
	    return this.channels.all();
	  };
	
	  prototype.connect = function() {
	    this.connection.connect();
	
	    if (this.timelineSender) {
	      if (!this.timelineSenderTimer) {
	        var encrypted = this.connection.isEncrypted();
	        var timelineSender = this.timelineSender;
	        this.timelineSenderTimer = new Pusher.PeriodicTimer(60000, function() {
	          timelineSender.send(encrypted);
	        });
	      }
	    }
	  };
	
	  prototype.disconnect = function() {
	    this.connection.disconnect();
	
	    if (this.timelineSenderTimer) {
	      this.timelineSenderTimer.ensureAborted();
	      this.timelineSenderTimer = null;
	    }
	  };
	
	  prototype.bind = function(event_name, callback) {
	    this.global_emitter.bind(event_name, callback);
	    return this;
	  };
	
	  prototype.bind_all = function(callback) {
	    this.global_emitter.bind_all(callback);
	    return this;
	  };
	
	  prototype.subscribeAll = function() {
	    var channelName;
	    for (channelName in this.channels.channels) {
	      if (this.channels.channels.hasOwnProperty(channelName)) {
	        this.subscribe(channelName);
	      }
	    }
	  };
	
	  prototype.subscribe = function(channel_name) {
	    var channel = this.channels.add(channel_name, this);
	    if (this.connection.state === 'connected') {
	      channel.subscribe();
	    }
	    return channel;
	  };
	
	  prototype.unsubscribe = function(channel_name) {
	    var channel = this.channels.remove(channel_name);
	    if (this.connection.state === 'connected') {
	      channel.unsubscribe();
	    }
	  };
	
	  prototype.send_event = function(event_name, data, channel) {
	    return this.connection.send_event(event_name, data, channel);
	  };
	
	  prototype.isEncrypted = function() {
	    if (Pusher.Util.getDocument().location.protocol === "https:") {
	      return true;
	    } else {
	      return Boolean(this.config.encrypted);
	    }
	  };
	
	  function checkAppKey(key) {
	    if (key === null || key === undefined) {
	      Pusher.warn(
	        'Warning', 'You must pass your app key when you instantiate Pusher.'
	      );
	    }
	  }
	
	  Pusher.HTTP = {};
	
	  this.Pusher = Pusher;
	}).call(this);
	
	;(function() {
	  // We need to bind clear functions this way to avoid exceptions on IE8
	  function clearTimeout(timer) {
	    window.clearTimeout(timer);
	  }
	  function clearInterval(timer) {
	    window.clearInterval(timer);
	  }
	
	  function GenericTimer(set, clear, delay, callback) {
	    var self = this;
	
	    this.clear = clear;
	    this.timer = set(function() {
	      if (self.timer !== null) {
	        self.timer = callback(self.timer);
	      }
	    }, delay);
	  }
	  var prototype = GenericTimer.prototype;
	
	  /** Returns whether the timer is still running.
	   *
	   * @return {Boolean}
	   */
	  prototype.isRunning = function() {
	    return this.timer !== null;
	  };
	
	  /** Aborts a timer when it's running. */
	  prototype.ensureAborted = function() {
	    if (this.timer) {
	      // Clear function is already bound
	      this.clear(this.timer);
	      this.timer = null;
	    }
	  };
	
	  /** Cross-browser compatible one-off timer abstraction.
	   *
	   * @param {Number} delay
	   * @param {Function} callback
	   */
	  Pusher.Timer = function(delay, callback) {
	    return new GenericTimer(setTimeout, clearTimeout, delay, function(timer) {
	      callback();
	      return null;
	    });
	  };
	  /** Cross-browser compatible periodic timer abstraction.
	   *
	   * @param {Number} delay
	   * @param {Function} callback
	   */
	  Pusher.PeriodicTimer = function(delay, callback) {
	    return new GenericTimer(setInterval, clearInterval, delay, function(timer) {
	      callback();
	      return timer;
	    });
	  };
	}).call(this);
	
	;(function() {
	  Pusher.Util = {
	    now: function() {
	      if (Date.now) {
	        return Date.now();
	      } else {
	        return new Date().valueOf();
	      }
	    },
	
	    defer: function(callback) {
	      return new Pusher.Timer(0, callback);
	    },
	
	    /** Merges multiple objects into the target argument.
	     *
	     * For properties that are plain Objects, performs a deep-merge. For the
	     * rest it just copies the value of the property.
	     *
	     * To extend prototypes use it as following:
	     *   Pusher.Util.extend(Target.prototype, Base.prototype)
	     *
	     * You can also use it to merge objects without altering them:
	     *   Pusher.Util.extend({}, object1, object2)
	     *
	     * @param  {Object} target
	     * @return {Object} the target argument
	     */
	    extend: function(target) {
	      for (var i = 1; i < arguments.length; i++) {
	        var extensions = arguments[i];
	        for (var property in extensions) {
	          if (extensions[property] && extensions[property].constructor &&
	              extensions[property].constructor === Object) {
	            target[property] = Pusher.Util.extend(
	              target[property] || {}, extensions[property]
	            );
	          } else {
	            target[property] = extensions[property];
	          }
	        }
	      }
	      return target;
	    },
	
	    stringify: function() {
	      var m = ["Pusher"];
	      for (var i = 0; i < arguments.length; i++) {
	        if (typeof arguments[i] === "string") {
	          m.push(arguments[i]);
	        } else {
	          if (window.JSON === undefined) {
	            m.push(arguments[i].toString());
	          } else {
	            m.push(JSON.stringify(arguments[i]));
	          }
	        }
	      }
	      return m.join(" : ");
	    },
	
	    arrayIndexOf: function(array, item) { // MSIE doesn't have array.indexOf
	      var nativeIndexOf = Array.prototype.indexOf;
	      if (array === null) {
	        return -1;
	      }
	      if (nativeIndexOf && array.indexOf === nativeIndexOf) {
	        return array.indexOf(item);
	      }
	      for (var i = 0, l = array.length; i < l; i++) {
	        if (array[i] === item) {
	          return i;
	        }
	      }
	      return -1;
	    },
	
	    /** Applies a function f to all properties of an object.
	     *
	     * Function f gets 3 arguments passed:
	     * - element from the object
	     * - key of the element
	     * - reference to the object
	     *
	     * @param {Object} object
	     * @param {Function} f
	     */
	    objectApply: function(object, f) {
	      for (var key in object) {
	        if (Object.prototype.hasOwnProperty.call(object, key)) {
	          f(object[key], key, object);
	        }
	      }
	    },
	
	    /** Return a list of object's own property keys
	     *
	     * @param {Object} object
	     * @returns {Array}
	     */
	    keys: function(object) {
	      var keys = [];
	      Pusher.Util.objectApply(object, function(_, key) {
	        keys.push(key);
	      });
	      return keys;
	    },
	
	    /** Return a list of object's own property values
	     *
	     * @param {Object} object
	     * @returns {Array}
	     */
	    values: function(object) {
	      var values = [];
	      Pusher.Util.objectApply(object, function(value) {
	        values.push(value);
	      });
	      return values;
	    },
	
	    /** Applies a function f to all elements of an array.
	     *
	     * Function f gets 3 arguments passed:
	     * - element from the array
	     * - index of the element
	     * - reference to the array
	     *
	     * @param {Array} array
	     * @param {Function} f
	     */
	    apply: function(array, f, context) {
	      for (var i = 0; i < array.length; i++) {
	        f.call(context || window, array[i], i, array);
	      }
	    },
	
	    /** Maps all elements of the array and returns the result.
	     *
	     * Function f gets 4 arguments passed:
	     * - element from the array
	     * - index of the element
	     * - reference to the source array
	     * - reference to the destination array
	     *
	     * @param {Array} array
	     * @param {Function} f
	     */
	    map: function(array, f) {
	      var result = [];
	      for (var i = 0; i < array.length; i++) {
	        result.push(f(array[i], i, array, result));
	      }
	      return result;
	    },
	
	    /** Maps all elements of the object and returns the result.
	     *
	     * Function f gets 4 arguments passed:
	     * - element from the object
	     * - key of the element
	     * - reference to the source object
	     * - reference to the destination object
	     *
	     * @param {Object} object
	     * @param {Function} f
	     */
	    mapObject: function(object, f) {
	      var result = {};
	      Pusher.Util.objectApply(object, function(value, key) {
	        result[key] = f(value);
	      });
	      return result;
	    },
	
	    /** Filters elements of the array using a test function.
	     *
	     * Function test gets 4 arguments passed:
	     * - element from the array
	     * - index of the element
	     * - reference to the source array
	     * - reference to the destination array
	     *
	     * @param {Array} array
	     * @param {Function} f
	     */
	    filter: function(array, test) {
	      test = test || function(value) { return !!value; };
	
	      var result = [];
	      for (var i = 0; i < array.length; i++) {
	        if (test(array[i], i, array, result)) {
	          result.push(array[i]);
	        }
	      }
	      return result;
	    },
	
	    /** Filters properties of the object using a test function.
	     *
	     * Function test gets 4 arguments passed:
	     * - element from the object
	     * - key of the element
	     * - reference to the source object
	     * - reference to the destination object
	     *
	     * @param {Object} object
	     * @param {Function} f
	     */
	    filterObject: function(object, test) {
	      var result = {};
	      Pusher.Util.objectApply(object, function(value, key) {
	        if ((test && test(value, key, object, result)) || Boolean(value)) {
	          result[key] = value;
	        }
	      });
	      return result;
	    },
	
	    /** Flattens an object into a two-dimensional array.
	     *
	     * @param  {Object} object
	     * @return {Array} resulting array of [key, value] pairs
	     */
	    flatten: function(object) {
	      var result = [];
	      Pusher.Util.objectApply(object, function(value, key) {
	        result.push([key, value]);
	      });
	      return result;
	    },
	
	    /** Checks whether any element of the array passes the test.
	     *
	     * Function test gets 3 arguments passed:
	     * - element from the array
	     * - index of the element
	     * - reference to the source array
	     *
	     * @param {Array} array
	     * @param {Function} f
	     */
	    any: function(array, test) {
	      for (var i = 0; i < array.length; i++) {
	        if (test(array[i], i, array)) {
	          return true;
	        }
	      }
	      return false;
	    },
	
	    /** Checks whether all elements of the array pass the test.
	     *
	     * Function test gets 3 arguments passed:
	     * - element from the array
	     * - index of the element
	     * - reference to the source array
	     *
	     * @param {Array} array
	     * @param {Function} f
	     */
	    all: function(array, test) {
	      for (var i = 0; i < array.length; i++) {
	        if (!test(array[i], i, array)) {
	          return false;
	        }
	      }
	      return true;
	    },
	
	    /** Builds a function that will proxy a method call to its first argument.
	     *
	     * Allows partial application of arguments, so additional arguments are
	     * prepended to the argument list.
	     *
	     * @param  {String} name method name
	     * @return {Function} proxy function
	     */
	    method: function(name) {
	      var boundArguments = Array.prototype.slice.call(arguments, 1);
	      return function(object) {
	        return object[name].apply(object, boundArguments.concat(arguments));
	      };
	    },
	
	    getWindow: function() {
	      return window;
	    },
	
	    getDocument: function() {
	      return document;
	    },
	
	    getNavigator: function() {
	      return navigator;
	    },
	
	    getLocalStorage: function() {
	      try {
	        return window.localStorage;
	      } catch (e) {
	        return undefined;
	      }
	    },
	
	    getClientFeatures: function() {
	      return Pusher.Util.keys(
	        Pusher.Util.filterObject(
	          { "ws": Pusher.WSTransport, "flash": Pusher.FlashTransport },
	          function (t) { return t.isSupported({}); }
	        )
	      );
	    },
	
	    addWindowListener: function(event, listener) {
	      var _window = Pusher.Util.getWindow();
	      if (_window.addEventListener !== undefined) {
	        _window.addEventListener(event, listener, false);
	      } else {
	        _window.attachEvent("on" + event, listener);
	      }
	    },
	
	    removeWindowListener: function(event, listener) {
	      var _window = Pusher.Util.getWindow();
	      if (_window.addEventListener !== undefined) {
	        _window.removeEventListener(event, listener, false);
	      } else {
	        _window.detachEvent("on" + event, listener);
	      }
	    },
	
	    isXHRSupported: function() {
	      var XHR = window.XMLHttpRequest;
	      return Boolean(XHR) && (new XHR()).withCredentials !== undefined;
	    },
	
	    isXDRSupported: function(encrypted) {
	      var protocol = encrypted ? "https:" : "http:";
	      var documentProtocol = Pusher.Util.getDocument().location.protocol;
	      return Boolean(window.XDomainRequest) && documentProtocol === protocol;
	    }
	  };
	}).call(this);
	
	;(function() {
	  Pusher.VERSION = '2.2.4';
	  Pusher.PROTOCOL = 7;
	
	  // DEPRECATED: WS connection parameters
	  Pusher.host = 'ws.pusherapp.com';
	  Pusher.ws_port = 80;
	  Pusher.wss_port = 443;
	  // DEPRECATED: SockJS fallback parameters
	  Pusher.sockjs_host = 'sockjs.pusher.com';
	  Pusher.sockjs_http_port = 80;
	  Pusher.sockjs_https_port = 443;
	  Pusher.sockjs_path = "/pusher";
	  // DEPRECATED: Stats
	  Pusher.stats_host = 'stats.pusher.com';
	  // DEPRECATED: Other settings
	  Pusher.channel_auth_endpoint = '/pusher/auth';
	  Pusher.channel_auth_transport = 'ajax';
	  Pusher.activity_timeout = 120000;
	  Pusher.pong_timeout = 30000;
	  Pusher.unavailable_timeout = 10000;
	  // CDN configuration
	  Pusher.cdn_http = 'http://js.pusher.com/';
	  Pusher.cdn_https = 'https://js.pusher.com/';
	  Pusher.dependency_suffix = '';
	
	  Pusher.getDefaultStrategy = function(config) {
	    var wsStrategy;
	    if (config.encrypted) {
	      wsStrategy = [
	        ":best_connected_ever",
	        ":ws_loop",
	        [":delayed", 2000, [":http_fallback_loop"]]
	      ];
	    } else {
	      wsStrategy = [
	        ":best_connected_ever",
	        ":ws_loop",
	        [":delayed", 2000, [":wss_loop"]],
	        [":delayed", 5000, [":http_fallback_loop"]]
	      ];
	    }
	
	    return [
	      [":def", "ws_options", {
	        hostUnencrypted: config.wsHost + ":" + config.wsPort,
	        hostEncrypted: config.wsHost + ":" + config.wssPort
	      }],
	      [":def", "wss_options", [":extend", ":ws_options", {
	        encrypted: true
	      }]],
	      [":def", "sockjs_options", {
	        hostUnencrypted: config.httpHost + ":" + config.httpPort,
	        hostEncrypted: config.httpHost + ":" + config.httpsPort,
	        httpPath: config.httpPath
	      }],
	      [":def", "timeouts", {
	        loop: true,
	        timeout: 15000,
	        timeoutLimit: 60000
	      }],
	
	      [":def", "ws_manager", [":transport_manager", {
	        lives: 2,
	        minPingDelay: 10000,
	        maxPingDelay: config.activity_timeout
	      }]],
	      [":def", "streaming_manager", [":transport_manager", {
	        lives: 2,
	        minPingDelay: 10000,
	        maxPingDelay: config.activity_timeout
	      }]],
	
	      [":def_transport", "ws", "ws", 3, ":ws_options", ":ws_manager"],
	      [":def_transport", "wss", "ws", 3, ":wss_options", ":ws_manager"],
	      [":def_transport", "flash", "flash", 2, ":ws_options", ":ws_manager"],
	      [":def_transport", "sockjs", "sockjs", 1, ":sockjs_options"],
	      [":def_transport", "xhr_streaming", "xhr_streaming", 1, ":sockjs_options", ":streaming_manager"],
	      [":def_transport", "xdr_streaming", "xdr_streaming", 1, ":sockjs_options", ":streaming_manager"],
	      [":def_transport", "xhr_polling", "xhr_polling", 1, ":sockjs_options"],
	      [":def_transport", "xdr_polling", "xdr_polling", 1, ":sockjs_options"],
	
	      [":def", "ws_loop", [":sequential", ":timeouts", ":ws"]],
	      [":def", "wss_loop", [":sequential", ":timeouts", ":wss"]],
	      [":def", "flash_loop", [":sequential", ":timeouts", ":flash"]],
	      [":def", "sockjs_loop", [":sequential", ":timeouts", ":sockjs"]],
	
	      [":def", "streaming_loop", [":sequential", ":timeouts",
	        [":if", [":is_supported", ":xhr_streaming"],
	          ":xhr_streaming",
	          ":xdr_streaming"
	        ]
	      ]],
	      [":def", "polling_loop", [":sequential", ":timeouts",
	        [":if", [":is_supported", ":xhr_polling"],
	          ":xhr_polling",
	          ":xdr_polling"
	        ]
	      ]],
	
	      [":def", "http_loop", [":if", [":is_supported", ":streaming_loop"], [
	        ":best_connected_ever",
	          ":streaming_loop",
	          [":delayed", 4000, [":polling_loop"]]
	      ], [
	        ":polling_loop"
	      ]]],
	
	      [":def", "http_fallback_loop",
	        [":if", [":is_supported", ":http_loop"], [
	          ":http_loop"
	        ], [
	          ":sockjs_loop"
	        ]]
	      ],
	
	      [":def", "strategy",
	        [":cached", 1800000,
	          [":first_connected",
	            [":if", [":is_supported", ":ws"],
	              wsStrategy,
	            [":if", [":is_supported", ":flash"], [
	              ":best_connected_ever",
	              ":flash_loop",
	              [":delayed", 2000, [":http_fallback_loop"]]
	            ], [
	              ":http_fallback_loop"
	            ]]]
	          ]
	        ]
	      ]
	    ];
	  };
	}).call(this);
	
	;(function() {
	  Pusher.getGlobalConfig = function() {
	    return {
	      wsHost: Pusher.host,
	      wsPort: Pusher.ws_port,
	      wssPort: Pusher.wss_port,
	      httpHost: Pusher.sockjs_host,
	      httpPort: Pusher.sockjs_http_port,
	      httpsPort: Pusher.sockjs_https_port,
	      httpPath: Pusher.sockjs_path,
	      statsHost: Pusher.stats_host,
	      authEndpoint: Pusher.channel_auth_endpoint,
	      authTransport: Pusher.channel_auth_transport,
	      // TODO make this consistent with other options in next major version
	      activity_timeout: Pusher.activity_timeout,
	      pong_timeout: Pusher.pong_timeout,
	      unavailable_timeout: Pusher.unavailable_timeout
	    };
	  };
	
	  Pusher.getClusterConfig = function(clusterName) {
	    return {
	      wsHost: "ws-" + clusterName + ".pusher.com",
	      httpHost: "sockjs-" + clusterName + ".pusher.com"
	    };
	  };
	}).call(this);
	
	;(function() {
	  function buildExceptionClass(name) {
	    var constructor = function(message) {
	      Error.call(this, message);
	      this.name = name;
	    };
	    Pusher.Util.extend(constructor.prototype, Error.prototype);
	
	    return constructor;
	  }
	
	  /** Error classes used throughout pusher-js library. */
	  Pusher.Errors = {
	    BadEventName: buildExceptionClass("BadEventName"),
	    RequestTimedOut: buildExceptionClass("RequestTimedOut"),
	    TransportPriorityTooLow: buildExceptionClass("TransportPriorityTooLow"),
	    TransportClosed: buildExceptionClass("TransportClosed"),
	    UnsupportedTransport: buildExceptionClass("UnsupportedTransport"),
	    UnsupportedStrategy: buildExceptionClass("UnsupportedStrategy")
	  };
	}).call(this);
	
	;(function() {
	  /** Manages callback bindings and event emitting.
	   *
	   * @param Function failThrough called when no listeners are bound to an event
	   */
	  function EventsDispatcher(failThrough) {
	    this.callbacks = new CallbackRegistry();
	    this.global_callbacks = [];
	    this.failThrough = failThrough;
	  }
	  var prototype = EventsDispatcher.prototype;
	
	  prototype.bind = function(eventName, callback, context) {
	    this.callbacks.add(eventName, callback, context);
	    return this;
	  };
	
	  prototype.bind_all = function(callback) {
	    this.global_callbacks.push(callback);
	    return this;
	  };
	
	  prototype.unbind = function(eventName, callback, context) {
	    this.callbacks.remove(eventName, callback, context);
	    return this;
	  };
	
	  prototype.unbind_all = function(eventName, callback) {
	    this.callbacks.remove(eventName, callback);
	    return this;
	  };
	
	  prototype.emit = function(eventName, data) {
	    var i;
	
	    for (i = 0; i < this.global_callbacks.length; i++) {
	      this.global_callbacks[i](eventName, data);
	    }
	
	    var callbacks = this.callbacks.get(eventName);
	    if (callbacks && callbacks.length > 0) {
	      for (i = 0; i < callbacks.length; i++) {
	        callbacks[i].fn.call(callbacks[i].context || window, data);
	      }
	    } else if (this.failThrough) {
	      this.failThrough(eventName, data);
	    }
	
	    return this;
	  };
	
	  /** Callback registry helper. */
	
	  function CallbackRegistry() {
	    this._callbacks = {};
	  }
	
	  CallbackRegistry.prototype.get = function(name) {
	    return this._callbacks[prefix(name)];
	  };
	
	  CallbackRegistry.prototype.add = function(name, callback, context) {
	    var prefixedEventName = prefix(name);
	    this._callbacks[prefixedEventName] = this._callbacks[prefixedEventName] || [];
	    this._callbacks[prefixedEventName].push({
	      fn: callback,
	      context: context
	    });
	  };
	
	  CallbackRegistry.prototype.remove = function(name, callback, context) {
	    if (!name && !callback && !context) {
	      this._callbacks = {};
	      return;
	    }
	
	    var names = name ? [prefix(name)] : Pusher.Util.keys(this._callbacks);
	
	    if (callback || context) {
	      Pusher.Util.apply(names, function(name) {
	        this._callbacks[name] = Pusher.Util.filter(
	          this._callbacks[name] || [],
	          function(binding) {
	            return (callback && callback !== binding.fn) ||
	                   (context && context !== binding.context);
	          }
	        );
	        if (this._callbacks[name].length === 0) {
	          delete this._callbacks[name];
	        }
	      }, this);
	    } else {
	      Pusher.Util.apply(names, function(name) {
	        delete this._callbacks[name];
	      }, this);
	    }
	  };
	
	  function prefix(name) {
	    return "_" + name;
	  }
	
	  Pusher.EventsDispatcher = EventsDispatcher;
	}).call(this);
	
	(function() {
	  /** Builds receivers for JSONP and Script requests.
	   *
	   * Each receiver is an object with following fields:
	   * - number - unique (for the factory instance), numerical id of the receiver
	   * - id - a string ID that can be used in DOM attributes
	   * - name - name of the function triggering the receiver
	   * - callback - callback function
	   *
	   * Receivers are triggered only once, on the first callback call.
	   *
	   * Receivers can be called by their name or by accessing factory object
	   * by the number key.
	   *
	   * @param {String} prefix the prefix used in ids
	   * @param {String} name the name of the object
	   */
	  function ScriptReceiverFactory(prefix, name) {
	    this.lastId = 0;
	    this.prefix = prefix;
	    this.name = name;
	  }
	  var prototype = ScriptReceiverFactory.prototype;
	
	  /** Creates a script receiver.
	   *
	   * @param {Function} callback
	   * @return {ScriptReceiver}
	   */
	  prototype.create = function(callback) {
	    this.lastId++;
	
	    var number = this.lastId;
	    var id = this.prefix + number;
	    var name = this.name + "[" + number + "]";
	
	    var called = false;
	    var callbackWrapper = function() {
	      if (!called) {
	        callback.apply(null, arguments);
	        called = true;
	      }
	    };
	
	    this[number] = callbackWrapper;
	    return { number: number, id: id, name: name, callback: callbackWrapper };
	  };
	
	  /** Removes the script receiver from the list.
	   *
	   * @param {ScriptReceiver} receiver
	   */
	  prototype.remove = function(receiver) {
	    delete this[receiver.number];
	  };
	
	  Pusher.ScriptReceiverFactory = ScriptReceiverFactory;
	  Pusher.ScriptReceivers = new ScriptReceiverFactory(
	    "_pusher_script_", "Pusher.ScriptReceivers"
	  );
	}).call(this);
	
	(function() {
	  /** Sends a generic HTTP GET request using a script tag.
	   *
	   * By constructing URL in a specific way, it can be used for loading
	   * JavaScript resources or JSONP requests. It can notify about errors, but
	   * only in certain environments. Please take care of monitoring the state of
	   * the request yourself.
	   *
	   * @param {String} src
	   */
	  function ScriptRequest(src) {
	    this.src = src;
	  }
	  var prototype = ScriptRequest.prototype;
	
	  /** Sends the actual script request.
	   *
	   * @param {ScriptReceiver} receiver
	   */
	  prototype.send = function(receiver) {
	    var self = this;
	    var errorString = "Error loading " + self.src;
	
	    self.script = document.createElement("script");
	    self.script.id = receiver.id;
	    self.script.src = self.src;
	    self.script.type = "text/javascript";
	    self.script.charset = "UTF-8";
	
	    if (self.script.addEventListener) {
	      self.script.onerror = function() {
	        receiver.callback(errorString);
	      };
	      self.script.onload = function() {
	        receiver.callback(null);
	      };
	    } else {
	      self.script.onreadystatechange = function() {
	        if (self.script.readyState === 'loaded' ||
	            self.script.readyState === 'complete') {
	          receiver.callback(null);
	        }
	      };
	    }
	
	    // Opera<11.6 hack for missing onerror callback
	    if (self.script.async === undefined && document.attachEvent &&
	        /opera/i.test(navigator.userAgent)) {
	      self.errorScript = document.createElement("script");
	      self.errorScript.id = receiver.id + "_error";
	      self.errorScript.text = receiver.name + "('" + errorString + "');";
	      self.script.async = self.errorScript.async = false;
	    } else {
	      self.script.async = true;
	    }
	
	    var head = document.getElementsByTagName('head')[0];
	    head.insertBefore(self.script, head.firstChild);
	    if (self.errorScript) {
	      head.insertBefore(self.errorScript, self.script.nextSibling);
	    }
	  };
	
	  /** Cleans up the DOM remains of the script request. */
	  prototype.cleanup = function() {
	    if (this.script) {
	      this.script.onload = this.script.onerror = null;
	      this.script.onreadystatechange = null;
	    }
	    if (this.script && this.script.parentNode) {
	      this.script.parentNode.removeChild(this.script);
	    }
	    if (this.errorScript && this.errorScript.parentNode) {
	      this.errorScript.parentNode.removeChild(this.errorScript);
	    }
	    this.script = null;
	    this.errorScript = null;
	  };
	
	  Pusher.ScriptRequest = ScriptRequest;
	}).call(this);
	
	;(function() {
	  /** Handles loading dependency files.
	   *
	   * Dependency loaders don't remember whether a resource has been loaded or
	   * not. It is caller's responsibility to make sure the resource is not loaded
	   * twice. This is because it's impossible to detect resource loading status
	   * without knowing its content.
	   *
	   * Options:
	   * - cdn_http - url to HTTP CND
	   * - cdn_https - url to HTTPS CDN
	   * - version - version of pusher-js
	   * - suffix - suffix appended to all names of dependency files
	   *
	   * @param {Object} options
	   */
	  function DependencyLoader(options) {
	    this.options = options;
	    this.receivers = options.receivers || Pusher.ScriptReceivers;
	    this.loading = {};
	  }
	  var prototype = DependencyLoader.prototype;
	
	  /** Loads the dependency from CDN.
	   *
	   * @param  {String} name
	   * @param  {Function} callback
	   */
	  prototype.load = function(name, options, callback) {
	    var self = this;
	
	    if (self.loading[name] && self.loading[name].length > 0) {
	      self.loading[name].push(callback);
	    } else {
	      self.loading[name] = [callback];
	
	      var request = new Pusher.ScriptRequest(self.getPath(name, options));
	      var receiver = self.receivers.create(function(error) {
	        self.receivers.remove(receiver);
	
	        if (self.loading[name]) {
	          var callbacks = self.loading[name];
	          delete self.loading[name];
	
	          var successCallback = function(wasSuccessful) {
	            if (!wasSuccessful) {
	              request.cleanup();
	            }
	          };
	          for (var i = 0; i < callbacks.length; i++) {
	            callbacks[i](error, successCallback);
	          }
	        }
	      });
	      request.send(receiver);
	    }
	  };
	
	  /** Returns a root URL for pusher-js CDN.
	   *
	   * @returns {String}
	   */
	  prototype.getRoot = function(options) {
	    var cdn;
	    var protocol = Pusher.Util.getDocument().location.protocol;
	    if ((options && options.encrypted) || protocol === "https:") {
	      cdn = this.options.cdn_https;
	    } else {
	      cdn = this.options.cdn_http;
	    }
	    // make sure there are no double slashes
	    return cdn.replace(/\/*$/, "") + "/" + this.options.version;
	  };
	
	  /** Returns a full path to a dependency file.
	   *
	   * @param {String} name
	   * @returns {String}
	   */
	  prototype.getPath = function(name, options) {
	    return this.getRoot(options) + '/' + name + this.options.suffix + '.js';
	  };
	
	  Pusher.DependencyLoader = DependencyLoader;
	}).call(this);
	
	;(function() {
	  Pusher.DependenciesReceivers = new Pusher.ScriptReceiverFactory(
	    "_pusher_dependencies", "Pusher.DependenciesReceivers"
	  );
	  Pusher.Dependencies = new Pusher.DependencyLoader({
	    cdn_http: Pusher.cdn_http,
	    cdn_https: Pusher.cdn_https,
	    version: Pusher.VERSION,
	    suffix: Pusher.dependency_suffix,
	    receivers: Pusher.DependenciesReceivers
	  });
	
	  function initialize() {
	    Pusher.ready();
	  }
	
	  // Allows calling a function when the document body is available
	   function onDocumentBody(callback) {
	    if (document.body) {
	      callback();
	    } else {
	      setTimeout(function() {
	        onDocumentBody(callback);
	      }, 0);
	    }
	  }
	
	  function initializeOnDocumentBody() {
	    onDocumentBody(initialize);
	  }
	
	  if (!window.JSON) {
	    Pusher.Dependencies.load("json2", {}, initializeOnDocumentBody);
	  } else {
	    initializeOnDocumentBody();
	  }
	})();
	
	(function() {
	
	  var Base64 = {
	    encode: function (s) {
	      return btoa(utob(s));
	    }
	  };
	
	  var fromCharCode = String.fromCharCode;
	
	  var b64chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
	  var b64tab = {};
	
	  for (var i = 0, l = b64chars.length; i < l; i++) {
	    b64tab[b64chars.charAt(i)] = i;
	  }
	
	  var cb_utob = function(c) {
	    var cc = c.charCodeAt(0);
	    return cc < 0x80 ? c
	        : cc < 0x800 ? fromCharCode(0xc0 | (cc >>> 6)) +
	                       fromCharCode(0x80 | (cc & 0x3f))
	        : fromCharCode(0xe0 | ((cc >>> 12) & 0x0f)) +
	          fromCharCode(0x80 | ((cc >>>  6) & 0x3f)) +
	          fromCharCode(0x80 | ( cc         & 0x3f));
	  };
	
	  var utob = function(u) {
	    return u.replace(/[^\x00-\x7F]/g, cb_utob);
	  };
	
	  var cb_encode = function(ccc) {
	    var padlen = [0, 2, 1][ccc.length % 3];
	    var ord = ccc.charCodeAt(0) << 16
	      | ((ccc.length > 1 ? ccc.charCodeAt(1) : 0) << 8)
	      | ((ccc.length > 2 ? ccc.charCodeAt(2) : 0));
	    var chars = [
	      b64chars.charAt( ord >>> 18),
	      b64chars.charAt((ord >>> 12) & 63),
	      padlen >= 2 ? '=' : b64chars.charAt((ord >>> 6) & 63),
	      padlen >= 1 ? '=' : b64chars.charAt(ord & 63)
	    ];
	    return chars.join('');
	  };
	
	  var btoa = window.btoa || function(b) {
	    return b.replace(/[\s\S]{1,3}/g, cb_encode);
	  };
	
	  Pusher.Base64 = Base64;
	
	}).call(this);
	
	(function() {
	  /** Sends data via JSONP.
	   *
	   * Data is a key-value map. Its values are JSON-encoded and then passed
	   * through base64. Finally, keys and encoded values are appended to the query
	   * string.
	   *
	   * The class itself does not guarantee raising errors on failures, as it's not
	   * possible to support such feature on all browsers. Instead, JSONP endpoint
	   * should call back in a way that's easy to distinguish from browser calls,
	   * for example by passing a second argument to the receiver.
	   *
	   * @param {String} url
	   * @param {Object} data key-value map of data to be submitted
	   */
	  function JSONPRequest(url, data) {
	    this.url = url;
	    this.data = data;
	  }
	  var prototype = JSONPRequest.prototype;
	
	  /** Sends the actual JSONP request.
	   *
	   * @param {ScriptReceiver} receiver
	   */
	  prototype.send = function(receiver) {
	    if (this.request) {
	      return;
	    }
	
	    var params = Pusher.Util.filterObject(this.data, function(value) {
	      return value !== undefined;
	    });
	    var query = Pusher.Util.map(
	      Pusher.Util.flatten(encodeParamsObject(params)),
	      Pusher.Util.method("join", "=")
	    ).join("&");
	    var url = this.url + "/" + receiver.number + "?" + query;
	
	    this.request = new Pusher.ScriptRequest(url);
	    this.request.send(receiver);
	  };
	
	  /** Cleans up the DOM remains of the JSONP request. */
	  prototype.cleanup = function() {
	    if (this.request) {
	      this.request.cleanup();
	    }
	  };
	
	  function encodeParamsObject(data) {
	    return Pusher.Util.mapObject(data, function(value) {
	      if (typeof value === "object") {
	        value = JSON.stringify(value);
	      }
	      return encodeURIComponent(Pusher.Base64.encode(value.toString()));
	    });
	  }
	
	  Pusher.JSONPRequest = JSONPRequest;
	}).call(this);
	
	(function() {
	  function Timeline(key, session, options) {
	    this.key = key;
	    this.session = session;
	    this.events = [];
	    this.options = options || {};
	    this.sent = 0;
	    this.uniqueID = 0;
	  }
	  var prototype = Timeline.prototype;
	
	  // Log levels
	  Timeline.ERROR = 3;
	  Timeline.INFO = 6;
	  Timeline.DEBUG = 7;
	
	  prototype.log = function(level, event) {
	    if (level <= this.options.level) {
	      this.events.push(
	        Pusher.Util.extend({}, event, { timestamp: Pusher.Util.now() })
	      );
	      if (this.options.limit && this.events.length > this.options.limit) {
	        this.events.shift();
	      }
	    }
	  };
	
	  prototype.error = function(event) {
	    this.log(Timeline.ERROR, event);
	  };
	
	  prototype.info = function(event) {
	    this.log(Timeline.INFO, event);
	  };
	
	  prototype.debug = function(event) {
	    this.log(Timeline.DEBUG, event);
	  };
	
	  prototype.isEmpty = function() {
	    return this.events.length === 0;
	  };
	
	  prototype.send = function(sendJSONP, callback) {
	    var self = this;
	
	    var data = Pusher.Util.extend({
	      session: self.session,
	      bundle: self.sent + 1,
	      key: self.key,
	      lib: "js",
	      version: self.options.version,
	      cluster: self.options.cluster,
	      features: self.options.features,
	      timeline: self.events
	    }, self.options.params);
	
	    self.events = [];
	    sendJSONP(data, function(error, result) {
	      if (!error) {
	        self.sent++;
	      }
	      if (callback) {
	        callback(error, result);
	      }
	    });
	
	    return true;
	  };
	
	  prototype.generateUniqueID = function() {
	    this.uniqueID++;
	    return this.uniqueID;
	  };
	
	  Pusher.Timeline = Timeline;
	}).call(this);
	
	(function() {
	  function TimelineSender(timeline, options) {
	    this.timeline = timeline;
	    this.options = options || {};
	  }
	  var prototype = TimelineSender.prototype;
	
	  prototype.send = function(encrypted, callback) {
	    var self = this;
	
	    if (self.timeline.isEmpty()) {
	      return;
	    }
	
	    var sendJSONP = function(data, callback) {
	      var scheme = "http" + (encrypted ? "s" : "") + "://";
	      var url = scheme + (self.host || self.options.host) + self.options.path;
	      var request = new Pusher.JSONPRequest(url, data);
	
	      var receiver = Pusher.ScriptReceivers.create(function(error, result) {
	        Pusher.ScriptReceivers.remove(receiver);
	        request.cleanup();
	
	        if (result && result.host) {
	          self.host = result.host;
	        }
	        if (callback) {
	          callback(error, result);
	        }
	      });
	      request.send(receiver);
	    };
	    self.timeline.send(sendJSONP, callback);
	  };
	
	  Pusher.TimelineSender = TimelineSender;
	}).call(this);
	
	;(function() {
	  /** Launches all substrategies and emits prioritized connected transports.
	   *
	   * @param {Array} strategies
	   */
	  function BestConnectedEverStrategy(strategies) {
	    this.strategies = strategies;
	  }
	  var prototype = BestConnectedEverStrategy.prototype;
	
	  prototype.isSupported = function() {
	    return Pusher.Util.any(this.strategies, Pusher.Util.method("isSupported"));
	  };
	
	  prototype.connect = function(minPriority, callback) {
	    return connect(this.strategies, minPriority, function(i, runners) {
	      return function(error, handshake) {
	        runners[i].error = error;
	        if (error) {
	          if (allRunnersFailed(runners)) {
	            callback(true);
	          }
	          return;
	        }
	        Pusher.Util.apply(runners, function(runner) {
	          runner.forceMinPriority(handshake.transport.priority);
	        });
	        callback(null, handshake);
	      };
	    });
	  };
	
	  /** Connects to all strategies in parallel.
	   *
	   * Callback builder should be a function that takes two arguments: index
	   * and a list of runners. It should return another function that will be
	   * passed to the substrategy with given index. Runners can be aborted using
	   * abortRunner(s) functions from this class.
	   *
	   * @param  {Array} strategies
	   * @param  {Function} callbackBuilder
	   * @return {Object} strategy runner
	   */
	  function connect(strategies, minPriority, callbackBuilder) {
	    var runners = Pusher.Util.map(strategies, function(strategy, i, _, rs) {
	      return strategy.connect(minPriority, callbackBuilder(i, rs));
	    });
	    return {
	      abort: function() {
	        Pusher.Util.apply(runners, abortRunner);
	      },
	      forceMinPriority: function(p) {
	        Pusher.Util.apply(runners, function(runner) {
	          runner.forceMinPriority(p);
	        });
	      }
	    };
	  }
	
	  function allRunnersFailed(runners) {
	    return Pusher.Util.all(runners, function(runner) {
	      return Boolean(runner.error);
	    });
	  }
	
	  function abortRunner(runner) {
	    if (!runner.error && !runner.aborted) {
	      runner.abort();
	      runner.aborted = true;
	    }
	  }
	
	  Pusher.BestConnectedEverStrategy = BestConnectedEverStrategy;
	}).call(this);
	
	;(function() {
	  /** Caches last successful transport and uses it for following attempts.
	   *
	   * @param {Strategy} strategy
	   * @param {Object} transports
	   * @param {Object} options
	   */
	  function CachedStrategy(strategy, transports, options) {
	    this.strategy = strategy;
	    this.transports = transports;
	    this.ttl = options.ttl || 1800*1000;
	    this.encrypted = options.encrypted;
	    this.timeline = options.timeline;
	  }
	  var prototype = CachedStrategy.prototype;
	
	  prototype.isSupported = function() {
	    return this.strategy.isSupported();
	  };
	
	  prototype.connect = function(minPriority, callback) {
	    var encrypted = this.encrypted;
	    var info = fetchTransportCache(encrypted);
	
	    var strategies = [this.strategy];
	    if (info && info.timestamp + this.ttl >= Pusher.Util.now()) {
	      var transport = this.transports[info.transport];
	      if (transport) {
	        this.timeline.info({
	          cached: true,
	          transport: info.transport,
	          latency: info.latency
	        });
	        strategies.push(new Pusher.SequentialStrategy([transport], {
	          timeout: info.latency * 2 + 1000,
	          failFast: true
	        }));
	      }
	    }
	
	    var startTimestamp = Pusher.Util.now();
	    var runner = strategies.pop().connect(
	      minPriority,
	      function cb(error, handshake) {
	        if (error) {
	          flushTransportCache(encrypted);
	          if (strategies.length > 0) {
	            startTimestamp = Pusher.Util.now();
	            runner = strategies.pop().connect(minPriority, cb);
	          } else {
	            callback(error);
	          }
	        } else {
	          storeTransportCache(
	            encrypted,
	            handshake.transport.name,
	            Pusher.Util.now() - startTimestamp
	          );
	          callback(null, handshake);
	        }
	      }
	    );
	
	    return {
	      abort: function() {
	        runner.abort();
	      },
	      forceMinPriority: function(p) {
	        minPriority = p;
	        if (runner) {
	          runner.forceMinPriority(p);
	        }
	      }
	    };
	  };
	
	  function getTransportCacheKey(encrypted) {
	    return "pusherTransport" + (encrypted ? "Encrypted" : "Unencrypted");
	  }
	
	  function fetchTransportCache(encrypted) {
	    var storage = Pusher.Util.getLocalStorage();
	    if (storage) {
	      try {
	        var serializedCache = storage[getTransportCacheKey(encrypted)];
	        if (serializedCache) {
	          return JSON.parse(serializedCache);
	        }
	      } catch (e) {
	        flushTransportCache(encrypted);
	      }
	    }
	    return null;
	  }
	
	  function storeTransportCache(encrypted, transport, latency) {
	    var storage = Pusher.Util.getLocalStorage();
	    if (storage) {
	      try {
	        storage[getTransportCacheKey(encrypted)] = JSON.stringify({
	          timestamp: Pusher.Util.now(),
	          transport: transport,
	          latency: latency
	        });
	      } catch (e) {
	        // catch over quota exceptions raised by localStorage
	      }
	    }
	  }
	
	  function flushTransportCache(encrypted) {
	    var storage = Pusher.Util.getLocalStorage();
	    if (storage) {
	      try {
	        delete storage[getTransportCacheKey(encrypted)];
	      } catch (e) {
	        // catch exceptions raised by localStorage
	      }
	    }
	  }
	
	  Pusher.CachedStrategy = CachedStrategy;
	}).call(this);
	
	;(function() {
	  /** Runs substrategy after specified delay.
	   *
	   * Options:
	   * - delay - time in miliseconds to delay the substrategy attempt
	   *
	   * @param {Strategy} strategy
	   * @param {Object} options
	   */
	  function DelayedStrategy(strategy, options) {
	    this.strategy = strategy;
	    this.options = { delay: options.delay };
	  }
	  var prototype = DelayedStrategy.prototype;
	
	  prototype.isSupported = function() {
	    return this.strategy.isSupported();
	  };
	
	  prototype.connect = function(minPriority, callback) {
	    var strategy = this.strategy;
	    var runner;
	    var timer = new Pusher.Timer(this.options.delay, function() {
	      runner = strategy.connect(minPriority, callback);
	    });
	
	    return {
	      abort: function() {
	        timer.ensureAborted();
	        if (runner) {
	          runner.abort();
	        }
	      },
	      forceMinPriority: function(p) {
	        minPriority = p;
	        if (runner) {
	          runner.forceMinPriority(p);
	        }
	      }
	    };
	  };
	
	  Pusher.DelayedStrategy = DelayedStrategy;
	}).call(this);
	
	;(function() {
	  /** Launches the substrategy and terminates on the first open connection.
	   *
	   * @param {Strategy} strategy
	   */
	  function FirstConnectedStrategy(strategy) {
	    this.strategy = strategy;
	  }
	  var prototype = FirstConnectedStrategy.prototype;
	
	  prototype.isSupported = function() {
	    return this.strategy.isSupported();
	  };
	
	  prototype.connect = function(minPriority, callback) {
	    var runner = this.strategy.connect(
	      minPriority,
	      function(error, handshake) {
	        if (handshake) {
	          runner.abort();
	        }
	        callback(error, handshake);
	      }
	    );
	    return runner;
	  };
	
	  Pusher.FirstConnectedStrategy = FirstConnectedStrategy;
	}).call(this);
	
	;(function() {
	  /** Proxies method calls to one of substrategies basing on the test function.
	   *
	   * @param {Function} test
	   * @param {Strategy} trueBranch strategy used when test returns true
	   * @param {Strategy} falseBranch strategy used when test returns false
	   */
	  function IfStrategy(test, trueBranch, falseBranch) {
	    this.test = test;
	    this.trueBranch = trueBranch;
	    this.falseBranch = falseBranch;
	  }
	  var prototype = IfStrategy.prototype;
	
	  prototype.isSupported = function() {
	    var branch = this.test() ? this.trueBranch : this.falseBranch;
	    return branch.isSupported();
	  };
	
	  prototype.connect = function(minPriority, callback) {
	    var branch = this.test() ? this.trueBranch : this.falseBranch;
	    return branch.connect(minPriority, callback);
	  };
	
	  Pusher.IfStrategy = IfStrategy;
	}).call(this);
	
	;(function() {
	  /** Loops through strategies with optional timeouts.
	   *
	   * Options:
	   * - loop - whether it should loop through the substrategy list
	   * - timeout - initial timeout for a single substrategy
	   * - timeoutLimit - maximum timeout
	   *
	   * @param {Strategy[]} strategies
	   * @param {Object} options
	   */
	  function SequentialStrategy(strategies, options) {
	    this.strategies = strategies;
	    this.loop = Boolean(options.loop);
	    this.failFast = Boolean(options.failFast);
	    this.timeout = options.timeout;
	    this.timeoutLimit = options.timeoutLimit;
	  }
	  var prototype = SequentialStrategy.prototype;
	
	  prototype.isSupported = function() {
	    return Pusher.Util.any(this.strategies, Pusher.Util.method("isSupported"));
	  };
	
	  prototype.connect = function(minPriority, callback) {
	    var self = this;
	
	    var strategies = this.strategies;
	    var current = 0;
	    var timeout = this.timeout;
	    var runner = null;
	
	    var tryNextStrategy = function(error, handshake) {
	      if (handshake) {
	        callback(null, handshake);
	      } else {
	        current = current + 1;
	        if (self.loop) {
	          current = current % strategies.length;
	        }
	
	        if (current < strategies.length) {
	          if (timeout) {
	            timeout = timeout * 2;
	            if (self.timeoutLimit) {
	              timeout = Math.min(timeout, self.timeoutLimit);
	            }
	          }
	          runner = self.tryStrategy(
	            strategies[current],
	            minPriority,
	            { timeout: timeout, failFast: self.failFast },
	            tryNextStrategy
	          );
	        } else {
	          callback(true);
	        }
	      }
	    };
	
	    runner = this.tryStrategy(
	      strategies[current],
	      minPriority,
	      { timeout: timeout, failFast: this.failFast },
	      tryNextStrategy
	    );
	
	    return {
	      abort: function() {
	        runner.abort();
	      },
	      forceMinPriority: function(p) {
	        minPriority = p;
	        if (runner) {
	          runner.forceMinPriority(p);
	        }
	      }
	    };
	  };
	
	  /** @private */
	  prototype.tryStrategy = function(strategy, minPriority, options, callback) {
	    var timer = null;
	    var runner = null;
	
	    if (options.timeout > 0) {
	      timer = new Pusher.Timer(options.timeout, function() {
	        runner.abort();
	        callback(true);
	      });
	    }
	
	    runner = strategy.connect(minPriority, function(error, handshake) {
	      if (error && timer && timer.isRunning() && !options.failFast) {
	        // advance to the next strategy after the timeout
	        return;
	      }
	      if (timer) {
	        timer.ensureAborted();
	      }
	      callback(error, handshake);
	    });
	
	    return {
	      abort: function() {
	        if (timer) {
	          timer.ensureAborted();
	        }
	        runner.abort();
	      },
	      forceMinPriority: function(p) {
	        runner.forceMinPriority(p);
	      }
	    };
	  };
	
	  Pusher.SequentialStrategy = SequentialStrategy;
	}).call(this);
	
	;(function() {
	  /** Provides a strategy interface for transports.
	   *
	   * @param {String} name
	   * @param {Number} priority
	   * @param {Class} transport
	   * @param {Object} options
	   */
	  function TransportStrategy(name, priority, transport, options) {
	    this.name = name;
	    this.priority = priority;
	    this.transport = transport;
	    this.options = options || {};
	  }
	  var prototype = TransportStrategy.prototype;
	
	  /** Returns whether the transport is supported in the browser.
	   *
	   * @returns {Boolean}
	   */
	  prototype.isSupported = function() {
	    return this.transport.isSupported({
	      encrypted: this.options.encrypted
	    });
	  };
	
	  /** Launches a connection attempt and returns a strategy runner.
	   *
	   * @param  {Function} callback
	   * @return {Object} strategy runner
	   */
	  prototype.connect = function(minPriority, callback) {
	    if (!this.isSupported()) {
	      return failAttempt(new Pusher.Errors.UnsupportedStrategy(), callback);
	    } else if (this.priority < minPriority) {
	      return failAttempt(new Pusher.Errors.TransportPriorityTooLow(), callback);
	    }
	
	    var self = this;
	    var connected = false;
	
	    var transport = this.transport.createConnection(
	      this.name, this.priority, this.options.key, this.options
	    );
	    var handshake = null;
	
	    var onInitialized = function() {
	      transport.unbind("initialized", onInitialized);
	      transport.connect();
	    };
	    var onOpen = function() {
	      handshake = new Pusher.Handshake(transport, function(result) {
	        connected = true;
	        unbindListeners();
	        callback(null, result);
	      });
	    };
	    var onError = function(error) {
	      unbindListeners();
	      callback(error);
	    };
	    var onClosed = function() {
	      unbindListeners();
	      callback(new Pusher.Errors.TransportClosed(transport));
	    };
	
	    var unbindListeners = function() {
	      transport.unbind("initialized", onInitialized);
	      transport.unbind("open", onOpen);
	      transport.unbind("error", onError);
	      transport.unbind("closed", onClosed);
	    };
	
	    transport.bind("initialized", onInitialized);
	    transport.bind("open", onOpen);
	    transport.bind("error", onError);
	    transport.bind("closed", onClosed);
	
	    // connect will be called automatically after initialization
	    transport.initialize();
	
	    return {
	      abort: function() {
	        if (connected) {
	          return;
	        }
	        unbindListeners();
	        if (handshake) {
	          handshake.close();
	        } else {
	          transport.close();
	        }
	      },
	      forceMinPriority: function(p) {
	        if (connected) {
	          return;
	        }
	        if (self.priority < p) {
	          if (handshake) {
	            handshake.close();
	          } else {
	            transport.close();
	          }
	        }
	      }
	    };
	  };
	
	  function failAttempt(error, callback) {
	    Pusher.Util.defer(function() {
	      callback(error);
	    });
	    return {
	      abort: function() {},
	      forceMinPriority: function() {}
	    };
	  }
	
	  Pusher.TransportStrategy = TransportStrategy;
	}).call(this);
	
	(function() {
	  function getGenericURL(baseScheme, params, path) {
	    var scheme = baseScheme + (params.encrypted ? "s" : "");
	    var host = params.encrypted ? params.hostEncrypted : params.hostUnencrypted;
	    return scheme + "://" + host + path;
	  }
	
	  function getGenericPath(key, queryString) {
	    var path = "/app/" + key;
	    var query =
	      "?protocol=" + Pusher.PROTOCOL +
	      "&client=js" +
	      "&version=" + Pusher.VERSION +
	      (queryString ? ("&" + queryString) : "");
	    return path + query;
	  }
	
	  /** URL schemes for different transport types. */
	  Pusher.URLSchemes = {
	    /** Standard WebSocket URL scheme. */
	    ws: {
	      getInitial: function(key, params) {
	        return getGenericURL("ws", params, getGenericPath(key, "flash=false"));
	      }
	    },
	    /** URL scheme for Flash. Same as WebSocket, but with a flash parameter. */
	    flash: {
	      getInitial: function(key, params) {
	        return getGenericURL("ws", params, getGenericPath(key, "flash=true"));
	      }
	    },
	    /** SockJS URL scheme. Supplies the path separately from the initial URL. */
	    sockjs: {
	      getInitial: function(key, params) {
	        return getGenericURL("http", params, params.httpPath || "/pusher", "");
	      },
	      getPath: function(key, params) {
	        return getGenericPath(key);
	      }
	    },
	    /** URL scheme for HTTP transports. Basically, WS scheme with a prefix. */
	    http: {
	      getInitial: function(key, params) {
	        var path = (params.httpPath || "/pusher") + getGenericPath(key);
	        return getGenericURL("http", params, path);
	      }
	    }
	  };
	}).call(this);
	
	(function() {
	  /** Provides universal API for transport connections.
	   *
	   * Transport connection is a low-level object that wraps a connection method
	   * and exposes a simple evented interface for the connection state and
	   * messaging. It does not implement Pusher-specific WebSocket protocol.
	   *
	   * Additionally, it fetches resources needed for transport to work and exposes
	   * an interface for querying transport features.
	   *
	   * States:
	   * - new - initial state after constructing the object
	   * - initializing - during initialization phase, usually fetching resources
	   * - intialized - ready to establish a connection
	   * - connection - when connection is being established
	   * - open - when connection ready to be used
	   * - closed - after connection was closed be either side
	   *
	   * Emits:
	   * - error - after the connection raised an error
	   *
	   * Options:
	   * - encrypted - whether connection should use ssl
	   * - hostEncrypted - host to connect to when connection is encrypted
	   * - hostUnencrypted - host to connect to when connection is not encrypted
	   *
	   * @param {String} key application key
	   * @param {Object} options
	   */
	  function TransportConnection(hooks, name, priority, key, options) {
	    Pusher.EventsDispatcher.call(this);
	
	    this.hooks = hooks;
	    this.name = name;
	    this.priority = priority;
	    this.key = key;
	    this.options = options;
	
	    this.state = "new";
	    this.timeline = options.timeline;
	    this.activityTimeout = options.activityTimeout;
	    this.id = this.timeline.generateUniqueID();
	  }
	  var prototype = TransportConnection.prototype;
	  Pusher.Util.extend(prototype, Pusher.EventsDispatcher.prototype);
	
	  /** Checks whether the transport handles activity checks by itself.
	   *
	   * @return {Boolean}
	   */
	  prototype.handlesActivityChecks = function() {
	    return Boolean(this.hooks.handlesActivityChecks);
	  };
	
	  /** Checks whether the transport supports the ping/pong API.
	   *
	   * @return {Boolean}
	   */
	  prototype.supportsPing = function() {
	    return Boolean(this.hooks.supportsPing);
	  };
	
	  /** Initializes the transport.
	   *
	   * Fetches resources if needed and then transitions to initialized.
	   */
	  prototype.initialize = function() {
	    var self = this;
	
	    self.timeline.info(self.buildTimelineMessage({
	      transport: self.name + (self.options.encrypted ? "s" : "")
	    }));
	
	    if (self.hooks.beforeInitialize) {
	      self.hooks.beforeInitialize.call(self);
	    }
	
	    if (self.hooks.isInitialized()) {
	      self.changeState("initialized");
	    } else if (self.hooks.file) {
	      self.changeState("initializing");
	      Pusher.Dependencies.load(
	        self.hooks.file,
	        { encrypted: self.options.encrypted },
	        function(error, callback) {
	          if (self.hooks.isInitialized()) {
	            self.changeState("initialized");
	            callback(true);
	          } else {
	            if (error) {
	              self.onError(error);
	            }
	            self.onClose();
	            callback(false);
	          }
	        }
	      );
	    } else {
	      self.onClose();
	    }
	  };
	
	  /** Tries to establish a connection.
	   *
	   * @returns {Boolean} false if transport is in invalid state
	   */
	  prototype.connect = function() {
	    var self = this;
	
	    if (self.socket || self.state !== "initialized") {
	      return false;
	    }
	
	    var url = self.hooks.urls.getInitial(self.key, self.options);
	    try {
	      self.socket = self.hooks.getSocket(url, self.options);
	    } catch (e) {
	      Pusher.Util.defer(function() {
	        self.onError(e);
	        self.changeState("closed");
	      });
	      return false;
	    }
	
	    self.bindListeners();
	
	    Pusher.debug("Connecting", { transport: self.name, url: url });
	    self.changeState("connecting");
	    return true;
	  };
	
	  /** Closes the connection.
	   *
	   * @return {Boolean} true if there was a connection to close
	   */
	  prototype.close = function() {
	    if (this.socket) {
	      this.socket.close();
	      return true;
	    } else {
	      return false;
	    }
	  };
	
	  /** Sends data over the open connection.
	   *
	   * @param {String} data
	   * @return {Boolean} true only when in the "open" state
	   */
	  prototype.send = function(data) {
	    var self = this;
	
	    if (self.state === "open") {
	      // Workaround for MobileSafari bug (see https://gist.github.com/2052006)
	      Pusher.Util.defer(function() {
	        if (self.socket) {
	          self.socket.send(data);
	        }
	      });
	      return true;
	    } else {
	      return false;
	    }
	  };
	
	  /** Sends a ping if the connection is open and transport supports it. */
	  prototype.ping = function() {
	    if (this.state === "open" && this.supportsPing()) {
	      this.socket.ping();
	    }
	  };
	
	  /** @private */
	  prototype.onOpen = function() {
	    if (this.hooks.beforeOpen) {
	      this.hooks.beforeOpen(
	        this.socket, this.hooks.urls.getPath(this.key, this.options)
	      );
	    }
	    this.changeState("open");
	    this.socket.onopen = undefined;
	  };
	
	  /** @private */
	  prototype.onError = function(error) {
	    this.emit("error", { type: 'WebSocketError', error: error });
	    this.timeline.error(this.buildTimelineMessage({ error: error.toString() }));
	  };
	
	  /** @private */
	  prototype.onClose = function(closeEvent) {
	    if (closeEvent) {
	      this.changeState("closed", {
	        code: closeEvent.code,
	        reason: closeEvent.reason,
	        wasClean: closeEvent.wasClean
	      });
	    } else {
	      this.changeState("closed");
	    }
	    this.unbindListeners();
	    this.socket = undefined;
	  };
	
	  /** @private */
	  prototype.onMessage = function(message) {
	    this.emit("message", message);
	  };
	
	  /** @private */
	  prototype.onActivity = function() {
	    this.emit("activity");
	  };
	
	  /** @private */
	  prototype.bindListeners = function() {
	    var self = this;
	
	    self.socket.onopen = function() {
	      self.onOpen();
	    };
	    self.socket.onerror = function(error) {
	      self.onError(error);
	    };
	    self.socket.onclose = function(closeEvent) {
	      self.onClose(closeEvent);
	    };
	    self.socket.onmessage = function(message) {
	      self.onMessage(message);
	    };
	
	    if (self.supportsPing()) {
	      self.socket.onactivity = function() { self.onActivity(); };
	    }
	  };
	
	  /** @private */
	  prototype.unbindListeners = function() {
	    if (this.socket) {
	      this.socket.onopen = undefined;
	      this.socket.onerror = undefined;
	      this.socket.onclose = undefined;
	      this.socket.onmessage = undefined;
	      if (this.supportsPing()) {
	        this.socket.onactivity = undefined;
	      }
	    }
	  };
	
	  /** @private */
	  prototype.changeState = function(state, params) {
	    this.state = state;
	    this.timeline.info(this.buildTimelineMessage({
	      state: state,
	      params: params
	    }));
	    this.emit(state, params);
	  };
	
	  /** @private */
	  prototype.buildTimelineMessage = function(message) {
	    return Pusher.Util.extend({ cid: this.id }, message);
	  };
	
	  Pusher.TransportConnection = TransportConnection;
	}).call(this);
	
	(function() {
	  /** Provides interface for transport connection instantiation.
	   *
	   * Takes transport-specific hooks as the only argument, which allow checking
	   * for transport support and creating its connections.
	   *
	   * Supported hooks:
	   * - file - the name of the file to be fetched during initialization
	   * - urls - URL scheme to be used by transport
	   * - handlesActivityCheck - true when the transport handles activity checks
	   * - supportsPing - true when the transport has a ping/activity API
	   * - isSupported - tells whether the transport is supported in the environment
	   * - getSocket - creates a WebSocket-compatible transport socket
	   *
	   * See transports.js for specific implementations.
	   *
	   * @param {Object} hooks object containing all needed transport hooks
	   */
	  function Transport(hooks) {
	    this.hooks = hooks;
	  }
	  var prototype = Transport.prototype;
	
	  /** Returns whether the transport is supported in the environment.
	   *
	   * @param {Object} environment the environment details (encryption, settings)
	   * @returns {Boolean} true when the transport is supported
	   */
	  prototype.isSupported = function(environment) {
	    return this.hooks.isSupported(environment);
	  };
	
	  /** Creates a transport connection.
	   *
	   * @param {String} name
	   * @param {Number} priority
	   * @param {String} key the application key
	   * @param {Object} options
	   * @returns {TransportConnection}
	   */
	  prototype.createConnection = function(name, priority, key, options) {
	    return new Pusher.TransportConnection(
	      this.hooks, name, priority, key, options
	    );
	  };
	
	  Pusher.Transport = Transport;
	}).call(this);
	
	(function() {
	  /** WebSocket transport.
	   *
	   * Uses native WebSocket implementation, including MozWebSocket supported by
	   * earlier Firefox versions.
	   */
	  Pusher.WSTransport = new Pusher.Transport({
	    urls: Pusher.URLSchemes.ws,
	    handlesActivityChecks: false,
	    supportsPing: false,
	
	    isInitialized: function() {
	      return Boolean(window.WebSocket || window.MozWebSocket);
	    },
	    isSupported: function() {
	      return Boolean(window.WebSocket || window.MozWebSocket);
	    },
	    getSocket: function(url) {
	      var Constructor = window.WebSocket || window.MozWebSocket;
	      return new Constructor(url);
	    }
	  });
	
	  /** Flash transport using the WebSocket protocol. */
	  Pusher.FlashTransport = new Pusher.Transport({
	    file: "flashfallback",
	    urls: Pusher.URLSchemes.flash,
	    handlesActivityChecks: false,
	    supportsPing: false,
	
	    isSupported: function() {
	      try {
	        return Boolean(new ActiveXObject('ShockwaveFlash.ShockwaveFlash'));
	      } catch (e1) {
	        try {
	          var nav = Pusher.Util.getNavigator();
	          return Boolean(
	            nav &&
	            nav.mimeTypes &&
	            nav.mimeTypes["application/x-shockwave-flash"] !== undefined
	          );
	        } catch (e2) {
	          return false;
	        }
	      }
	    },
	    beforeInitialize: function() {
	      if (window.WEB_SOCKET_SUPPRESS_CROSS_DOMAIN_SWF_ERROR === undefined) {
	        window.WEB_SOCKET_SUPPRESS_CROSS_DOMAIN_SWF_ERROR = true;
	      }
	      window.WEB_SOCKET_SWF_LOCATION =
	        Pusher.Dependencies.getRoot({ encrypted: this.options.encrypted }) +
	        "/WebSocketMain.swf";
	    },
	    isInitialized: function() {
	      return window.FlashWebSocket !== undefined;
	    },
	    getSocket: function(url) {
	      return new FlashWebSocket(url);
	    }
	  });
	
	  /** SockJS transport. */
	  Pusher.SockJSTransport = new Pusher.Transport({
	    file: "sockjs",
	    urls: Pusher.URLSchemes.sockjs,
	    handlesActivityChecks: true,
	    supportsPing: false,
	
	    isSupported: function() {
	      return true;
	    },
	    isInitialized: function() {
	      return window.SockJS !== undefined;
	    },
	    getSocket: function(url, options) {
	      return new SockJS(url, null, {
	        js_path: Pusher.Dependencies.getPath("sockjs", {
	          encrypted: options.encrypted
	        }),
	        ignore_null_origin: options.ignoreNullOrigin
	      });
	    },
	    beforeOpen: function(socket, path) {
	      socket.send(JSON.stringify({
	        path: path
	      }));
	    }
	  });
	
	  var httpConfiguration = {
	    urls: Pusher.URLSchemes.http,
	    handlesActivityChecks: false,
	    supportsPing: true,
	    isInitialized: function() {
	      return Boolean(Pusher.HTTP.Socket);
	    }
	  };
	
	  var streamingConfiguration = Pusher.Util.extend(
	    { getSocket: function(url) {
	        return Pusher.HTTP.getStreamingSocket(url);
	      }
	    },
	    httpConfiguration
	  );
	  var pollingConfiguration = Pusher.Util.extend(
	    { getSocket: function(url) {
	        return Pusher.HTTP.getPollingSocket(url);
	      }
	    },
	    httpConfiguration
	  );
	
	  var xhrConfiguration = {
	    file: "xhr",
	    isSupported: Pusher.Util.isXHRSupported
	  };
	  var xdrConfiguration = {
	    file: "xdr",
	    isSupported: function(environment) {
	      return Pusher.Util.isXDRSupported(environment.encrypted);
	    }
	  };
	
	  /** HTTP streaming transport using CORS-enabled XMLHttpRequest. */
	  Pusher.XHRStreamingTransport = new Pusher.Transport(
	    Pusher.Util.extend({}, streamingConfiguration, xhrConfiguration)
	  );
	  /** HTTP streaming transport using XDomainRequest (IE 8,9). */
	  Pusher.XDRStreamingTransport = new Pusher.Transport(
	    Pusher.Util.extend({}, streamingConfiguration, xdrConfiguration)
	  );
	  /** HTTP long-polling transport using CORS-enabled XMLHttpRequest. */
	  Pusher.XHRPollingTransport = new Pusher.Transport(
	    Pusher.Util.extend({}, pollingConfiguration, xhrConfiguration)
	  );
	  /** HTTP long-polling transport using XDomainRequest (IE 8,9). */
	  Pusher.XDRPollingTransport = new Pusher.Transport(
	    Pusher.Util.extend({}, pollingConfiguration, xdrConfiguration)
	  );
	}).call(this);
	
	;(function() {
	  /** Creates transport connections monitored by a transport manager.
	   *
	   * When a transport is closed, it might mean the environment does not support
	   * it. It's possible that messages get stuck in an intermediate buffer or
	   * proxies terminate inactive connections. To combat these problems,
	   * assistants monitor the connection lifetime, report unclean exits and
	   * adjust ping timeouts to keep the connection active. The decision to disable
	   * a transport is the manager's responsibility.
	   *
	   * @param {TransportManager} manager
	   * @param {TransportConnection} transport
	   * @param {Object} options
	   */
	  function AssistantToTheTransportManager(manager, transport, options) {
	    this.manager = manager;
	    this.transport = transport;
	    this.minPingDelay = options.minPingDelay;
	    this.maxPingDelay = options.maxPingDelay;
	    this.pingDelay = undefined;
	  }
	  var prototype = AssistantToTheTransportManager.prototype;
	
	  /** Creates a transport connection.
	   *
	   * This function has the same API as Transport#createConnection.
	   *
	   * @param {String} name
	   * @param {Number} priority
	   * @param {String} key the application key
	   * @param {Object} options
	   * @returns {TransportConnection}
	   */
	  prototype.createConnection = function(name, priority, key, options) {
	    var self = this;
	
	    options = Pusher.Util.extend({}, options, {
	      activityTimeout: self.pingDelay
	    });
	    var connection = self.transport.createConnection(
	      name, priority, key, options
	    );
	
	    var openTimestamp = null;
	
	    var onOpen = function() {
	      connection.unbind("open", onOpen);
	      connection.bind("closed", onClosed);
	      openTimestamp = Pusher.Util.now();
	    };
	    var onClosed = function(closeEvent) {
	      connection.unbind("closed", onClosed);
	
	      if (closeEvent.code === 1002 || closeEvent.code === 1003) {
	        // we don't want to use transports not obeying the protocol
	        self.manager.reportDeath();
	      } else if (!closeEvent.wasClean && openTimestamp) {
	        // report deaths only for short-living transport
	        var lifespan = Pusher.Util.now() - openTimestamp;
	        if (lifespan < 2 * self.maxPingDelay) {
	          self.manager.reportDeath();
	          self.pingDelay = Math.max(lifespan / 2, self.minPingDelay);
	        }
	      }
	    };
	
	    connection.bind("open", onOpen);
	    return connection;
	  };
	
	  /** Returns whether the transport is supported in the environment.
	   *
	   * This function has the same API as Transport#isSupported. Might return false
	   * when the manager decides to kill the transport.
	   *
	   * @param {Object} environment the environment details (encryption, settings)
	   * @returns {Boolean} true when the transport is supported
	   */
	  prototype.isSupported = function(environment) {
	    return this.manager.isAlive() && this.transport.isSupported(environment);
	  };
	
	  Pusher.AssistantToTheTransportManager = AssistantToTheTransportManager;
	}).call(this);
	
	;(function() {
	  /** Keeps track of the number of lives left for a transport.
	   *
	   * In the beginning of a session, transports may be assigned a number of
	   * lives. When an AssistantToTheTransportManager instance reports a transport
	   * connection closed uncleanly, the transport loses a life. When the number
	   * of lives drops to zero, the transport gets disabled by its manager.
	   *
	   * @param {Object} options
	   */
	  function TransportManager(options) {
	    this.options = options || {};
	    this.livesLeft = this.options.lives || Infinity;
	  }
	  var prototype = TransportManager.prototype;
	
	  /** Creates a assistant for the transport.
	   *
	   * @param {Transport} transport
	   * @returns {AssistantToTheTransportManager}
	   */
	  prototype.getAssistant = function(transport) {
	    return new Pusher.AssistantToTheTransportManager(this, transport, {
	      minPingDelay: this.options.minPingDelay,
	      maxPingDelay: this.options.maxPingDelay
	    });
	  };
	
	  /** Returns whether the transport has any lives left.
	   *
	   * @returns {Boolean}
	   */
	  prototype.isAlive = function() {
	    return this.livesLeft > 0;
	  };
	
	  /** Takes one life from the transport. */
	  prototype.reportDeath = function() {
	    this.livesLeft -= 1;
	  };
	
	  Pusher.TransportManager = TransportManager;
	}).call(this);
	
	;(function() {
	  var StrategyBuilder = {
	    /** Transforms a JSON scheme to a strategy tree.
	     *
	     * @param {Array} scheme JSON strategy scheme
	     * @param {Object} options a hash of symbols to be included in the scheme
	     * @returns {Strategy} strategy tree that's represented by the scheme
	     */
	    build: function(scheme, options) {
	      var context = Pusher.Util.extend({}, globalContext, options);
	      return evaluate(scheme, context)[1].strategy;
	    }
	  };
	
	  var transports = {
	    ws: Pusher.WSTransport,
	    flash: Pusher.FlashTransport,
	    sockjs: Pusher.SockJSTransport,
	    xhr_streaming: Pusher.XHRStreamingTransport,
	    xdr_streaming: Pusher.XDRStreamingTransport,
	    xhr_polling: Pusher.XHRPollingTransport,
	    xdr_polling: Pusher.XDRPollingTransport
	  };
	
	  var UnsupportedStrategy = {
	    isSupported: function() {
	      return false;
	    },
	    connect: function(_, callback) {
	      var deferred = Pusher.Util.defer(function() {
	        callback(new Pusher.Errors.UnsupportedStrategy());
	      });
	      return {
	        abort: function() {
	          deferred.ensureAborted();
	        },
	        forceMinPriority: function() {}
	      };
	    }
	  };
	
	  // DSL bindings
	
	  function returnWithOriginalContext(f) {
	    return function(context) {
	      return [f.apply(this, arguments), context];
	    };
	  }
	
	  var globalContext = {
	    extend: function(context, first, second) {
	      return [Pusher.Util.extend({}, first, second), context];
	    },
	
	    def: function(context, name, value) {
	      if (context[name] !== undefined) {
	        throw "Redefining symbol " + name;
	      }
	      context[name] = value;
	      return [undefined, context];
	    },
	
	    def_transport: function(context, name, type, priority, options, manager) {
	      var transportClass = transports[type];
	      if (!transportClass) {
	        throw new Pusher.Errors.UnsupportedTransport(type);
	      }
	
	      var enabled =
	        (!context.enabledTransports ||
	          Pusher.Util.arrayIndexOf(context.enabledTransports, name) !== -1) &&
	        (!context.disabledTransports ||
	          Pusher.Util.arrayIndexOf(context.disabledTransports, name) === -1) &&
	        (name !== "flash" || context.disableFlash !== true);
	
	      var transport;
	      if (enabled) {
	        transport = new Pusher.TransportStrategy(
	          name,
	          priority,
	          manager ? manager.getAssistant(transportClass) : transportClass,
	          Pusher.Util.extend({
	            key: context.key,
	            encrypted: context.encrypted,
	            timeline: context.timeline,
	            ignoreNullOrigin: context.ignoreNullOrigin
	          }, options)
	        );
	      } else {
	        transport = UnsupportedStrategy;
	      }
	
	      var newContext = context.def(context, name, transport)[1];
	      newContext.transports = context.transports || {};
	      newContext.transports[name] = transport;
	      return [undefined, newContext];
	    },
	
	    transport_manager: returnWithOriginalContext(function(_, options) {
	      return new Pusher.TransportManager(options);
	    }),
	
	    sequential: returnWithOriginalContext(function(_, options) {
	      var strategies = Array.prototype.slice.call(arguments, 2);
	      return new Pusher.SequentialStrategy(strategies, options);
	    }),
	
	    cached: returnWithOriginalContext(function(context, ttl, strategy){
	      return new Pusher.CachedStrategy(strategy, context.transports, {
	        ttl: ttl,
	        timeline: context.timeline,
	        encrypted: context.encrypted
	      });
	    }),
	
	    first_connected: returnWithOriginalContext(function(_, strategy) {
	      return new Pusher.FirstConnectedStrategy(strategy);
	    }),
	
	    best_connected_ever: returnWithOriginalContext(function() {
	      var strategies = Array.prototype.slice.call(arguments, 1);
	      return new Pusher.BestConnectedEverStrategy(strategies);
	    }),
	
	    delayed: returnWithOriginalContext(function(_, delay, strategy) {
	      return new Pusher.DelayedStrategy(strategy, { delay: delay });
	    }),
	
	    "if": returnWithOriginalContext(function(_, test, trueBranch, falseBranch) {
	      return new Pusher.IfStrategy(test, trueBranch, falseBranch);
	    }),
	
	    is_supported: returnWithOriginalContext(function(_, strategy) {
	      return function() {
	        return strategy.isSupported();
	      };
	    })
	  };
	
	  // DSL interpreter
	
	  function isSymbol(expression) {
	    return (typeof expression === "string") && expression.charAt(0) === ":";
	  }
	
	  function getSymbolValue(expression, context) {
	    return context[expression.slice(1)];
	  }
	
	  function evaluateListOfExpressions(expressions, context) {
	    if (expressions.length === 0) {
	      return [[], context];
	    }
	    var head = evaluate(expressions[0], context);
	    var tail = evaluateListOfExpressions(expressions.slice(1), head[1]);
	    return [[head[0]].concat(tail[0]), tail[1]];
	  }
	
	  function evaluateString(expression, context) {
	    if (!isSymbol(expression)) {
	      return [expression, context];
	    }
	    var value = getSymbolValue(expression, context);
	    if (value === undefined) {
	      throw "Undefined symbol " + expression;
	    }
	    return [value, context];
	  }
	
	  function evaluateArray(expression, context) {
	    if (isSymbol(expression[0])) {
	      var f = getSymbolValue(expression[0], context);
	      if (expression.length > 1) {
	        if (typeof f !== "function") {
	          throw "Calling non-function " + expression[0];
	        }
	        var args = [Pusher.Util.extend({}, context)].concat(
	          Pusher.Util.map(expression.slice(1), function(arg) {
	            return evaluate(arg, Pusher.Util.extend({}, context))[0];
	          })
	        );
	        return f.apply(this, args);
	      } else {
	        return [f, context];
	      }
	    } else {
	      return evaluateListOfExpressions(expression, context);
	    }
	  }
	
	  function evaluate(expression, context) {
	    var expressionType = typeof expression;
	    if (typeof expression === "string") {
	      return evaluateString(expression, context);
	    } else if (typeof expression === "object") {
	      if (expression instanceof Array && expression.length > 0) {
	        return evaluateArray(expression, context);
	      }
	    }
	    return [expression, context];
	  }
	
	  Pusher.StrategyBuilder = StrategyBuilder;
	}).call(this);
	
	;(function() {
	  /**
	   * Provides functions for handling Pusher protocol-specific messages.
	   */
	  var Protocol = {};
	
	  /**
	   * Decodes a message in a Pusher format.
	   *
	   * Throws errors when messages are not parse'able.
	   *
	   * @param  {Object} message
	   * @return {Object}
	   */
	  Protocol.decodeMessage = function(message) {
	    try {
	      var params = JSON.parse(message.data);
	      if (typeof params.data === 'string') {
	        try {
	          params.data = JSON.parse(params.data);
	        } catch (e) {
	          if (!(e instanceof SyntaxError)) {
	            // TODO looks like unreachable code
	            // https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/JSON/parse
	            throw e;
	          }
	        }
	      }
	      return params;
	    } catch (e) {
	      throw { type: 'MessageParseError', error: e, data: message.data};
	    }
	  };
	
	  /**
	   * Encodes a message to be sent.
	   *
	   * @param  {Object} message
	   * @return {String}
	   */
	  Protocol.encodeMessage = function(message) {
	    return JSON.stringify(message);
	  };
	
	  /** Processes a handshake message and returns appropriate actions.
	   *
	   * Returns an object with an 'action' and other action-specific properties.
	   *
	   * There are three outcomes when calling this function. First is a successful
	   * connection attempt, when pusher:connection_established is received, which
	   * results in a 'connected' action with an 'id' property. When passed a
	   * pusher:error event, it returns a result with action appropriate to the
	   * close code and an error. Otherwise, it raises an exception.
	   *
	   * @param {String} message
	   * @result Object
	   */
	  Protocol.processHandshake = function(message) {
	    message = this.decodeMessage(message);
	
	    if (message.event === "pusher:connection_established") {
	      if (!message.data.activity_timeout) {
	        throw "No activity timeout specified in handshake";
	      }
	      return {
	        action: "connected",
	        id: message.data.socket_id,
	        activityTimeout: message.data.activity_timeout * 1000
	      };
	    } else if (message.event === "pusher:error") {
	      // From protocol 6 close codes are sent only once, so this only
	      // happens when connection does not support close codes
	      return {
	        action: this.getCloseAction(message.data),
	        error: this.getCloseError(message.data)
	      };
	    } else {
	      throw "Invalid handshake";
	    }
	  };
	
	  /**
	   * Dispatches the close event and returns an appropriate action name.
	   *
	   * See:
	   * 1. https://developer.mozilla.org/en-US/docs/WebSockets/WebSockets_reference/CloseEvent
	   * 2. http://pusher.com/docs/pusher_protocol
	   *
	   * @param  {CloseEvent} closeEvent
	   * @return {String} close action name
	   */
	  Protocol.getCloseAction = function(closeEvent) {
	    if (closeEvent.code < 4000) {
	      // ignore 1000 CLOSE_NORMAL, 1001 CLOSE_GOING_AWAY,
	      //        1005 CLOSE_NO_STATUS, 1006 CLOSE_ABNORMAL
	      // ignore 1007...3999
	      // handle 1002 CLOSE_PROTOCOL_ERROR, 1003 CLOSE_UNSUPPORTED,
	      //        1004 CLOSE_TOO_LARGE
	      if (closeEvent.code >= 1002 && closeEvent.code <= 1004) {
	        return "backoff";
	      } else {
	        return null;
	      }
	    } else if (closeEvent.code === 4000) {
	      return "ssl_only";
	    } else if (closeEvent.code < 4100) {
	      return "refused";
	    } else if (closeEvent.code < 4200) {
	      return "backoff";
	    } else if (closeEvent.code < 4300) {
	      return "retry";
	    } else {
	      // unknown error
	      return "refused";
	    }
	  };
	
	  /**
	   * Returns an error or null basing on the close event.
	   *
	   * Null is returned when connection was closed cleanly. Otherwise, an object
	   * with error details is returned.
	   *
	   * @param  {CloseEvent} closeEvent
	   * @return {Object} error object
	   */
	  Protocol.getCloseError = function(closeEvent) {
	    if (closeEvent.code !== 1000 && closeEvent.code !== 1001) {
	      return {
	        type: 'PusherError',
	        data: {
	          code: closeEvent.code,
	          message: closeEvent.reason || closeEvent.message
	        }
	      };
	    } else {
	      return null;
	    }
	  };
	
	  Pusher.Protocol = Protocol;
	}).call(this);
	
	;(function() {
	  /**
	   * Provides Pusher protocol interface for transports.
	   *
	   * Emits following events:
	   * - message - on received messages
	   * - ping - on ping requests
	   * - pong - on pong responses
	   * - error - when the transport emits an error
	   * - closed - after closing the transport
	   *
	   * It also emits more events when connection closes with a code.
	   * See Protocol.getCloseAction to get more details.
	   *
	   * @param {Number} id
	   * @param {AbstractTransport} transport
	   */
	  function Connection(id, transport) {
	    Pusher.EventsDispatcher.call(this);
	
	    this.id = id;
	    this.transport = transport;
	    this.activityTimeout = transport.activityTimeout;
	    this.bindListeners();
	  }
	  var prototype = Connection.prototype;
	  Pusher.Util.extend(prototype, Pusher.EventsDispatcher.prototype);
	
	  /** Returns whether used transport handles activity checks by itself
	   *
	   * @returns {Boolean} true if activity checks are handled by the transport
	   */
	  prototype.handlesActivityChecks = function() {
	    return this.transport.handlesActivityChecks();
	  };
	
	  /** Sends raw data.
	   *
	   * @param {String} data
	   */
	  prototype.send = function(data) {
	    return this.transport.send(data);
	  };
	
	  /** Sends an event.
	   *
	   * @param {String} name
	   * @param {String} data
	   * @param {String} [channel]
	   * @returns {Boolean} whether message was sent or not
	   */
	  prototype.send_event = function(name, data, channel) {
	    var message = { event: name, data: data };
	    if (channel) {
	      message.channel = channel;
	    }
	    Pusher.debug('Event sent', message);
	    return this.send(Pusher.Protocol.encodeMessage(message));
	  };
	
	  /** Sends a ping message to the server.
	   *
	   * Basing on the underlying transport, it might send either transport's
	   * protocol-specific ping or pusher:ping event.
	   */
	  prototype.ping = function() {
	    if (this.transport.supportsPing()) {
	      this.transport.ping();
	    } else {
	      this.send_event('pusher:ping', {});
	    }
	  };
	
	  /** Closes the connection. */
	  prototype.close = function() {
	    this.transport.close();
	  };
	
	  /** @private */
	  prototype.bindListeners = function() {
	    var self = this;
	
	    var listeners = {
	      message: function(m) {
	        var message;
	        try {
	          message = Pusher.Protocol.decodeMessage(m);
	        } catch(e) {
	          self.emit('error', {
	            type: 'MessageParseError',
	            error: e,
	            data: m.data
	          });
	        }
	
	        if (message !== undefined) {
	          Pusher.debug('Event recd', message);
	
	          switch (message.event) {
	            case 'pusher:error':
	              self.emit('error', { type: 'PusherError', data: message.data });
	              break;
	            case 'pusher:ping':
	              self.emit("ping");
	              break;
	            case 'pusher:pong':
	              self.emit("pong");
	              break;
	          }
	          self.emit('message', message);
	        }
	      },
	      activity: function() {
	        self.emit("activity");
	      },
	      error: function(error) {
	        self.emit("error", { type: "WebSocketError", error: error });
	      },
	      closed: function(closeEvent) {
	        unbindListeners();
	
	        if (closeEvent && closeEvent.code) {
	          self.handleCloseEvent(closeEvent);
	        }
	
	        self.transport = null;
	        self.emit("closed");
	      }
	    };
	
	    var unbindListeners = function() {
	      Pusher.Util.objectApply(listeners, function(listener, event) {
	        self.transport.unbind(event, listener);
	      });
	    };
	
	    Pusher.Util.objectApply(listeners, function(listener, event) {
	      self.transport.bind(event, listener);
	    });
	  };
	
	  /** @private */
	  prototype.handleCloseEvent = function(closeEvent) {
	    var action = Pusher.Protocol.getCloseAction(closeEvent);
	    var error = Pusher.Protocol.getCloseError(closeEvent);
	    if (error) {
	      this.emit('error', error);
	    }
	    if (action) {
	      this.emit(action);
	    }
	  };
	
	  Pusher.Connection = Connection;
	}).call(this);
	
	;(function() {
	  /**
	   * Handles Pusher protocol handshakes for transports.
	   *
	   * Calls back with a result object after handshake is completed. Results
	   * always have two fields:
	   * - action - string describing action to be taken after the handshake
	   * - transport - the transport object passed to the constructor
	   *
	   * Different actions can set different additional properties on the result.
	   * In the case of 'connected' action, there will be a 'connection' property
	   * containing a Connection object for the transport. Other actions should
	   * carry an 'error' property.
	   *
	   * @param {AbstractTransport} transport
	   * @param {Function} callback
	   */
	  function Handshake(transport, callback) {
	    this.transport = transport;
	    this.callback = callback;
	    this.bindListeners();
	  }
	  var prototype = Handshake.prototype;
	
	  prototype.close = function() {
	    this.unbindListeners();
	    this.transport.close();
	  };
	
	  /** @private */
	  prototype.bindListeners = function() {
	    var self = this;
	
	    self.onMessage = function(m) {
	      self.unbindListeners();
	
	      try {
	        var result = Pusher.Protocol.processHandshake(m);
	        if (result.action === "connected") {
	          self.finish("connected", {
	            connection: new Pusher.Connection(result.id, self.transport),
	            activityTimeout: result.activityTimeout
	          });
	        } else {
	          self.finish(result.action, { error: result.error });
	          self.transport.close();
	        }
	      } catch (e) {
	        self.finish("error", { error: e });
	        self.transport.close();
	      }
	    };
	
	    self.onClosed = function(closeEvent) {
	      self.unbindListeners();
	
	      var action = Pusher.Protocol.getCloseAction(closeEvent) || "backoff";
	      var error = Pusher.Protocol.getCloseError(closeEvent);
	      self.finish(action, { error: error });
	    };
	
	    self.transport.bind("message", self.onMessage);
	    self.transport.bind("closed", self.onClosed);
	  };
	
	  /** @private */
	  prototype.unbindListeners = function() {
	    this.transport.unbind("message", this.onMessage);
	    this.transport.unbind("closed", this.onClosed);
	  };
	
	  /** @private */
	  prototype.finish = function(action, params) {
	    this.callback(
	      Pusher.Util.extend({ transport: this.transport, action: action }, params)
	    );
	  };
	
	  Pusher.Handshake = Handshake;
	}).call(this);
	
	;(function() {
	  /** Manages connection to Pusher.
	   *
	   * Uses a strategy (currently only default), timers and network availability
	   * info to establish a connection and export its state. In case of failures,
	   * manages reconnection attempts.
	   *
	   * Exports state changes as following events:
	   * - "state_change", { previous: p, current: state }
	   * - state
	   *
	   * States:
	   * - initialized - initial state, never transitioned to
	   * - connecting - connection is being established
	   * - connected - connection has been fully established
	   * - disconnected - on requested disconnection
	   * - unavailable - after connection timeout or when there's no network
	   * - failed - when the connection strategy is not supported
	   *
	   * Options:
	   * - unavailableTimeout - time to transition to unavailable state
	   * - activityTimeout - time after which ping message should be sent
	   * - pongTimeout - time for Pusher to respond with pong before reconnecting
	   *
	   * @param {String} key application key
	   * @param {Object} options
	   */
	  function ConnectionManager(key, options) {
	    Pusher.EventsDispatcher.call(this);
	
	    this.key = key;
	    this.options = options || {};
	    this.state = "initialized";
	    this.connection = null;
	    this.encrypted = !!options.encrypted;
	    this.timeline = this.options.timeline;
	
	    this.connectionCallbacks = this.buildConnectionCallbacks();
	    this.errorCallbacks = this.buildErrorCallbacks();
	    this.handshakeCallbacks = this.buildHandshakeCallbacks(this.errorCallbacks);
	
	    var self = this;
	
	    Pusher.Network.bind("online", function() {
	      self.timeline.info({ netinfo: "online" });
	      if (self.state === "connecting" || self.state === "unavailable") {
	        self.retryIn(0);
	      }
	    });
	    Pusher.Network.bind("offline", function() {
	      self.timeline.info({ netinfo: "offline" });
	      if (self.connection) {
	        self.sendActivityCheck();
	      }
	    });
	
	    this.updateStrategy();
	  }
	  var prototype = ConnectionManager.prototype;
	
	  Pusher.Util.extend(prototype, Pusher.EventsDispatcher.prototype);
	
	  /** Establishes a connection to Pusher.
	   *
	   * Does nothing when connection is already established. See top-level doc
	   * to find events emitted on connection attempts.
	   */
	  prototype.connect = function() {
	    if (this.connection || this.runner) {
	      return;
	    }
	    if (!this.strategy.isSupported()) {
	      this.updateState("failed");
	      return;
	    }
	    this.updateState("connecting");
	    this.startConnecting();
	    this.setUnavailableTimer();
	  };
	
	  /** Sends raw data.
	   *
	   * @param {String} data
	   */
	  prototype.send = function(data) {
	    if (this.connection) {
	      return this.connection.send(data);
	    } else {
	      return false;
	    }
	  };
	
	  /** Sends an event.
	   *
	   * @param {String} name
	   * @param {String} data
	   * @param {String} [channel]
	   * @returns {Boolean} whether message was sent or not
	   */
	  prototype.send_event = function(name, data, channel) {
	    if (this.connection) {
	      return this.connection.send_event(name, data, channel);
	    } else {
	      return false;
	    }
	  };
	
	  /** Closes the connection. */
	  prototype.disconnect = function() {
	    this.disconnectInternally();
	    this.updateState("disconnected");
	  };
	
	  prototype.isEncrypted = function() {
	    return this.encrypted;
	  };
	
	  /** @private */
	  prototype.startConnecting = function() {
	    var self = this;
	    var callback = function(error, handshake) {
	      if (error) {
	        self.runner = self.strategy.connect(0, callback);
	      } else {
	        if (handshake.action === "error") {
	          self.emit("error", { type: "HandshakeError", error: handshake.error });
	          self.timeline.error({ handshakeError: handshake.error });
	        } else {
	          self.abortConnecting(); // we don't support switching connections yet
	          self.handshakeCallbacks[handshake.action](handshake);
	        }
	      }
	    };
	    self.runner = self.strategy.connect(0, callback);
	  };
	
	  /** @private */
	  prototype.abortConnecting = function() {
	    if (this.runner) {
	      this.runner.abort();
	      this.runner = null;
	    }
	  };
	
	  /** @private */
	  prototype.disconnectInternally = function() {
	    this.abortConnecting();
	    this.clearRetryTimer();
	    this.clearUnavailableTimer();
	    if (this.connection) {
	      var connection = this.abandonConnection();
	      connection.close();
	    }
	  };
	
	  /** @private */
	  prototype.updateStrategy = function() {
	    this.strategy = this.options.getStrategy({
	      key: this.key,
	      timeline: this.timeline,
	      encrypted: this.encrypted
	    });
	  };
	
	  /** @private */
	  prototype.retryIn = function(delay) {
	    var self = this;
	    self.timeline.info({ action: "retry", delay: delay });
	    if (delay > 0) {
	      self.emit("connecting_in", Math.round(delay / 1000));
	    }
	    self.retryTimer = new Pusher.Timer(delay || 0, function() {
	      self.disconnectInternally();
	      self.connect();
	    });
	  };
	
	  /** @private */
	  prototype.clearRetryTimer = function() {
	    if (this.retryTimer) {
	      this.retryTimer.ensureAborted();
	      this.retryTimer = null;
	    }
	  };
	
	  /** @private */
	  prototype.setUnavailableTimer = function() {
	    var self = this;
	    self.unavailableTimer = new Pusher.Timer(
	      self.options.unavailableTimeout,
	      function() {
	        self.updateState("unavailable");
	      }
	    );
	  };
	
	  /** @private */
	  prototype.clearUnavailableTimer = function() {
	    if (this.unavailableTimer) {
	      this.unavailableTimer.ensureAborted();
	    }
	  };
	
	  /** @private */
	  prototype.sendActivityCheck = function() {
	    var self = this;
	    self.stopActivityCheck();
	    self.connection.ping();
	    // wait for pong response
	    self.activityTimer = new Pusher.Timer(
	      self.options.pongTimeout,
	      function() {
	        self.timeline.error({ pong_timed_out: self.options.pongTimeout });
	        self.retryIn(0);
	      }
	    );
	  };
	
	  /** @private */
	  prototype.resetActivityCheck = function() {
	    var self = this;
	    self.stopActivityCheck();
	    // send ping after inactivity
	    if (!self.connection.handlesActivityChecks()) {
	      self.activityTimer = new Pusher.Timer(self.activityTimeout, function() {
	        self.sendActivityCheck();
	      });
	    }
	  };
	
	  /** @private */
	  prototype.stopActivityCheck = function() {
	    if (this.activityTimer) {
	      this.activityTimer.ensureAborted();
	    }
	  };
	
	  /** @private */
	  prototype.buildConnectionCallbacks = function() {
	    var self = this;
	    return {
	      message: function(message) {
	        // includes pong messages from server
	        self.resetActivityCheck();
	        self.emit('message', message);
	      },
	      ping: function() {
	        self.send_event('pusher:pong', {});
	      },
	      activity: function() {
	        self.resetActivityCheck();
	      },
	      error: function(error) {
	        // just emit error to user - socket will already be closed by browser
	        self.emit("error", { type: "WebSocketError", error: error });
	      },
	      closed: function() {
	        self.abandonConnection();
	        if (self.shouldRetry()) {
	          self.retryIn(1000);
	        }
	      }
	    };
	  };
	
	  /** @private */
	  prototype.buildHandshakeCallbacks = function(errorCallbacks) {
	    var self = this;
	    return Pusher.Util.extend({}, errorCallbacks, {
	      connected: function(handshake) {
	        self.activityTimeout = Math.min(
	          self.options.activityTimeout,
	          handshake.activityTimeout,
	          handshake.connection.activityTimeout || Infinity
	        );
	        self.clearUnavailableTimer();
	        self.setConnection(handshake.connection);
	        self.socket_id = self.connection.id;
	        self.updateState("connected", { socket_id: self.socket_id });
	      }
	    });
	  };
	
	  /** @private */
	  prototype.buildErrorCallbacks = function() {
	    var self = this;
	
	    function withErrorEmitted(callback) {
	      return function(result) {
	        if (result.error) {
	          self.emit("error", { type: "WebSocketError", error: result.error });
	        }
	        callback(result);
	      };
	    }
	
	    return {
	      ssl_only: withErrorEmitted(function() {
	        self.encrypted = true;
	        self.updateStrategy();
	        self.retryIn(0);
	      }),
	      refused: withErrorEmitted(function() {
	        self.disconnect();
	      }),
	      backoff: withErrorEmitted(function() {
	        self.retryIn(1000);
	      }),
	      retry: withErrorEmitted(function() {
	        self.retryIn(0);
	      })
	    };
	  };
	
	  /** @private */
	  prototype.setConnection = function(connection) {
	    this.connection = connection;
	    for (var event in this.connectionCallbacks) {
	      this.connection.bind(event, this.connectionCallbacks[event]);
	    }
	    this.resetActivityCheck();
	  };
	
	  /** @private */
	  prototype.abandonConnection = function() {
	    if (!this.connection) {
	      return;
	    }
	    this.stopActivityCheck();
	    for (var event in this.connectionCallbacks) {
	      this.connection.unbind(event, this.connectionCallbacks[event]);
	    }
	    var connection = this.connection;
	    this.connection = null;
	    return connection;
	  };
	
	  /** @private */
	  prototype.updateState = function(newState, data) {
	    var previousState = this.state;
	    this.state = newState;
	    if (previousState !== newState) {
	      Pusher.debug('State changed', previousState + ' -> ' + newState);
	      this.timeline.info({ state: newState, params: data });
	      this.emit('state_change', { previous: previousState, current: newState });
	      this.emit(newState, data);
	    }
	  };
	
	  /** @private */
	  prototype.shouldRetry = function() {
	    return this.state === "connecting" || this.state === "connected";
	  };
	
	  Pusher.ConnectionManager = ConnectionManager;
	}).call(this);
	
	;(function() {
	  /** Really basic interface providing network availability info.
	   *
	   * Emits:
	   * - online - when browser goes online
	   * - offline - when browser goes offline
	   */
	  function NetInfo() {
	    Pusher.EventsDispatcher.call(this);
	
	    var self = this;
	    // This is okay, as IE doesn't support this stuff anyway.
	    if (window.addEventListener !== undefined) {
	      window.addEventListener("online", function() {
	        self.emit('online');
	      }, false);
	      window.addEventListener("offline", function() {
	        self.emit('offline');
	      }, false);
	    }
	  }
	  Pusher.Util.extend(NetInfo.prototype, Pusher.EventsDispatcher.prototype);
	
	  var prototype = NetInfo.prototype;
	
	  /** Returns whether browser is online or not
	   *
	   * Offline means definitely offline (no connection to router).
	   * Inverse does NOT mean definitely online (only currently supported in Safari
	   * and even there only means the device has a connection to the router).
	   *
	   * @return {Boolean}
	   */
	  prototype.isOnline = function() {
	    if (window.navigator.onLine === undefined) {
	      return true;
	    } else {
	      return window.navigator.onLine;
	    }
	  };
	
	  Pusher.NetInfo = NetInfo;
	  Pusher.Network = new NetInfo();
	}).call(this);
	
	;(function() {
	  /** Represents a collection of members of a presence channel. */
	  function Members() {
	    this.reset();
	  }
	  var prototype = Members.prototype;
	
	  /** Returns member's info for given id.
	   *
	   * Resulting object containts two fields - id and info.
	   *
	   * @param {Number} id
	   * @return {Object} member's info or null
	   */
	  prototype.get = function(id) {
	    if (Object.prototype.hasOwnProperty.call(this.members, id)) {
	      return {
	        id: id,
	        info: this.members[id]
	      };
	    } else {
	      return null;
	    }
	  };
	
	  /** Calls back for each member in unspecified order.
	   *
	   * @param  {Function} callback
	   */
	  prototype.each = function(callback) {
	    var self = this;
	    Pusher.Util.objectApply(self.members, function(member, id) {
	      callback(self.get(id));
	    });
	  };
	
	  /** Updates the id for connected member. For internal use only. */
	  prototype.setMyID = function(id) {
	    this.myID = id;
	  };
	
	  /** Handles subscription data. For internal use only. */
	  prototype.onSubscription = function(subscriptionData) {
	    this.members = subscriptionData.presence.hash;
	    this.count = subscriptionData.presence.count;
	    this.me = this.get(this.myID);
	  };
	
	  /** Adds a new member to the collection. For internal use only. */
	  prototype.addMember = function(memberData) {
	    if (this.get(memberData.user_id) === null) {
	      this.count++;
	    }
	    this.members[memberData.user_id] = memberData.user_info;
	    return this.get(memberData.user_id);
	  };
	
	  /** Adds a member from the collection. For internal use only. */
	  prototype.removeMember = function(memberData) {
	    var member = this.get(memberData.user_id);
	    if (member) {
	      delete this.members[memberData.user_id];
	      this.count--;
	    }
	    return member;
	  };
	
	  /** Resets the collection to the initial state. For internal use only. */
	  prototype.reset = function() {
	    this.members = {};
	    this.count = 0;
	    this.myID = null;
	    this.me = null;
	  };
	
	  Pusher.Members = Members;
	}).call(this);
	
	;(function() {
	  /** Provides base public channel interface with an event emitter.
	   *
	   * Emits:
	   * - pusher:subscription_succeeded - after subscribing successfully
	   * - other non-internal events
	   *
	   * @param {String} name
	   * @param {Pusher} pusher
	   */
	  function Channel(name, pusher) {
	    Pusher.EventsDispatcher.call(this, function(event, data) {
	      Pusher.debug('No callbacks on ' + name + ' for ' + event);
	    });
	
	    this.name = name;
	    this.pusher = pusher;
	    this.subscribed = false;
	  }
	  var prototype = Channel.prototype;
	  Pusher.Util.extend(prototype, Pusher.EventsDispatcher.prototype);
	
	  /** Skips authorization, since public channels don't require it.
	   *
	   * @param {Function} callback
	   */
	  prototype.authorize = function(socketId, callback) {
	    return callback(false, {});
	  };
	
	  /** Triggers an event */
	  prototype.trigger = function(event, data) {
	    if (event.indexOf("client-") !== 0) {
	      throw new Pusher.Errors.BadEventName(
	        "Event '" + event + "' does not start with 'client-'"
	      );
	    }
	    return this.pusher.send_event(event, data, this.name);
	  };
	
	  /** Signals disconnection to the channel. For internal use only. */
	  prototype.disconnect = function() {
	    this.subscribed = false;
	  };
	
	  /** Handles an event. For internal use only.
	   *
	   * @param {String} event
	   * @param {*} data
	   */
	  prototype.handleEvent = function(event, data) {
	    if (event.indexOf("pusher_internal:") === 0) {
	      if (event === "pusher_internal:subscription_succeeded") {
	        this.subscribed = true;
	        this.emit("pusher:subscription_succeeded", data);
	      }
	    } else {
	      this.emit(event, data);
	    }
	  };
	
	  /** Sends a subscription request. For internal use only. */
	  prototype.subscribe = function() {
	    var self = this;
	
	    self.authorize(self.pusher.connection.socket_id, function(error, data) {
	      if (error) {
	        self.handleEvent('pusher:subscription_error', data);
	      } else {
	        self.pusher.send_event('pusher:subscribe', {
	          auth: data.auth,
	          channel_data: data.channel_data,
	          channel: self.name
	        });
	      }
	    });
	  };
	
	  /** Sends an unsubscription request. For internal use only. */
	  prototype.unsubscribe = function() {
	    this.pusher.send_event('pusher:unsubscribe', {
	      channel: this.name
	    });
	  };
	
	  Pusher.Channel = Channel;
	}).call(this);
	
	;(function() {
	  /** Extends public channels to provide private channel interface.
	   *
	   * @param {String} name
	   * @param {Pusher} pusher
	   */
	  function PrivateChannel(name, pusher) {
	    Pusher.Channel.call(this, name, pusher);
	  }
	  var prototype = PrivateChannel.prototype;
	  Pusher.Util.extend(prototype, Pusher.Channel.prototype);
	
	  /** Authorizes the connection to use the channel.
	   *
	   * @param  {String} socketId
	   * @param  {Function} callback
	   */
	  prototype.authorize = function(socketId, callback) {
	    var authorizer = new Pusher.Channel.Authorizer(this, this.pusher.config);
	    return authorizer.authorize(socketId, callback);
	  };
	
	  Pusher.PrivateChannel = PrivateChannel;
	}).call(this);
	
	;(function() {
	  /** Adds presence channel functionality to private channels.
	   *
	   * @param {String} name
	   * @param {Pusher} pusher
	   */
	  function PresenceChannel(name, pusher) {
	    Pusher.PrivateChannel.call(this, name, pusher);
	    this.members = new Pusher.Members();
	  }
	  var prototype = PresenceChannel.prototype;
	  Pusher.Util.extend(prototype, Pusher.PrivateChannel.prototype);
	
	  /** Authenticates the connection as a member of the channel.
	   *
	   * @param  {String} socketId
	   * @param  {Function} callback
	   */
	  prototype.authorize = function(socketId, callback) {
	    var _super = Pusher.PrivateChannel.prototype.authorize;
	    var self = this;
	    _super.call(self, socketId, function(error, authData) {
	      if (!error) {
	        if (authData.channel_data === undefined) {
	          Pusher.warn(
	            "Invalid auth response for channel '" +
	            self.name +
	            "', expected 'channel_data' field"
	          );
	          callback("Invalid auth response");
	          return;
	        }
	        var channelData = JSON.parse(authData.channel_data);
	        self.members.setMyID(channelData.user_id);
	      }
	      callback(error, authData);
	    });
	  };
	
	  /** Handles presence and subscription events. For internal use only.
	   *
	   * @param {String} event
	   * @param {*} data
	   */
	  prototype.handleEvent = function(event, data) {
	    switch (event) {
	      case "pusher_internal:subscription_succeeded":
	        this.members.onSubscription(data);
	        this.subscribed = true;
	        this.emit("pusher:subscription_succeeded", this.members);
	        break;
	      case "pusher_internal:member_added":
	        var addedMember = this.members.addMember(data);
	        this.emit('pusher:member_added', addedMember);
	        break;
	      case "pusher_internal:member_removed":
	        var removedMember = this.members.removeMember(data);
	        if (removedMember) {
	          this.emit('pusher:member_removed', removedMember);
	        }
	        break;
	      default:
	        Pusher.PrivateChannel.prototype.handleEvent.call(this, event, data);
	    }
	  };
	
	  /** Resets the channel state, including members map. For internal use only. */
	  prototype.disconnect = function() {
	    this.members.reset();
	    Pusher.PrivateChannel.prototype.disconnect.call(this);
	  };
	
	  Pusher.PresenceChannel = PresenceChannel;
	}).call(this);
	
	;(function() {
	  /** Handles a channel map. */
	  function Channels() {
	    this.channels = {};
	  }
	  var prototype = Channels.prototype;
	
	  /** Creates or retrieves an existing channel by its name.
	   *
	   * @param {String} name
	   * @param {Pusher} pusher
	   * @return {Channel}
	   */
	  prototype.add = function(name, pusher) {
	    if (!this.channels[name]) {
	      this.channels[name] = createChannel(name, pusher);
	    }
	    return this.channels[name];
	  };
	
	  /** Returns a list of all channels
	   *
	   * @return {Array}
	   */
	  prototype.all = function(name) {
	    return Pusher.Util.values(this.channels);
	  };
	
	  /** Finds a channel by its name.
	   *
	   * @param {String} name
	   * @return {Channel} channel or null if it doesn't exist
	   */
	  prototype.find = function(name) {
	    return this.channels[name];
	  };
	
	  /** Removes a channel from the map.
	   *
	   * @param {String} name
	   */
	  prototype.remove = function(name) {
	    var channel = this.channels[name];
	    delete this.channels[name];
	    return channel;
	  };
	
	  /** Proxies disconnection signal to all channels. */
	  prototype.disconnect = function() {
	    Pusher.Util.objectApply(this.channels, function(channel) {
	      channel.disconnect();
	    });
	  };
	
	  function createChannel(name, pusher) {
	    if (name.indexOf('private-') === 0) {
	      return new Pusher.PrivateChannel(name, pusher);
	    } else if (name.indexOf('presence-') === 0) {
	      return new Pusher.PresenceChannel(name, pusher);
	    } else {
	      return new Pusher.Channel(name, pusher);
	    }
	  }
	
	  Pusher.Channels = Channels;
	}).call(this);
	
	;(function() {
	  Pusher.Channel.Authorizer = function(channel, options) {
	    this.channel = channel;
	    this.type = options.authTransport;
	
	    this.options = options;
	    this.authOptions = (options || {}).auth || {};
	  };
	
	  Pusher.Channel.Authorizer.prototype = {
	    composeQuery: function(socketId) {
	      var query = 'socket_id=' + encodeURIComponent(socketId) +
	        '&channel_name=' + encodeURIComponent(this.channel.name);
	
	      for(var i in this.authOptions.params) {
	        query += "&" + encodeURIComponent(i) + "=" + encodeURIComponent(this.authOptions.params[i]);
	      }
	
	      return query;
	    },
	
	    authorize: function(socketId, callback) {
	      return Pusher.authorizers[this.type].call(this, socketId, callback);
	    }
	  };
	
	  var nextAuthCallbackID = 1;
	
	  Pusher.auth_callbacks = {};
	  Pusher.authorizers = {
	    ajax: function(socketId, callback){
	      var self = this, xhr;
	
	      if (Pusher.XHR) {
	        xhr = new Pusher.XHR();
	      } else {
	        xhr = (window.XMLHttpRequest ? new window.XMLHttpRequest() : new ActiveXObject("Microsoft.XMLHTTP"));
	      }
	
	      xhr.open("POST", self.options.authEndpoint, true);
	
	      // add request headers
	      xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
	      for(var headerName in this.authOptions.headers) {
	        xhr.setRequestHeader(headerName, this.authOptions.headers[headerName]);
	      }
	
	      xhr.onreadystatechange = function() {
	        if (xhr.readyState === 4) {
	          if (xhr.status === 200) {
	            var data, parsed = false;
	
	            try {
	              data = JSON.parse(xhr.responseText);
	              parsed = true;
	            } catch (e) {
	              callback(true, 'JSON returned from webapp was invalid, yet status code was 200. Data was: ' + xhr.responseText);
	            }
	
	            if (parsed) { // prevents double execution.
	              callback(false, data);
	            }
	          } else {
	            Pusher.warn("Couldn't get auth info from your webapp", xhr.status);
	            callback(true, xhr.status);
	          }
	        }
	      };
	
	      xhr.send(this.composeQuery(socketId));
	      return xhr;
	    },
	
	    jsonp: function(socketId, callback){
	      if(this.authOptions.headers !== undefined) {
	        Pusher.warn("Warn", "To send headers with the auth request, you must use AJAX, rather than JSONP.");
	      }
	
	      var callbackName = nextAuthCallbackID.toString();
	      nextAuthCallbackID++;
	
	      var document = Pusher.Util.getDocument();
	      var script = document.createElement("script");
	      // Hacked wrapper.
	      Pusher.auth_callbacks[callbackName] = function(data) {
	        callback(false, data);
	      };
	
	      var callback_name = "Pusher.auth_callbacks['" + callbackName + "']";
	      script.src = this.options.authEndpoint +
	        '?callback=' +
	        encodeURIComponent(callback_name) +
	        '&' +
	        this.composeQuery(socketId);
	
	      var head = document.getElementsByTagName("head")[0] || document.documentElement;
	      head.insertBefore( script, head.firstChild );
	    }
	  };
	}).call(this);
	
	
	
	/*** EXPORTS FROM exports-loader ***/
	module.exports = this.Pusher
	}.call(window));

/***/ },

/***/ 1187:
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	
	desktopApprovalButtonDirective.$inject = ["$modal", "i18n", "browser", "$http"];
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	exports.default = desktopApprovalButtonDirective;
	/*@ngInject*/
	
	function desktopApprovalButtonDirective($modal, i18n, browser, $http) {
	  return {
	    scope: {
	      approvalHref: '@approvalHref'
	    },
	    replace: true,
	    link: function link(scope, element) {
	      scope.launchText = i18n.t("campaign_editor.buttons.launch_campaign");
	
	      var showModal = function showModal() {
	        $modal({
	          scope: scope,
	          template: __webpack_require__(1188)
	        });
	      };
	
	      scope.publishAndRefresh = function () {
	        scope.launchText = i18n.t("campaign_editor.buttons.launching");
	        $http.post(scope.approvalHref).then(function () {
	          browser.refreshPage();
	        });
	      };
	
	      scope.i18n = i18n;
	      element.bind('click', showModal);
	    }
	  };
	}

/***/ },

/***/ 1188:
/***/ function(module, exports) {

	module.exports = "<div class=\"modal i-modal i-confirm-launch-modal\">\n  <div class=\"modal-dialog\">\n    <div class=\"modal-content\">\n      <a class=\"modal-close\" href=\"\" ng-click=\"$hide()\" aria-hidden=\"true\"><svg><use xlink:href=\"#icon-icon-close\"></use></svg></a>\n      <h2>{{ i18n.t(\"campaign_editor.confirm_publish.confirm_launch\") }}</h2>\n      <p>{{ i18n.t(\"campaign_editor.confirm_publish.are_you_sure_you_want_to_launch\") }}</p>\n      <div class=\"i-button-row\">\n        <a class=\"i-cta-1 i-cta-1--ghost\" href=\"\" ng-click=\"$hide()\">{{ i18n.t(\"cancel\") }}</a>\n        <a class=\"i-cta-1\" href=\"\" ng-click=\"publishAndRefresh()\">{{ launchText }}</a>\n      </div>\n    </div>\n  </div>\n</div>\n";

/***/ },

/***/ 1250:
/***/ function(module, exports, __webpack_require__) {

	"use strict";
	
	emailImporterDirective.$inject = ["i18n", "$modal", "emailImporter", "flash", "browser", "$timeout", "gon", "$http"];
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	exports.default = emailImporterDirective;
	/*@ngInject*/
	
	function emailImporterDirective(i18n, $modal, emailImporter, flash, browser, $timeout, gon, $http) {
	  return {
	    scope: {
	      postEmailCallback: "&",
	      emailFrom: "@",
	      emailImporterClick: '&'
	    },
	    replace: true,
	    template: __webpack_require__(1251),
	    transclude: true,
	    link: function link(scope, element, attrs) {
	      var CONTACT_OFFSET = 92;
	      var VIEW_OFFSET = 185;
	      var VALID_EMAIL = /.*@.*\..{2,}/;
	      var currentAccount = _(gon.current_account).clone() || {};
	      var postEmailCallback = scope.postEmailCallback;
	      var fundraiserRecipient = gon.fundraiser && gon.fundraiser.fundraiser_recipient;
	      var fundraiserTitle = gon.fundraiser && gon.fundraiser.title;
	      var emailFrom = scope.emailFrom || 'from_supporter';
	      var onGenerosity = gon.domain === 'generosity';
	      var yahooProvider;
	      var googleProvider;
	
	      scope.onGenerosity = onGenerosity;
	
	      if (onGenerosity) {
	        yahooProvider = 'yahoo_generosity';
	        googleProvider = 'gmail_generosity';
	      } else {
	        yahooProvider = 'yahoo';
	        googleProvider = 'gmail';
	      }
	
	      function changeSelectedStatus(contact, newContactStatus) {
	        if (contact.isSelected !== newContactStatus) {
	          contact.isSelected = newContactStatus;
	          if (contact.isSelected) {
	            scope.totalSelected += 1;
	          } else {
	            scope.totalSelected -= 1;
	          }
	        }
	
	        var contactLi = findContactLi(contact);
	        contactLi.toggleClass('ng-hide', !scope.showContact(contact));
	        updateContactSelectionLook(contact);
	      }
	
	      function updateContactSelectionLook(contact) {
	        var contactLi = findContactLi(contact);
	        var checkbox = contactLi.find('div.pull-right');
	        checkbox.toggleClass('pc-checked-checkbox', contact.isSelected);
	        checkbox.toggleClass('pc-unchecked-checkbox', !contact.isSelected);
	      }
	
	      function updateContactListVisibility() {
	        scope.contactList.forEach(function (contact) {
	          var contactLi = findContactLi(contact);
	          contactLi.toggleClass('ng-hide', !scope.showContact(contact));
	        });
	      }
	
	      scope.i18n = i18n;
	      scope.contact = {};
	      scope.gmailImported = false;
	      scope.yahooImported = false;
	      scope.isComposing = false;
	      scope.totalSelected = 0;
	      scope.showSelectedContacts = false;
	
	      scope.ableToCompose = function () {
	        return scope.contactList.length > 0 && scope.totalSelected > 0 && scope.remainingCount() > 0;
	      };
	
	      scope.onImporterClick = function () {
	        if (attrs.emailImporterClick) {
	          scope.emailImporterClick();
	        } else {
	          scope.openModal();
	        }
	      };
	
	      scope.message = {
	        subject: i18n.pt('email_import.' + emailFrom + '.email_subject', { project_title: fundraiserTitle, full_name: currentAccount.full_name })
	      };
	
	      var i18nOptions, key;
	      if (!!fundraiserRecipient && onGenerosity) {
	        i18nOptions = {
	          project_title: fundraiserTitle,
	          beneficiary: fundraiserRecipient,
	          organizer_name: currentAccount.full_name
	        };
	
	        key = '.email_message_with_beneficiary';
	
	        scope.message.body = i18n.pt('email_import.' + emailFrom + key, i18nOptions);
	      } else {
	        i18nOptions = {
	          project_title: fundraiserTitle,
	          organizer_name: currentAccount.full_name
	        };
	
	        key = '.email_message';
	
	        scope.message.body = i18n.pt('email_import.' + emailFrom + key, i18nOptions);
	      }
	
	      var selectedContacts = function selectedContacts() {
	        return scope.contactList.filter(function (contact) {
	          return contact.isSelected;
	        });
	      };
	
	      var selectedContactsIds = function selectedContactsIds() {
	        return selectedContacts().map(function (contact) {
	          return contact.id;
	        });
	      };
	
	      var findContactLi = function findContactLi(contact) {
	        return modal.$element.find(".emailImporter-contactList-contact#email-contact-" + contact.id);
	      };
	
	      var viewHeight = function viewHeight() {
	        return Math.max(browser.height() * 0.9 - 600, 200);
	      };
	
	      scope.contactListHeight = function () {
	        if (scope.showSelectedContacts) {
	          var msgHeight = modal.$element.find('.emailImporter-importContacts-selectedMessage').height();
	          return viewHeight() - msgHeight - 42 + 'px';
	        } else {
	          return viewHeight() + 'px';
	        }
	      };
	
	      scope.emailChanged = function () {
	        updateContactListVisibility();
	      };
	
	      scope.showContact = function (contactItem) {
	        if (scope.showSelectedContacts && !contactItem.isSelected) {
	          return false;
	        }
	        if (scope.contact.email) {
	          if (contactItem.email.toLowerCase().indexOf(scope.contact.email.toLowerCase()) === -1) {
	            return false;
	          }
	        }
	        return true;
	      };
	
	      var modal;
	      scope.openModal = function () {
	        if (gon.current_account) {
	          if (modal) {
	            modal.show();
	          } else {
	            $http.get(gon.urls.email_contacts).then(function (response) {
	              var json = response.data;
	              scope.contactList = json.email_contacts || [];
	              var contactsData = json.email_contacts_data || {};
	              scope.remainingCount = function () {
	                return contactsData.remaining - scope.totalSelected;
	              };
	              scope.emailLimitReachedMsg = i18n.t('email_import.limit_reached', {
	                daily_limit: contactsData.max
	              });
	              scope.remainingMessage = function () {
	                return i18n.t('email_import.emails_remaining', { remaining: scope.remainingCount(), daily_limit: contactsData.max });
	              };
	
	              modal = $modal({ scope: scope, template: __webpack_require__(1252) });
	            });
	          }
	        } else {
	          browser.redirectTo(gon.urls.email_login_url);
	        }
	      };
	
	      scope.validEmail = function () {
	        return scope.contact.email && scope.contact.email.match(VALID_EMAIL);
	      };
	
	      scope.onlyShowSelectedContacts = function () {
	        scope.showSelectedContacts = true;
	        updateContactListVisibility();
	      };
	
	      scope.showAllContacts = function () {
	        scope.showSelectedContacts = false;
	        updateContactListVisibility();
	      };
	
	      scope.toggleSelection = function (event) {
	        var contactId = $(event.target).closest('li').attr('id').replace('email-contact-', '');
	        var contact = _.find(scope.contactList, { id: +contactId });
	        changeSelectedStatus(contact, !contact.isSelected);
	      };
	
	      scope.addContact = function () {
	        emailImporter.createContact({ email: scope.contact.email }).then(function (contact) {
	          if (contact) {
	            scope.contactList.push(contact);
	
	            $timeout(function () {
	              updateContactListVisibility();
	              changeSelectedStatus(contact, true);
	
	              var contactLi = findContactLi(contact);
	
	              if (contactLi.position()) {
	                var contactPosition = contactLi.position().top - CONTACT_OFFSET;
	                var contactList = modal.$element.find('.emailImporter-importContacts-contactList');
	                contactList.animate({ scrollTop: contactPosition });
	              }
	            });
	          }
	        });
	
	        scope.contact.email = '';
	      };
	
	      scope.allContactsSelected = function () {
	        return scope.totalSelected === scope.contactList.length && scope.contactList.length > 0;
	      };
	
	      scope.sendMessages = function (message) {
	        emailImporter.sendBulkMessages(message, selectedContactsIds()).then(function () {
	          flash.addMessage('notice', i18n.t('email_import.successful_send'));
	          modal.hide();
	          scope.isComposing = false;
	
	          if (postEmailCallback) {
	            postEmailCallback();
	          }
	        });
	      };
	
	      scope.selectAllContacts = function (newContactStatus) {
	        if (newContactStatus) {
	          scope.showSelectedContacts = false;
	        }
	        scope.contactList.forEach(function (contact) {
	          changeSelectedStatus(contact, newContactStatus);
	        });
	      };
	
	      scope.messageFieldHeight = function () {
	        return viewHeight() + VIEW_OFFSET + 'px';
	      };
	
	      scope.toggleCompose = function () {
	        scope.isComposing = !scope.isComposing;
	      };
	
	      scope.importGmailContacts = function () {
	        emailImporter.importContacts(googleProvider).then(function (contacts) {
	          scope.contactList = contacts.concat(scope.contactList);
	          scope.gmailImported = true;
	        });
	      };
	
	      scope.importYahooContacts = function () {
	        emailImporter.importContacts(yahooProvider).then(function (contacts) {
	          scope.contactList = contacts.concat(scope.contactList);
	          scope.yahooImported = true;
	        });
	      };
	
	      browser.onLoad(function () {
	        if (gon.show_email_importer && gon.current_account) {
	          scope.openModal();
	        }
	      });
	
	      scope.$on('emailImporter.launch', function () {
	        scope.openModal();
	      });
	    }
	  };
	}

/***/ },

/***/ 1251:
/***/ function(module, exports) {

	module.exports = "<a href=\"\" ng-click=\"onImporterClick()\" ng-transclude></a>\n";

/***/ },

/***/ 1252:
/***/ function(module, exports) {

	module.exports = "<div class=\"modal modal--emailImporter\">\n  <div class=\"modal-dialog modal-dialog--emailImporter\">\n    <div class=\"modal-content modal-content--emailImporter\">\n      <a class=\"modal-close emailImporter-close\" ng-click=\"$hide()\" aria-hidden=\"true\">\n        <svg-icon icon=\"icon-icon-close\"></svg-icon>\n      </a>\n      <h1 class=\"emailImporter-title\">{{::i18n.pt('email_import.share_this_campaign')}}</h1>\n\n      <div class=\"emailImporter-importView\" ng-hide=\"isComposing\">\n        <div class=\"i-musty-background emailImporter-importContacts\">\n          <p class=\"emailImporter-importContacts-heading\">{{::i18n.t('email_import.import_contacts')}}</p>\n          <p class=\"emailImporter-importContacts-subheading\">{{::i18n.t('email_import.add_existing')}}</p>\n\n          <div class=\"emailImporter-importContacts-emails\">\n            <div class=\"emailImporter-provider\" ng-click=\"importGmailContacts()\" ng-class=\"{imported: gmailImported}\">\n              <div class=\"emailImporter-provider-icon emailImporter-provider-icon--gmail\"></div>\n              <span class=\"emailImporter-provider-name\">Gmail</span>\n              <div ng-if=\"gmailImported\" class=\"emailImporter-provider-checkmark\"></div>\n            </div>\n            <div class=\"emailImporter-provider\" ng-click=\"importYahooContacts()\" ng-class=\"{imported: yahooImported}\">\n              <div class=\"emailImporter-provider-icon emailImporter-provider-icon--yahoo\"></div>\n              <span class=\"emailImporter-provider-name\">Yahoo!</span>\n              <div ng-if=\"yahooImported\" class=\"emailImporter-provider-checkmark\"></div>\n            </div>\n          </div>\n        </div>\n\n        <div class=\"i-musty-background emailImporter-contactList\">\n          <form ng-submit=\"addContact()\" class=\"emailImporter-addContact\">\n            <input type=\"text\" class=\"i-text-field emailImporter-addContact-inputField\" placeholder=\"Enter an email\" ng-model=\"contact.email\" ng-change=\"emailChanged()\" />\n            <input type=\"submit\" class=\"i-cta-1 i-cta-1--50px\" ng-disabled=\"!validEmail()\" value=\"{{::i18n.t('email_import.button_add')}}\" />\n          </form>\n\n          <div class=\"emailImporter-importContacts-selectedMessage\" ng-if=\"showSelectedContacts\">\n            {{i18n.t('email_import.selected_recipient_count', {selected_count: totalSelected})}} — <a href=\"\" ng-click=\"showAllContacts()\">{{i18n.t('email_import.total_recipient_count', {total_count: contactList.length})}}</a>\n          </div>\n\n          <div class=\"emailImporter-importContacts-contactList\" ng-style=\"{height: contactListHeight(), lineHeight: contactListHeight()}\" ng-click=\"toggleSelection($event)\">\n            <div ng-if=\"contactList.length === 0\" class=\"emailImporter-noContacts\">{{::i18n.t('email_import.no_contacts')}}</div>\n            <ul>\n              <li id=\"{{::'email-contact-' + contactItem.id}}\" class=\"emailImporter-contactList-contact\" ng-repeat=\"contactItem in contactList | orderBy:'email' track by contactItem.id\"><span>{{::contactItem.email}}</span><div class=\"pull-right pc-unchecked-checkbox\"></div></li>\n            </ul>\n          </div>\n\n          <div class=\"emailImporter-importContacts-recipients\">\n            {{::i18n.t('email_import.recipients')}} (<a href=\"\" ng-click=\"onlyShowSelectedContacts()\">{{totalSelected}}</a>)\n          </div>\n          <div ng-if=\"!allContactsSelected()\" class=\"emailImporter-importContacts-selectAll\" ng-click=\"selectAllContacts(true)\">\n            <span>{{::i18n.t('email_import.select_all')}}</span>\n            <div class=\"pull-right pc-unchecked-checkbox\"></div>\n          </div>\n          <div ng-if=\"allContactsSelected()\" class=\"emailImporter-importContacts-selectAll\" ng-click=\"selectAllContacts(false)\">\n            <span>{{::i18n.t('email_import.select_all')}}</span>\n            <div class=\"pull-right pc-checked-checkbox\"></div>\n          </div>\n        </div>\n      </div>\n\n      <div class=\"emailImporter-messageComposeView i-musty-background\" ng-show=\"isComposing\">\n        <p class=\"emailImporter-composeLabel\">{{::i18n.t('email_import.email_subject')}}</p>\n        <input type=\"text\" class=\"i-text-field emailImporter-subjectField\" ng-model=\"message.subject\"/>\n        <p class=\"emailImporter-composeLabel\">{{::i18n.t('message_label')}}</p>\n        <textarea class=\"emailImporter-messageField\" ng-model=\"message.body\" ng-style=\"{height: messageFieldHeight()}\"></textarea>\n      </div>\n\n      <div class=\"emailImporter-linkMessage\" ng-show=\"isComposing\">{{::i18n.t('email_import.campaign_link_message')}}</div>\n\n      <div class=\"emailImporter-actions\" ng-if=\"!isComposing\">\n          <div class=\"emailImporter-actions-remainingArea\">\n            <div class=\"emailImporter-actions-remainingError\" ng-if=\"remainingCount() <= 0\">\n              <span>{{::emailLimitReachedMsg}}</span>\n            </div>\n            <div class=\"emailImporter-actions-remainingWarning\" ng-if=\"remainingCount() < 250 && remainingCount() > 0\">{{remainingMessage()}}</div>\n          </div>\n        <button class=\"emailImporter-actions-button i-cta-1 i-cta-1--50px\" ng-click=\"toggleCompose()\" ng-disabled=\"!ableToCompose()\">{{::i18n.t('email_import.button_compose')}}</button>\n      </div>\n      <div class=\"emailImporter-actions\" ng-if=\"isComposing\">\n        <!-- TODO EVENTS: id=aido2 fixtype=event-dir subsystem=share trigger=click dom=button name=click_send_email_importer category-new=share_wizard action-new=send label-new=email . review -->\n        <button class=\"emailImporter-actions-button i-cta-1 emailImporter-sendMessagesBtn\" ng-click=\"sendMessages(message)\" ng-disabled=\"!message.subject || !message.body\"\n                event-on=\"click\"\n                event-name=\"click_send_email_importer\"\n                event-ga-event-category=\"share_wizard\"\n                event-ga-event-action=\"send\"\n                event-ga-event-label=\"email\">{{::i18n.t('email_import.button_send')}}</button>\n        <button class=\"emailImporter-actions-button i-cta-1 i-cta-1--ghost emailImporter-backBtn\" ng-click=\"toggleCompose()\" >{{::i18n.t('email_import.button_back')}}</button>\n      </div>\n    </div>\n  </div>\n</div>\n";

/***/ },

/***/ 1253:
/***/ function(module, exports) {

	'use strict';
	
	emailImporterDirective.$inject = ["$http", "$window", "browser", "$q", "gon"];
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	exports.default = emailImporterDirective;
	/*@ngInject*/
	
	function emailImporterDirective($http, $window, browser, $q, gon) {
	  var service = {};
	
	  service.createContact = function (contact) {
	    var data = { source_type: 'user_entered', email: contact.email };
	
	    return $http.post(gon.urls.contact_create_url, { contact: data }).then(function (response) {
	      return response.data;
	    });
	  };
	
	  service.sendBulkMessages = function (message, contactIds) {
	    var email = {
	      project_id: gon.fundraiser.id,
	      subject: message.subject,
	      message: message.body,
	      email_contact_ids: contactIds
	    };
	    return $http.post(gon.urls.bulk_message_url, { email: email });
	  };
	
	  service.importContacts = function (provider) {
	    var deferred = $q.defer();
	    $window.addContacts = function (contacts) {
	      deferred.resolve(contacts);
	    };
	
	    browser.openWindow('/contacts/' + provider, provider, { width: 800, height: 600 });
	    return deferred.promise;
	  };
	
	  return service;
	}

/***/ },

/***/ 1280:
/***/ function(module, exports, __webpack_require__) {

	/*** IMPORTS FROM imports-loader ***/
	var Pusher = __webpack_require__(1181);
	
	'use strict';
	
	angular.module('pusher-angular', [])
	
	.factory('$pusher', ['$rootScope', '$channel', '$connection',
	  function ($rootScope, $channel, $connection) {
	
	    function PusherAngular (pusherClient) {
	      if (!(this instanceof PusherAngular)) {
	        return new PusherAngular(pusherClient);
	      }
	
	      this._assertValidClient(pusherClient);
	      this.client = pusherClient;
	      this.connection = $connection(pusherClient.connection, pusherClient);
	      this.channels = {};
	    }
	
	    PusherAngular.prototype = {
	      /**
	       * Subscribe the client to the specified channelName and returns the channel object.
	       * {@link https://pusher.com/docs/client_api_guide/client_public_channels#subscribe}
	       *
	       * @param {String} channelName name of the channel
	       * @returns {Object} channel object
	       */
	      subscribe: function (channelName) {
	        var channel = $channel(this.client.subscribe(channelName), this);
	        this.channels[channelName] = channel;
	        return channel;
	      },
	
	      /**
	       * Unsubscribes the client from the specified channel
	       * {@link https://pusher.com/docs/client_api_guide/client_public_channels#unsubscribe}
	       *
	       * @param {String} channelName name of the channel
	       */
	      unsubscribe: function (channelName) {
	        if (this.client.channel(channelName)) {
	          this.client.unsubscribe(channelName);
	          if (this.channels[channelName]) { delete this.channels[channelName]; }
	        }
	      },
	
	      /**
	       * Binds to global events on the pusher client. You can attach behaviour to these events
	       * regardless of the channel the event is broadcast to.
	       *
	       * @param {String} eventName name of the event you want to bind to
	       * @param {Function|undefined} callback callback that you want called upon the event occurring
	       */
	      bind: function (eventName, callback) {
	        this.client.bind(eventName, function (data) {
	          callback(data);
	          $rootScope.$digest();
	        });
	      },
	
	      /**
	       * Binds to all of the global client messages.
	       *
	       * @param {Function|undefined} callback callback that you want called upon a message being received
	       */
	      bind_all: function (callback) {
	        this.client.bind_all(function (eventName, data) {
	          callback(eventName, data);
	          $rootScope.$digest();
	        });
	      },
	
	      /**
	       * Unbinds from global events on the pusher client.
	       *
	       * @param {String} eventName name of the event you want to bind from
	       * @param {Function|undefined} callback callback that you want to unbind
	       */
	      unbind: function (eventName, callback) {
	        this.client.unbind(eventName, callback);
	      },
	
	      /**
	       * Disconnects the pusher client.
	       * {@link http://pusher.com/docs/client_api_guide/client_connect#disconnecting}
	       */
	      disconnect: function () {
	        this.client.disconnect();
	      },
	
	      /**
	       * Returns a pusher channel object.
	       * {@link https://pusher.com/docs/client_api_guide/client_channels#access}
	       *
	       * @param {String} channelName name of the channel
	       * @returns {Array} channel object
	       */
	      channel: function (channelName) {
	        return this.channels[channelName];
	      },
	
	      /**
	       * Returns a an array of the channels that the client is subscribed to.
	       * {@link https://pusher.com/docs/client_api_guide/client_channels#access}
	       *
	       * @returns {Array} array of subscribed channels
	       */
	      allChannels: function () {
	        return this.channels;
	      },
	
	      /**
	       * Asserts that the $pusher object is being initialised with valid pusherClient.
	       * Throws an error if pusherClient is invalid.
	       *
	       * @param {Object} pusherClient members object from base pusher channel object
	       */
	      _assertValidClient: function (pusherClient) {
	        if (!angular.isObject(pusherClient) ||
	            !angular.isObject(pusherClient.connection) ||
	            typeof(pusherClient.channel) !== 'function') {
	          throw new Error('Invalid Pusher client object');
	        }
	      }
	    };
	
	    return PusherAngular;
	  }
	])
	
	.factory('$channel', ['$rootScope', '$members',
	  function ($rootScope, $members) {
	
	    function checkPresenceOrPrivateChannel (channelName) {
	      if (channelName.indexOf('presence-') == -1 && channelName.indexOf('private-') == -1) {
	        throw new Error('Presence or private channel required');
	      }
	    }
	
	    function $channel (baseChannel, $pusherClient) {
	      if (!(this instanceof $channel)) {
	        return new $channel(baseChannel, $pusherClient);
	      }
	
	      this._assertValidChannel(baseChannel);
	      this.baseChannel = baseChannel;
	      this.client = $pusherClient;
	      this.name = baseChannel.name;
	
	      if (baseChannel.name.indexOf('presence') == -1) {
	        this.members = function () { throw new Error('Members object only exists for presence channels'); }
	      } else {
	        this.members = $members(baseChannel.members, baseChannel);
	      }
	    }
	
	    $channel.prototype = {
	      /**
	       * Binds to the given event name on the channel.
	       *
	       * @param {String} eventName name of the event you want to bind to
	       * @param {Function|undefined} callback callback that you want called upon the event occurring
	       */
	      bind: function (eventName, callback) {
	        this.baseChannel.bind(eventName, function (data) {
	          callback(data);
	          $rootScope.$digest();
	        });
	      },
	
	      /**
	       * Unbinds from the given event name on the channel.
	       *
	       * @param {String} eventName name of the event you want to bind from
	       * @param {Function|undefined} callback callback that you want to unbind
	       */
	      unbind: function (eventName, callback) {
	        this.baseChannel.unbind(eventName, callback);
	      },
	
	      /**
	       * Binds to all of the channel events.
	       *
	       * @param {Function|undefined} callback callback that you want called upon the event occurring
	       */
	      bind_all: function (callback) {
	        this.baseChannel.bind_all(function (eventName, data) {
	          callback(eventName, data);
	          $rootScope.$digest();
	        });
	      },
	
	      /**
	       * Triggers a client event.
	       * {@link https://pusher.com/docs/client_api_guide/client_events#trigger-events}
	       *
	       * @param {String} channelName name of the channel
	       * @param {String} eventName name of the event
	       * @param {Object} obj object that you wish to pass along with your client event
	       * @returns {}
	       */
	      trigger: function (eventName, obj) {
	        checkPresenceOrPrivateChannel(this.name);
	        if (eventName.indexOf('client-') == -1) { throw new Error('Event name requires \'client-\' prefix'); }
	        return this.baseChannel.trigger(eventName, obj);
	      },
	
	      /**
	       * Asserts that the $channel object is being initialised with valid baseChannel.
	       * Throws an error if baseChannel is invalid.
	       *
	       * @param {Object} baseChannel channel object from base pusher channel object
	       */
	      _assertValidChannel: function (baseChannel) {
	        if (!angular.isObject(baseChannel) ||
	            typeof(baseChannel.name) !== 'string') {
	          throw new Error('Invalid Pusher channel object');
	        }
	      }
	    };
	
	    return $channel;
	  }
	])
	
	.factory('$members', ['$rootScope',
	  function ($rootScope) {
	
	    function $members (baseMembers, baseChannel) {
	      if (!(this instanceof $members)) {
	        return new $members(baseMembers, baseChannel);
	      }
	      var self = this;
	
	      this._assertValidMembers(baseMembers);
	      this.baseMembers = baseMembers;
	      this.baseChannel = baseChannel;
	      this.me = {};
	      this.count = 0;
	      this.members = {};
	
	      baseChannel.bind('pusher:subscription_succeeded', function (members) {
	        self.me = members.me;
	        self.count = members.count;
	        self.members = members.members;
	        $rootScope.$digest();
	      });
	
	      baseChannel.bind('pusher:member_added', function (member) {
	        self.count++;
	        if (member.info) {
	          self.members[member.id.toString()] = member.info;
	        } else {
	          self.members[member.id.toString()] = null;
	        }
	        $rootScope.$digest();
	      });
	
	      baseChannel.bind('pusher:member_removed', function (member) {
	        self.count--;
	        delete self.members[member.id.toString()];
	        $rootScope.$digest();
	      });
	    }
	
	    $members.prototype = {
	     /**
	      * Returns member's info for given id. Resulting object containts two fields - id and info.
	      *
	      * @param {Number} id user's id
	      * @return {Object} member's info or null
	      */
	      get: function (id) {
	        return this.baseMembers.get(id);
	      },
	
	      /**
	       * Calls back for each member in unspecified order.
	       *
	       * @param {Function} callback callback function
	       */
	      each: function (callback) {
	        this.baseMembers.each(function (member) {
	          callback(member);
	          $rootScope.$digest();
	        });
	      },
	
	      /**
	       * Asserts that the $members object is being initialised with valid baseMembers.
	       * Throws an error if baseMembers is invalid.
	       *
	       * @param {Object} baseMembers members object from base pusher channel object
	       */
	      _assertValidMembers: function (baseMembers) {
	        if (!angular.isObject(baseMembers) ||
	            typeof(baseMembers.me) !== 'object') {
	          throw new Error('Invalid Pusher channel members object');
	        }
	      }
	    };
	
	    return $members;
	  }
	])
	
	.factory('$connection', ['$rootScope',
	  function ($rootScope) {
	
	    function $connection (baseConnection, baseClient) {
	      if (!(this instanceof $connection)) {
	        return new $connection(baseConnection, baseClient);
	      }
	
	      this._assertValidConnection(baseConnection);
	      this.baseConnection = baseConnection;
	      this.baseClient = baseClient;
	    }
	
	    $connection.prototype = {
	      /**
	       * Binds to the given event name on the connection.
	       *
	       * @param {String} eventName name of the event you want to bind to
	       * @param {Function|undefined} callback callback that you want called upon the event occurring
	       */
	      bind: function (eventName, callback) {
	        this.baseConnection.bind(eventName, function (data) {
	          callback(data);
	          $rootScope.$digest();
	        });
	      },
	
	      /**
	       * Binds to all of the global connection events.
	       *
	       * @param {Function|undefined} callback callback that you want called upon the event occurring
	       */
	      bind_all: function (callback) {
	        this.baseConnection.bind_all(function (eventName, data) {
	          callback(eventName, data);
	          $rootScope.$digest();
	        });
	      },
	
	      /**
	       * Asserts that the $connection object is being initialised with valid baseConnection.
	       * Throws an error if baseConnection is invalid.
	       *
	       * @param {Object} baseConnection connection object from base pusher object
	       */
	      _assertValidConnection: function (baseConnection) {
	        if (!angular.isObject(baseConnection)) {
	          throw new Error('Invalid Pusher connection object');
	        }
	      }
	    };
	
	    return $connection;
	  }
	]);
	


/***/ },

/***/ 1291:
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	
	__webpack_require__(41);
	
	__webpack_require__(1292);
	
	var _fastclick = __webpack_require__(1294);
	
	var _fastclick2 = _interopRequireDefault(_fastclick);
	
	var _campaignService = __webpack_require__(1113);
	
	var _campaignService2 = _interopRequireDefault(_campaignService);
	
	var _campaignLayoutService = __webpack_require__(1295);
	
	var _campaignLayoutService2 = _interopRequireDefault(_campaignLayoutService);
	
	var _campaignOverviewDirective = __webpack_require__(1296);
	
	var _campaignOverviewDirective2 = _interopRequireDefault(_campaignOverviewDirective);
	
	var _campaignPillsDirective = __webpack_require__(1300);
	
	var _campaignPillsDirective2 = _interopRequireDefault(_campaignPillsDirective);
	
	var _campaignPageDirective = __webpack_require__(1304);
	
	var _campaignPageDirective2 = _interopRequireDefault(_campaignPageDirective);
	
	var _campaignPageTrackingDirective = __webpack_require__(1308);
	
	var _campaignPageTrackingDirective2 = _interopRequireDefault(_campaignPageTrackingDirective);
	
	var _campaignProductStageDirective = __webpack_require__(1309);
	
	var _campaignProductStageDirective2 = _interopRequireDefault(_campaignProductStageDirective);
	
	var _campaignCategoryDirective = __webpack_require__(1313);
	
	var _campaignCategoryDirective2 = _interopRequireDefault(_campaignCategoryDirective);
	
	var _campaignPlaceholderDirective = __webpack_require__(1092);
	
	var _campaignPlaceholderDirective2 = _interopRequireDefault(_campaignPlaceholderDirective);
	
	var _campaignPitchmediaDirective = __webpack_require__(1088);
	
	var _campaignPitchmediaDirective2 = _interopRequireDefault(_campaignPitchmediaDirective);
	
	__webpack_require__(1317);
	
	var _campaignVideoDirective = __webpack_require__(1069);
	
	var _campaignVideoDirective2 = _interopRequireDefault(_campaignVideoDirective);
	
	var _campaignVideoYoutubeAutoplayDirective = __webpack_require__(1071);
	
	var _campaignVideoYoutubeAutoplayDirective2 = _interopRequireDefault(_campaignVideoYoutubeAutoplayDirective);
	
	__webpack_require__(1319);
	
	var _campaignGalleryThumbnailsDirective = __webpack_require__(1321);
	
	var _campaignGalleryThumbnailsDirective2 = _interopRequireDefault(_campaignGalleryThumbnailsDirective);
	
	var _campaignGalleryService = __webpack_require__(1325);
	
	var _campaignGalleryService2 = _interopRequireDefault(_campaignGalleryService);
	
	var _galleryMediaFactory = __webpack_require__(1326);
	
	var _galleryMediaFactory2 = _interopRequireDefault(_galleryMediaFactory);
	
	var _galleryThumbnailDirective = __webpack_require__(1327);
	
	var _galleryThumbnailDirective2 = _interopRequireDefault(_galleryThumbnailDirective);
	
	var _galleryDescriptionDirective = __webpack_require__(1331);
	
	var _galleryDescriptionDirective2 = _interopRequireDefault(_galleryDescriptionDirective);
	
	var _campaignHeaderPitchDirective = __webpack_require__(1335);
	
	var _campaignHeaderPitchDirective2 = _interopRequireDefault(_campaignHeaderPitchDirective);
	
	var _campaignHeaderBasicsDirective = __webpack_require__(1337);
	
	var _campaignHeaderBasicsDirective2 = _interopRequireDefault(_campaignHeaderBasicsDirective);
	
	var _campaignStateLabelDirective = __webpack_require__(1341);
	
	var _campaignStateLabelDirective2 = _interopRequireDefault(_campaignStateLabelDirective);
	
	var _campaignShareButtonsDirective = __webpack_require__(1345);
	
	var _campaignShareButtonsDirective2 = _interopRequireDefault(_campaignShareButtonsDirective);
	
	var _campaignTagsDirective = __webpack_require__(1090);
	
	var _campaignTagsDirective2 = _interopRequireDefault(_campaignTagsDirective);
	
	var _campaignContributeDirective = __webpack_require__(1349);
	
	var _campaignContributeDirective2 = _interopRequireDefault(_campaignContributeDirective);
	
	var _campaignViewPerksDirective = __webpack_require__(1351);
	
	var _campaignViewPerksDirective2 = _interopRequireDefault(_campaignViewPerksDirective);
	
	var _campaignContributeService = __webpack_require__(1353);
	
	var _campaignContributeService2 = _interopRequireDefault(_campaignContributeService);
	
	var _campaignTrustInfoDirective = __webpack_require__(1354);
	
	var _campaignTrustInfoDirective2 = _interopRequireDefault(_campaignTrustInfoDirective);
	
	var _campaignTrustQuestionDirective = __webpack_require__(1358);
	
	var _campaignTrustQuestionDirective2 = _interopRequireDefault(_campaignTrustQuestionDirective);
	
	var _trustPassportService = __webpack_require__(1114);
	
	var _trustPassportService2 = _interopRequireDefault(_trustPassportService);
	
	var _campaignGoalService = __webpack_require__(1078);
	
	var _campaignGoalService2 = _interopRequireDefault(_campaignGoalService);
	
	var _campaignTrustDirective = __webpack_require__(1362);
	
	var _campaignTrustDirective2 = _interopRequireDefault(_campaignTrustDirective);
	
	var _campaignGoalProgressDirective = __webpack_require__(1366);
	
	var _campaignGoalProgressDirective2 = _interopRequireDefault(_campaignGoalProgressDirective);
	
	var _campaignPerksDirective = __webpack_require__(1370);
	
	var _campaignPerksDirective2 = _interopRequireDefault(_campaignPerksDirective);
	
	var _campaignPerksService = __webpack_require__(1374);
	
	var _campaignPerksService2 = _interopRequireDefault(_campaignPerksService);
	
	var _indemandProgressDirective = __webpack_require__(1375);
	
	var _indemandProgressDirective2 = _interopRequireDefault(_indemandProgressDirective);
	
	var _indemandCampaignHistoryPopoverDirective = __webpack_require__(1379);
	
	var _indemandCampaignHistoryPopoverDirective2 = _interopRequireDefault(_indemandCampaignHistoryPopoverDirective);
	
	var _reportThisCampaignDirective = __webpack_require__(1383);
	
	var _reportThisCampaignDirective2 = _interopRequireDefault(_reportThisCampaignDirective);
	
	var _campaignStoryLinkDirective = __webpack_require__(1387);
	
	var _campaignStoryLinkDirective2 = _interopRequireDefault(_campaignStoryLinkDirective);
	
	var _campaignModalDirective = __webpack_require__(1391);
	
	var _campaignModalDirective2 = _interopRequireDefault(_campaignModalDirective);
	
	var _campaignModalService = __webpack_require__(1394);
	
	var _campaignModalService2 = _interopRequireDefault(_campaignModalService);
	
	var _campaignModalCloseDirective = __webpack_require__(1395);
	
	var _campaignModalCloseDirective2 = _interopRequireDefault(_campaignModalCloseDirective);
	
	var _campaignAnalyticsService = __webpack_require__(1093);
	
	var _campaignAnalyticsService2 = _interopRequireDefault(_campaignAnalyticsService);
	
	var _campaignActionsDirective = __webpack_require__(1399);
	
	var _campaignActionsDirective2 = _interopRequireDefault(_campaignActionsDirective);
	
	var _campaignActionsModalDirective = __webpack_require__(1403);
	
	var _campaignActionsModalDirective2 = _interopRequireDefault(_campaignActionsModalDirective);
	
	var _emailImporterDirective = __webpack_require__(1250);
	
	var _emailImporterDirective2 = _interopRequireDefault(_emailImporterDirective);
	
	var _emailImporterService = __webpack_require__(1253);
	
	var _emailImporterService2 = _interopRequireDefault(_emailImporterService);
	
	var _campaignLoginModalDirective = __webpack_require__(1407);
	
	var _campaignLoginModalDirective2 = _interopRequireDefault(_campaignLoginModalDirective);
	
	var _campaignBackersDirective = __webpack_require__(1408);
	
	var _campaignBackersDirective2 = _interopRequireDefault(_campaignBackersDirective);
	
	var _campaignPartnerBadgeDirective = __webpack_require__(1412);
	
	var _campaignPartnerBadgeDirective2 = _interopRequireDefault(_campaignPartnerBadgeDirective);
	
	var _campaignCollectionBadgeDirective = __webpack_require__(1416);
	
	var _campaignCollectionBadgeDirective2 = _interopRequireDefault(_campaignCollectionBadgeDirective);
	
	var _campaignSponsorsDirective = __webpack_require__(1420);
	
	var _campaignSponsorsDirective2 = _interopRequireDefault(_campaignSponsorsDirective);
	
	var _campaignHeaderTrustDirective = __webpack_require__(1424);
	
	var _campaignHeaderTrustDirective2 = _interopRequireDefault(_campaignHeaderTrustDirective);
	
	var _desktopApprovalButtonDirective = __webpack_require__(1187);
	
	var _desktopApprovalButtonDirective2 = _interopRequireDefault(_desktopApprovalButtonDirective);
	
	var _campaignBodyDirective = __webpack_require__(1428);
	
	var _campaignBodyDirective2 = _interopRequireDefault(_campaignBodyDirective);
	
	var _campaignNextPerkDirective = __webpack_require__(1432);
	
	var _campaignNextPerkDirective2 = _interopRequireDefault(_campaignNextPerkDirective);
	
	var _campaignNextPerkItemsDirective = __webpack_require__(1437);
	
	var _campaignNextPerkItemsDirective2 = _interopRequireDefault(_campaignNextPerkItemsDirective);
	
	var _campaignOldPerkDirective = __webpack_require__(1441);
	
	var _campaignOldPerkDirective2 = _interopRequireDefault(_campaignOldPerkDirective);
	
	var _campaignNavigationDirective = __webpack_require__(1445);
	
	var _campaignNavigationDirective2 = _interopRequireDefault(_campaignNavigationDirective);
	
	var _campaignAccordionDirective = __webpack_require__(1449);
	
	var _campaignAccordionDirective2 = _interopRequireDefault(_campaignAccordionDirective);
	
	var _contributionsApiService = __webpack_require__(936);
	
	var _contributionsApiService2 = _interopRequireDefault(_contributionsApiService);
	
	var _campaignDescriptionDirective = __webpack_require__(1453);
	
	var _campaignDescriptionDirective2 = _interopRequireDefault(_campaignDescriptionDirective);
	
	var _campaignSponsorBadgeDirective = __webpack_require__(1456);
	
	var _campaignSponsorBadgeDirective2 = _interopRequireDefault(_campaignSponsorBadgeDirective);
	
	var _campaignSupportedByDirective = __webpack_require__(1460);
	
	var _campaignSupportedByDirective2 = _interopRequireDefault(_campaignSupportedByDirective);
	
	var _perks = __webpack_require__(602);
	
	var _perks2 = _interopRequireDefault(_perks);
	
	var _share = __webpack_require__(1462);
	
	var _share2 = _interopRequireDefault(_share);
	
	var _perkPrefs = __webpack_require__(1473);
	
	var _perkPrefs2 = _interopRequireDefault(_perkPrefs);
	
	function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
	
	__webpack_require__(1280);
	__webpack_require__(1475);
	
	/* the fold */
	
	(0, _perks2.default)(angular);
	
	(0, _share2.default)(angular);
	
	(0, _perkPrefs2.default)(angular);
	
	angular.module('campaignPage.next', ['utils', 'header', 'footer', 'ui.router', 'pusher-angular', 'perks', 'ngAnimate', 'ngTouch', 'angulartics.scroll', 'indiegogo.components.share', 'indiegogo.components.perkPrefs']).service('campaign', _campaignService2.default).service('campaignLayoutService', _campaignLayoutService2.default).service('trustPassportService', _trustPassportService2.default).directive('campaignPlaceholder', _campaignPlaceholderDirective2.default).directive('campaignHeaderPitch', _campaignHeaderPitchDirective2.default).directive('campaignHeaderBasics', _campaignHeaderBasicsDirective2.default).directive('campaignStateLabel', _campaignStateLabelDirective2.default).directive('campaignTrust', _campaignTrustDirective2.default).directive('campaignNavigation', _campaignNavigationDirective2.default).directive('campaignAccordion', _campaignAccordionDirective2.default).directive('campaignOverview', _campaignOverviewDirective2.default).directive('campaignPills', _campaignPillsDirective2.default).directive('campaignPage', _campaignPageDirective2.default).directive('campaignBody', _campaignBodyDirective2.default).directive('campaignPitchmedia', _campaignPitchmediaDirective2.default).directive('campaignVideo', _campaignVideoDirective2.default).directive('campaignVideoYoutubeAutoplay', _campaignVideoYoutubeAutoplayDirective2.default).directive('campaignShareButtons', _campaignShareButtonsDirective2.default).directive('campaignTags', _campaignTagsDirective2.default).directive('campaignGoalProgress', _campaignGoalProgressDirective2.default).directive('campaignPerks', _campaignPerksDirective2.default).service('campaignPerksService', _campaignPerksService2.default).directive('campaignProductStage', _campaignProductStageDirective2.default).directive('campaignCategory', _campaignCategoryDirective2.default).directive('campaignNextPerk', _campaignNextPerkDirective2.default).directive('campaignNextPerkItems', _campaignNextPerkItemsDirective2.default).directive('campaignOldPerk', _campaignOldPerkDirective2.default).directive('campaignContribute', _campaignContributeDirective2.default).directive('campaignViewPerks', _campaignViewPerksDirective2.default).service('campaignContributeService', _campaignContributeService2.default).directive('campaignDescription', _campaignDescriptionDirective2.default).directive('campaignBackers', _campaignBackersDirective2.default).directive('indemandProgress', _indemandProgressDirective2.default).directive('indemandCampaignHistoryPopover', _indemandCampaignHistoryPopoverDirective2.default).directive('reportThisCampaign', _reportThisCampaignDirective2.default).directive('campaignStoryLink', _campaignStoryLinkDirective2.default).directive('campaignModalClose', _campaignModalCloseDirective2.default).directive('campaignModal', _campaignModalDirective2.default).service('campaignGoal', _campaignGoalService2.default).service('campaignModalService', _campaignModalService2.default).directive('campaignTrustInfo', _campaignTrustInfoDirective2.default).directive('campaignTrustQuestion', _campaignTrustQuestionDirective2.default).service('campaignAnalyticsService', _campaignAnalyticsService2.default).factory('contributionsApi', _contributionsApiService2.default).directive('campaignActions', _campaignActionsDirective2.default).directive('campaignActionsModal', _campaignActionsModalDirective2.default).directive('emailImporter', _emailImporterDirective2.default).service('emailImporter', _emailImporterService2.default).directive('campaignSponsors', _campaignSponsorsDirective2.default).directive('campaignSponsorBadge', _campaignSponsorBadgeDirective2.default).directive('campaignSupportedBy', _campaignSupportedByDirective2.default).directive('campaignHeaderTrust', _campaignHeaderTrustDirective2.default).directive('campaignPageTracking', _campaignPageTrackingDirective2.default).directive('campaignLoginModal', _campaignLoginModalDirective2.default).directive('campaignPartnerBadge', _campaignPartnerBadgeDirective2.default).directive('campaignCollectionBadge', _campaignCollectionBadgeDirective2.default).directive('campaignGalleryThumbnails', _campaignGalleryThumbnailsDirective2.default).factory('GalleryMedia', _galleryMediaFactory2.default).directive('galleryThumbnail', _galleryThumbnailDirective2.default).service('campaignGalleryService', _campaignGalleryService2.default).directive('galleryDescription', _galleryDescriptionDirective2.default).directive('desktopApprovalButton', _desktopApprovalButtonDirective2.default).config(["$stateProvider", "$urlRouterProvider", "$compileProvider", "$controllerProvider", "$provide", function ($stateProvider, $urlRouterProvider, $compileProvider, $controllerProvider, $provide) {
	  $urlRouterProvider.otherwise("/");
	  $stateProvider.state('main', {
	    url: '/',
	    template: '<campaign-description></campaign-description>',
	    resolve: {
	      nil: ["$q", function nil($q) {
	        return $q.when(true);
	      }]
	    }
	  }).state('updates', {
	    url: '/updates',
	    template: "<campaign-updates></campaign-updates>",
	    resolve: {
	      dependencies: ["$q", "$rootScope", "$injector", "$timeout", function dependencies($q, $rootScope, $injector, $timeout) {
	        var deferred = $q.defer();
	        if ($injector.has('campaignUpdatesDirective')) {
	          deferred.resolve();
	          return deferred.promise;
	        }
	        __webpack_require__.e/* require */(5, function(__webpack_require__) { var __WEBPACK_AMD_REQUIRE_ARRAY__ = [__webpack_require__(1212), __webpack_require__(1216), __webpack_require__(1179), __webpack_require__(936), __webpack_require__(1278), __webpack_require__(1279)]; (function (desktopUpdates, desktopUpdatePreview, campaignUpdates, contributionsApi, updatePreview, updatePreviewModal) {
	          $provide.factory('campaignUpdates', campaignUpdates.default);
	          $provide.factory('updatePreview', updatePreview.default);
	
	          $compileProvider.directive('campaignUpdates', desktopUpdates.default).directive('desktopUpdatePreview', desktopUpdatePreview.default);
	
	          $controllerProvider.register('UpdatePreviewModal', updatePreviewModal.default);
	
	          $timeout(function () {
	            $rootScope.$apply(function () {
	              return deferred.resolve();
	            });
	          });
	        }.apply(null, __WEBPACK_AMD_REQUIRE_ARRAY__));});
	        return deferred.promise;
	      }]
	    }
	  }).state('comments', {
	    url: '/comments',
	    template: "<campaign-comments></campaign-comments>",
	    resolve: {
	      dependencies: ["$q", "$rootScope", "$timeout", function dependencies($q, $rootScope, $timeout) {
	        var deferred = $q.defer();
	        __webpack_require__.e/* require */(6, function(__webpack_require__) { var __WEBPACK_AMD_REQUIRE_ARRAY__ = [__webpack_require__(1193), __webpack_require__(1190), __webpack_require__(1197), __webpack_require__(957), __webpack_require__(961), __webpack_require__(956), __webpack_require__(965), __webpack_require__(1178), __webpack_require__(1183), __webpack_require__(1180), __webpack_require__(938)]; (function (desktopComments, desktopComment, desktopCommentContributionDetails, contributionState, paymentBreakdown, contributionDetails, paymentMethod, campaignComments, campaignPusher, pusherWrapper, refundDisplayFactory) {
	          $provide.factory('RefundDisplayFactory', refundDisplayFactory.default);
	          $provide.service('campaignComments', campaignComments.default);
	          $provide.service('campaignPusher', campaignPusher.default);
	          $provide.service('pusherWrapper', pusherWrapper.default);
	          $provide.service('contributionDetails', contributionDetails.default);
	
	          $compileProvider.directive('campaignComments', desktopComments.default).directive('desktopCommentContributionDetails', desktopCommentContributionDetails.default).directive('desktopComment', desktopComment.default).directive('paymentMethod', paymentMethod.default).directive('paymentBreakdown', paymentBreakdown.default).directive('contributionState', contributionState.default);
	
	          $timeout(function () {
	            $rootScope.$apply(function () {
	              return deferred.resolve();
	            });
	          });
	        }.apply(null, __WEBPACK_AMD_REQUIRE_ARRAY__));});
	        return deferred.promise;
	      }]
	    }
	  }).state('backers', {
	    url: '/backers',
	    template: "<campaign-backers></campaign-backers>",
	    resolve: {
	      nil: ["$q", function nil($q) {
	        return $q.when(true);
	      }]
	    }
	  }).state('gallery', {
	    url: '/gallery',
	    template: "<campaign-gallery></campaign-gallery>",
	    resolve: {
	      dependencies: ["$q", "$rootScope", "$timeout", function dependencies($q, $rootScope, $timeout) {
	        var deferred = $q.defer();
	        __webpack_require__.e/* require */(7, function(__webpack_require__) { var __WEBPACK_AMD_REQUIRE_ARRAY__ = [__webpack_require__(1205)]; (function (desktopGallery) {
	          $compileProvider.directive('campaignGallery', desktopGallery.default);
	
	          $timeout(function () {
	            $rootScope.$apply(function () {
	              return deferred.resolve();
	            });
	          });
	        }.apply(null, __WEBPACK_AMD_REQUIRE_ARRAY__));});
	        return deferred.promise;
	      }]
	    }
	  });
	}]).run(['campaign', 'campaignLayoutService', 'gon', '$document', function (campaign, campaignLayoutService, gon, $document) {
	  _fastclick2.default.attach($document.find('body')[0]);
	  if (gon && gon.campaign) {
	    var campaignPrivateJson = gon.campaignPrivateJson;
	    campaign.setCampaignJson(_.assign({}, gon.campaign, campaignPrivateJson));
	    campaignLayoutService.load();
	  }
	}]);

/***/ },

/***/ 1292:
/***/ function(module, exports, __webpack_require__) {

	__webpack_require__(46)(__webpack_require__(1293))

/***/ },

/***/ 1293:
/***/ function(module, exports) {

	module.exports = "/**\n * @license Angulartics v0.19.2\n * (c) 2013 Luis Farzati http://luisfarzati.github.io/angulartics\n * License: MIT\n */\n(function (angular) {\n'use strict';\n\n/**\n * @ngdoc overview\n * @name angulartics.scroll\n * Provides an implementation of jQuery Waypoints (http://imakewebthings.com/jquery-waypoints/)\n * for use as a valid DOM event in analytics-on.\n */\nangular.module('angulartics.scroll', ['angulartics'])\n.factory('$waypoint', function () {\n  return function(options) {\n    return new Waypoint(options);\n  };\n})\n.directive('analyticsOn', ['$analytics', '$waypoint', function ($analytics, $waypoint) {\n  function isProperty (name) {\n    return name.substr(0, 8) === 'scrollby';\n  }\n  function cast (value) {\n    if (value === '' || value === 'true') {\n      return true;\n    } else if (value === 'false') {\n      return false;\n    } else {\n      return value;\n    }\n  }\n\n  return {\n    restrict: 'A',\n    priority: 5,\n    scope: false,\n    link: function ($scope, $element, $attrs) {\n      if ($attrs.analyticsOn !== 'scrollby') return;\n\n      var properties = {\n        handler: function () {\n          $element.triggerHandler('scrollby');\n          if (this.options.triggeronce) {\n            this.destroy();\n          }\n        },\n        element: $element[0],\n        continuous: false,\n        triggeronce: true\n      };\n      angular.forEach($attrs.$attr, function (attr, name) {\n        if (isProperty(attr)) {\n          properties[name.slice(8,9).toLowerCase()+name.slice(9)] = cast($attrs[name]);\n        }\n      });\n\n      $waypoint(properties);\n    }\n  };\n}]);\n})(angular);\n"

/***/ },

/***/ 1294:
/***/ function(module, exports, __webpack_require__) {

	var __WEBPACK_AMD_DEFINE_RESULT__;;(function () {
		'use strict';
	
		/**
		 * @preserve FastClick: polyfill to remove click delays on browsers with touch UIs.
		 *
		 * @codingstandard ftlabs-jsv2
		 * @copyright The Financial Times Limited [All Rights Reserved]
		 * @license MIT License (see LICENSE.txt)
		 */
	
		/*jslint browser:true, node:true*/
		/*global define, Event, Node*/
	
	
		/**
		 * Instantiate fast-clicking listeners on the specified layer.
		 *
		 * @constructor
		 * @param {Element} layer The layer to listen on
		 * @param {Object} [options={}] The options to override the defaults
		 */
		function FastClick(layer, options) {
			var oldOnClick;
	
			options = options || {};
	
			/**
			 * Whether a click is currently being tracked.
			 *
			 * @type boolean
			 */
			this.trackingClick = false;
	
	
			/**
			 * Timestamp for when click tracking started.
			 *
			 * @type number
			 */
			this.trackingClickStart = 0;
	
	
			/**
			 * The element being tracked for a click.
			 *
			 * @type EventTarget
			 */
			this.targetElement = null;
	
	
			/**
			 * X-coordinate of touch start event.
			 *
			 * @type number
			 */
			this.touchStartX = 0;
	
	
			/**
			 * Y-coordinate of touch start event.
			 *
			 * @type number
			 */
			this.touchStartY = 0;
	
	
			/**
			 * ID of the last touch, retrieved from Touch.identifier.
			 *
			 * @type number
			 */
			this.lastTouchIdentifier = 0;
	
	
			/**
			 * Touchmove boundary, beyond which a click will be cancelled.
			 *
			 * @type number
			 */
			this.touchBoundary = options.touchBoundary || 10;
	
	
			/**
			 * The FastClick layer.
			 *
			 * @type Element
			 */
			this.layer = layer;
	
			/**
			 * The minimum time between tap(touchstart and touchend) events
			 *
			 * @type number
			 */
			this.tapDelay = options.tapDelay || 200;
	
			/**
			 * The maximum time for a tap
			 *
			 * @type number
			 */
			this.tapTimeout = options.tapTimeout || 700;
	
			if (FastClick.notNeeded(layer)) {
				return;
			}
	
			// Some old versions of Android don't have Function.prototype.bind
			function bind(method, context) {
				return function() { return method.apply(context, arguments); };
			}
	
	
			var methods = ['onMouse', 'onClick', 'onTouchStart', 'onTouchMove', 'onTouchEnd', 'onTouchCancel'];
			var context = this;
			for (var i = 0, l = methods.length; i < l; i++) {
				context[methods[i]] = bind(context[methods[i]], context);
			}
	
			// Set up event handlers as required
			if (deviceIsAndroid) {
				layer.addEventListener('mouseover', this.onMouse, true);
				layer.addEventListener('mousedown', this.onMouse, true);
				layer.addEventListener('mouseup', this.onMouse, true);
			}
	
			layer.addEventListener('click', this.onClick, true);
			layer.addEventListener('touchstart', this.onTouchStart, false);
			layer.addEventListener('touchmove', this.onTouchMove, false);
			layer.addEventListener('touchend', this.onTouchEnd, false);
			layer.addEventListener('touchcancel', this.onTouchCancel, false);
	
			// Hack is required for browsers that don't support Event#stopImmediatePropagation (e.g. Android 2)
			// which is how FastClick normally stops click events bubbling to callbacks registered on the FastClick
			// layer when they are cancelled.
			if (!Event.prototype.stopImmediatePropagation) {
				layer.removeEventListener = function(type, callback, capture) {
					var rmv = Node.prototype.removeEventListener;
					if (type === 'click') {
						rmv.call(layer, type, callback.hijacked || callback, capture);
					} else {
						rmv.call(layer, type, callback, capture);
					}
				};
	
				layer.addEventListener = function(type, callback, capture) {
					var adv = Node.prototype.addEventListener;
					if (type === 'click') {
						adv.call(layer, type, callback.hijacked || (callback.hijacked = function(event) {
							if (!event.propagationStopped) {
								callback(event);
							}
						}), capture);
					} else {
						adv.call(layer, type, callback, capture);
					}
				};
			}
	
			// If a handler is already declared in the element's onclick attribute, it will be fired before
			// FastClick's onClick handler. Fix this by pulling out the user-defined handler function and
			// adding it as listener.
			if (typeof layer.onclick === 'function') {
	
				// Android browser on at least 3.2 requires a new reference to the function in layer.onclick
				// - the old one won't work if passed to addEventListener directly.
				oldOnClick = layer.onclick;
				layer.addEventListener('click', function(event) {
					oldOnClick(event);
				}, false);
				layer.onclick = null;
			}
		}
	
		/**
		* Windows Phone 8.1 fakes user agent string to look like Android and iPhone.
		*
		* @type boolean
		*/
		var deviceIsWindowsPhone = navigator.userAgent.indexOf("Windows Phone") >= 0;
	
		/**
		 * Android requires exceptions.
		 *
		 * @type boolean
		 */
		var deviceIsAndroid = navigator.userAgent.indexOf('Android') > 0 && !deviceIsWindowsPhone;
	
	
		/**
		 * iOS requires exceptions.
		 *
		 * @type boolean
		 */
		var deviceIsIOS = /iP(ad|hone|od)/.test(navigator.userAgent) && !deviceIsWindowsPhone;
	
	
		/**
		 * iOS 4 requires an exception for select elements.
		 *
		 * @type boolean
		 */
		var deviceIsIOS4 = deviceIsIOS && (/OS 4_\d(_\d)?/).test(navigator.userAgent);
	
	
		/**
		 * iOS 6.0-7.* requires the target element to be manually derived
		 *
		 * @type boolean
		 */
		var deviceIsIOSWithBadTarget = deviceIsIOS && (/OS [6-7]_\d/).test(navigator.userAgent);
	
		/**
		 * BlackBerry requires exceptions.
		 *
		 * @type boolean
		 */
		var deviceIsBlackBerry10 = navigator.userAgent.indexOf('BB10') > 0;
	
		/**
		 * Determine whether a given element requires a native click.
		 *
		 * @param {EventTarget|Element} target Target DOM element
		 * @returns {boolean} Returns true if the element needs a native click
		 */
		FastClick.prototype.needsClick = function(target) {
			switch (target.nodeName.toLowerCase()) {
	
			// Don't send a synthetic click to disabled inputs (issue #62)
			case 'button':
			case 'select':
			case 'textarea':
				if (target.disabled) {
					return true;
				}
	
				break;
			case 'input':
	
				// File inputs need real clicks on iOS 6 due to a browser bug (issue #68)
				if ((deviceIsIOS && target.type === 'file') || target.disabled) {
					return true;
				}
	
				break;
			case 'label':
			case 'iframe': // iOS8 homescreen apps can prevent events bubbling into frames
			case 'video':
				return true;
			}
	
			return (/\bneedsclick\b/).test(target.className);
		};
	
	
		/**
		 * Determine whether a given element requires a call to focus to simulate click into element.
		 *
		 * @param {EventTarget|Element} target Target DOM element
		 * @returns {boolean} Returns true if the element requires a call to focus to simulate native click.
		 */
		FastClick.prototype.needsFocus = function(target) {
			switch (target.nodeName.toLowerCase()) {
			case 'textarea':
				return true;
			case 'select':
				return !deviceIsAndroid;
			case 'input':
				switch (target.type) {
				case 'button':
				case 'checkbox':
				case 'file':
				case 'image':
				case 'radio':
				case 'submit':
					return false;
				}
	
				// No point in attempting to focus disabled inputs
				return !target.disabled && !target.readOnly;
			default:
				return (/\bneedsfocus\b/).test(target.className);
			}
		};
	
	
		/**
		 * Send a click event to the specified element.
		 *
		 * @param {EventTarget|Element} targetElement
		 * @param {Event} event
		 */
		FastClick.prototype.sendClick = function(targetElement, event) {
			var clickEvent, touch;
	
			// On some Android devices activeElement needs to be blurred otherwise the synthetic click will have no effect (#24)
			if (document.activeElement && document.activeElement !== targetElement) {
				document.activeElement.blur();
			}
	
			touch = event.changedTouches[0];
	
			// Synthesise a click event, with an extra attribute so it can be tracked
			clickEvent = document.createEvent('MouseEvents');
			clickEvent.initMouseEvent(this.determineEventType(targetElement), true, true, window, 1, touch.screenX, touch.screenY, touch.clientX, touch.clientY, false, false, false, false, 0, null);
			clickEvent.forwardedTouchEvent = true;
			targetElement.dispatchEvent(clickEvent);
		};
	
		FastClick.prototype.determineEventType = function(targetElement) {
	
			//Issue #159: Android Chrome Select Box does not open with a synthetic click event
			if (deviceIsAndroid && targetElement.tagName.toLowerCase() === 'select') {
				return 'mousedown';
			}
	
			return 'click';
		};
	
	
		/**
		 * @param {EventTarget|Element} targetElement
		 */
		FastClick.prototype.focus = function(targetElement) {
			var length;
	
			// Issue #160: on iOS 7, some input elements (e.g. date datetime month) throw a vague TypeError on setSelectionRange. These elements don't have an integer value for the selectionStart and selectionEnd properties, but unfortunately that can't be used for detection because accessing the properties also throws a TypeError. Just check the type instead. Filed as Apple bug #15122724.
			if (deviceIsIOS && targetElement.setSelectionRange && targetElement.type.indexOf('date') !== 0 && targetElement.type !== 'time' && targetElement.type !== 'month') {
				length = targetElement.value.length;
				targetElement.setSelectionRange(length, length);
			} else {
				targetElement.focus();
			}
		};
	
	
		/**
		 * Check whether the given target element is a child of a scrollable layer and if so, set a flag on it.
		 *
		 * @param {EventTarget|Element} targetElement
		 */
		FastClick.prototype.updateScrollParent = function(targetElement) {
			var scrollParent, parentElement;
	
			scrollParent = targetElement.fastClickScrollParent;
	
			// Attempt to discover whether the target element is contained within a scrollable layer. Re-check if the
			// target element was moved to another parent.
			if (!scrollParent || !scrollParent.contains(targetElement)) {
				parentElement = targetElement;
				do {
					if (parentElement.scrollHeight > parentElement.offsetHeight) {
						scrollParent = parentElement;
						targetElement.fastClickScrollParent = parentElement;
						break;
					}
	
					parentElement = parentElement.parentElement;
				} while (parentElement);
			}
	
			// Always update the scroll top tracker if possible.
			if (scrollParent) {
				scrollParent.fastClickLastScrollTop = scrollParent.scrollTop;
			}
		};
	
	
		/**
		 * @param {EventTarget} targetElement
		 * @returns {Element|EventTarget}
		 */
		FastClick.prototype.getTargetElementFromEventTarget = function(eventTarget) {
	
			// On some older browsers (notably Safari on iOS 4.1 - see issue #56) the event target may be a text node.
			if (eventTarget.nodeType === Node.TEXT_NODE) {
				return eventTarget.parentNode;
			}
	
			return eventTarget;
		};
	
	
		/**
		 * On touch start, record the position and scroll offset.
		 *
		 * @param {Event} event
		 * @returns {boolean}
		 */
		FastClick.prototype.onTouchStart = function(event) {
			var targetElement, touch, selection;
	
			// Ignore multiple touches, otherwise pinch-to-zoom is prevented if both fingers are on the FastClick element (issue #111).
			if (event.targetTouches.length > 1) {
				return true;
			}
	
			targetElement = this.getTargetElementFromEventTarget(event.target);
			touch = event.targetTouches[0];
	
			if (deviceIsIOS) {
	
				// Only trusted events will deselect text on iOS (issue #49)
				selection = window.getSelection();
				if (selection.rangeCount && !selection.isCollapsed) {
					return true;
				}
	
				if (!deviceIsIOS4) {
	
					// Weird things happen on iOS when an alert or confirm dialog is opened from a click event callback (issue #23):
					// when the user next taps anywhere else on the page, new touchstart and touchend events are dispatched
					// with the same identifier as the touch event that previously triggered the click that triggered the alert.
					// Sadly, there is an issue on iOS 4 that causes some normal touch events to have the same identifier as an
					// immediately preceeding touch event (issue #52), so this fix is unavailable on that platform.
					// Issue 120: touch.identifier is 0 when Chrome dev tools 'Emulate touch events' is set with an iOS device UA string,
					// which causes all touch events to be ignored. As this block only applies to iOS, and iOS identifiers are always long,
					// random integers, it's safe to to continue if the identifier is 0 here.
					if (touch.identifier && touch.identifier === this.lastTouchIdentifier) {
						event.preventDefault();
						return false;
					}
	
					this.lastTouchIdentifier = touch.identifier;
	
					// If the target element is a child of a scrollable layer (using -webkit-overflow-scrolling: touch) and:
					// 1) the user does a fling scroll on the scrollable layer
					// 2) the user stops the fling scroll with another tap
					// then the event.target of the last 'touchend' event will be the element that was under the user's finger
					// when the fling scroll was started, causing FastClick to send a click event to that layer - unless a check
					// is made to ensure that a parent layer was not scrolled before sending a synthetic click (issue #42).
					this.updateScrollParent(targetElement);
				}
			}
	
			this.trackingClick = true;
			this.trackingClickStart = event.timeStamp;
			this.targetElement = targetElement;
	
			this.touchStartX = touch.pageX;
			this.touchStartY = touch.pageY;
	
			// Prevent phantom clicks on fast double-tap (issue #36)
			if ((event.timeStamp - this.lastClickTime) < this.tapDelay) {
				event.preventDefault();
			}
	
			return true;
		};
	
	
		/**
		 * Based on a touchmove event object, check whether the touch has moved past a boundary since it started.
		 *
		 * @param {Event} event
		 * @returns {boolean}
		 */
		FastClick.prototype.touchHasMoved = function(event) {
			var touch = event.changedTouches[0], boundary = this.touchBoundary;
	
			if (Math.abs(touch.pageX - this.touchStartX) > boundary || Math.abs(touch.pageY - this.touchStartY) > boundary) {
				return true;
			}
	
			return false;
		};
	
	
		/**
		 * Update the last position.
		 *
		 * @param {Event} event
		 * @returns {boolean}
		 */
		FastClick.prototype.onTouchMove = function(event) {
			if (!this.trackingClick) {
				return true;
			}
	
			// If the touch has moved, cancel the click tracking
			if (this.targetElement !== this.getTargetElementFromEventTarget(event.target) || this.touchHasMoved(event)) {
				this.trackingClick = false;
				this.targetElement = null;
			}
	
			return true;
		};
	
	
		/**
		 * Attempt to find the labelled control for the given label element.
		 *
		 * @param {EventTarget|HTMLLabelElement} labelElement
		 * @returns {Element|null}
		 */
		FastClick.prototype.findControl = function(labelElement) {
	
			// Fast path for newer browsers supporting the HTML5 control attribute
			if (labelElement.control !== undefined) {
				return labelElement.control;
			}
	
			// All browsers under test that support touch events also support the HTML5 htmlFor attribute
			if (labelElement.htmlFor) {
				return document.getElementById(labelElement.htmlFor);
			}
	
			// If no for attribute exists, attempt to retrieve the first labellable descendant element
			// the list of which is defined here: http://www.w3.org/TR/html5/forms.html#category-label
			return labelElement.querySelector('button, input:not([type=hidden]), keygen, meter, output, progress, select, textarea');
		};
	
	
		/**
		 * On touch end, determine whether to send a click event at once.
		 *
		 * @param {Event} event
		 * @returns {boolean}
		 */
		FastClick.prototype.onTouchEnd = function(event) {
			var forElement, trackingClickStart, targetTagName, scrollParent, touch, targetElement = this.targetElement;
	
			if (!this.trackingClick) {
				return true;
			}
	
			// Prevent phantom clicks on fast double-tap (issue #36)
			if ((event.timeStamp - this.lastClickTime) < this.tapDelay) {
				this.cancelNextClick = true;
				return true;
			}
	
			if ((event.timeStamp - this.trackingClickStart) > this.tapTimeout) {
				return true;
			}
	
			// Reset to prevent wrong click cancel on input (issue #156).
			this.cancelNextClick = false;
	
			this.lastClickTime = event.timeStamp;
	
			trackingClickStart = this.trackingClickStart;
			this.trackingClick = false;
			this.trackingClickStart = 0;
	
			// On some iOS devices, the targetElement supplied with the event is invalid if the layer
			// is performing a transition or scroll, and has to be re-detected manually. Note that
			// for this to function correctly, it must be called *after* the event target is checked!
			// See issue #57; also filed as rdar://13048589 .
			if (deviceIsIOSWithBadTarget) {
				touch = event.changedTouches[0];
	
				// In certain cases arguments of elementFromPoint can be negative, so prevent setting targetElement to null
				targetElement = document.elementFromPoint(touch.pageX - window.pageXOffset, touch.pageY - window.pageYOffset) || targetElement;
				targetElement.fastClickScrollParent = this.targetElement.fastClickScrollParent;
			}
	
			targetTagName = targetElement.tagName.toLowerCase();
			if (targetTagName === 'label') {
				forElement = this.findControl(targetElement);
				if (forElement) {
					this.focus(targetElement);
					if (deviceIsAndroid) {
						return false;
					}
	
					targetElement = forElement;
				}
			} else if (this.needsFocus(targetElement)) {
	
				// Case 1: If the touch started a while ago (best guess is 100ms based on tests for issue #36) then focus will be triggered anyway. Return early and unset the target element reference so that the subsequent click will be allowed through.
				// Case 2: Without this exception for input elements tapped when the document is contained in an iframe, then any inputted text won't be visible even though the value attribute is updated as the user types (issue #37).
				if ((event.timeStamp - trackingClickStart) > 100 || (deviceIsIOS && window.top !== window && targetTagName === 'input')) {
					this.targetElement = null;
					return false;
				}
	
				this.focus(targetElement);
				this.sendClick(targetElement, event);
	
				// Select elements need the event to go through on iOS 4, otherwise the selector menu won't open.
				// Also this breaks opening selects when VoiceOver is active on iOS6, iOS7 (and possibly others)
				if (!deviceIsIOS || targetTagName !== 'select') {
					this.targetElement = null;
					event.preventDefault();
				}
	
				return false;
			}
	
			if (deviceIsIOS && !deviceIsIOS4) {
	
				// Don't send a synthetic click event if the target element is contained within a parent layer that was scrolled
				// and this tap is being used to stop the scrolling (usually initiated by a fling - issue #42).
				scrollParent = targetElement.fastClickScrollParent;
				if (scrollParent && scrollParent.fastClickLastScrollTop !== scrollParent.scrollTop) {
					return true;
				}
			}
	
			// Prevent the actual click from going though - unless the target node is marked as requiring
			// real clicks or if it is in the whitelist in which case only non-programmatic clicks are permitted.
			if (!this.needsClick(targetElement)) {
				event.preventDefault();
				this.sendClick(targetElement, event);
			}
	
			return false;
		};
	
	
		/**
		 * On touch cancel, stop tracking the click.
		 *
		 * @returns {void}
		 */
		FastClick.prototype.onTouchCancel = function() {
			this.trackingClick = false;
			this.targetElement = null;
		};
	
	
		/**
		 * Determine mouse events which should be permitted.
		 *
		 * @param {Event} event
		 * @returns {boolean}
		 */
		FastClick.prototype.onMouse = function(event) {
	
			// If a target element was never set (because a touch event was never fired) allow the event
			if (!this.targetElement) {
				return true;
			}
	
			if (event.forwardedTouchEvent) {
				return true;
			}
	
			// Programmatically generated events targeting a specific element should be permitted
			if (!event.cancelable) {
				return true;
			}
	
			// Derive and check the target element to see whether the mouse event needs to be permitted;
			// unless explicitly enabled, prevent non-touch click events from triggering actions,
			// to prevent ghost/doubleclicks.
			if (!this.needsClick(this.targetElement) || this.cancelNextClick) {
	
				// Prevent any user-added listeners declared on FastClick element from being fired.
				if (event.stopImmediatePropagation) {
					event.stopImmediatePropagation();
				} else {
	
					// Part of the hack for browsers that don't support Event#stopImmediatePropagation (e.g. Android 2)
					event.propagationStopped = true;
				}
	
				// Cancel the event
				event.stopPropagation();
				event.preventDefault();
	
				return false;
			}
	
			// If the mouse event is permitted, return true for the action to go through.
			return true;
		};
	
	
		/**
		 * On actual clicks, determine whether this is a touch-generated click, a click action occurring
		 * naturally after a delay after a touch (which needs to be cancelled to avoid duplication), or
		 * an actual click which should be permitted.
		 *
		 * @param {Event} event
		 * @returns {boolean}
		 */
		FastClick.prototype.onClick = function(event) {
			var permitted;
	
			// It's possible for another FastClick-like library delivered with third-party code to fire a click event before FastClick does (issue #44). In that case, set the click-tracking flag back to false and return early. This will cause onTouchEnd to return early.
			if (this.trackingClick) {
				this.targetElement = null;
				this.trackingClick = false;
				return true;
			}
	
			// Very odd behaviour on iOS (issue #18): if a submit element is present inside a form and the user hits enter in the iOS simulator or clicks the Go button on the pop-up OS keyboard the a kind of 'fake' click event will be triggered with the submit-type input element as the target.
			if (event.target.type === 'submit' && event.detail === 0) {
				return true;
			}
	
			permitted = this.onMouse(event);
	
			// Only unset targetElement if the click is not permitted. This will ensure that the check for !targetElement in onMouse fails and the browser's click doesn't go through.
			if (!permitted) {
				this.targetElement = null;
			}
	
			// If clicks are permitted, return true for the action to go through.
			return permitted;
		};
	
	
		/**
		 * Remove all FastClick's event listeners.
		 *
		 * @returns {void}
		 */
		FastClick.prototype.destroy = function() {
			var layer = this.layer;
	
			if (deviceIsAndroid) {
				layer.removeEventListener('mouseover', this.onMouse, true);
				layer.removeEventListener('mousedown', this.onMouse, true);
				layer.removeEventListener('mouseup', this.onMouse, true);
			}
	
			layer.removeEventListener('click', this.onClick, true);
			layer.removeEventListener('touchstart', this.onTouchStart, false);
			layer.removeEventListener('touchmove', this.onTouchMove, false);
			layer.removeEventListener('touchend', this.onTouchEnd, false);
			layer.removeEventListener('touchcancel', this.onTouchCancel, false);
		};
	
	
		/**
		 * Check whether FastClick is needed.
		 *
		 * @param {Element} layer The layer to listen on
		 */
		FastClick.notNeeded = function(layer) {
			var metaViewport;
			var chromeVersion;
			var blackberryVersion;
			var firefoxVersion;
	
			// Devices that don't support touch don't need FastClick
			if (typeof window.ontouchstart === 'undefined') {
				return true;
			}
	
			// Chrome version - zero for other browsers
			chromeVersion = +(/Chrome\/([0-9]+)/.exec(navigator.userAgent) || [,0])[1];
	
			if (chromeVersion) {
	
				if (deviceIsAndroid) {
					metaViewport = document.querySelector('meta[name=viewport]');
	
					if (metaViewport) {
						// Chrome on Android with user-scalable="no" doesn't need FastClick (issue #89)
						if (metaViewport.content.indexOf('user-scalable=no') !== -1) {
							return true;
						}
						// Chrome 32 and above with width=device-width or less don't need FastClick
						if (chromeVersion > 31 && document.documentElement.scrollWidth <= window.outerWidth) {
							return true;
						}
					}
	
				// Chrome desktop doesn't need FastClick (issue #15)
				} else {
					return true;
				}
			}
	
			if (deviceIsBlackBerry10) {
				blackberryVersion = navigator.userAgent.match(/Version\/([0-9]*)\.([0-9]*)/);
	
				// BlackBerry 10.3+ does not require Fastclick library.
				// https://github.com/ftlabs/fastclick/issues/251
				if (blackberryVersion[1] >= 10 && blackberryVersion[2] >= 3) {
					metaViewport = document.querySelector('meta[name=viewport]');
	
					if (metaViewport) {
						// user-scalable=no eliminates click delay.
						if (metaViewport.content.indexOf('user-scalable=no') !== -1) {
							return true;
						}
						// width=device-width (or less than device-width) eliminates click delay.
						if (document.documentElement.scrollWidth <= window.outerWidth) {
							return true;
						}
					}
				}
			}
	
			// IE10 with -ms-touch-action: none or manipulation, which disables double-tap-to-zoom (issue #97)
			if (layer.style.msTouchAction === 'none' || layer.style.touchAction === 'manipulation') {
				return true;
			}
	
			// Firefox version - zero for other browsers
			firefoxVersion = +(/Firefox\/([0-9]+)/.exec(navigator.userAgent) || [,0])[1];
	
			if (firefoxVersion >= 27) {
				// Firefox 27+ does not have tap delay if the content is not zoomable - https://bugzilla.mozilla.org/show_bug.cgi?id=922896
	
				metaViewport = document.querySelector('meta[name=viewport]');
				if (metaViewport && (metaViewport.content.indexOf('user-scalable=no') !== -1 || document.documentElement.scrollWidth <= window.outerWidth)) {
					return true;
				}
			}
	
			// IE11: prefixed -ms-touch-action is no longer supported and it's recomended to use non-prefixed version
			// http://msdn.microsoft.com/en-us/library/windows/apps/Hh767313.aspx
			if (layer.style.touchAction === 'none' || layer.style.touchAction === 'manipulation') {
				return true;
			}
	
			return false;
		};
	
	
		/**
		 * Factory method for creating a FastClick object
		 *
		 * @param {Element} layer The layer to listen on
		 * @param {Object} [options={}] The options to override the defaults
		 */
		FastClick.attach = function(layer, options) {
			return new FastClick(layer, options);
		};
	
	
		if (true) {
	
			// AMD. Register as an anonymous module.
			!(__WEBPACK_AMD_DEFINE_RESULT__ = function() {
				return FastClick;
			}.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
		} else if (typeof module !== 'undefined' && module.exports) {
			module.exports = FastClick.attach;
			module.exports.FastClick = FastClick;
		} else {
			window.FastClick = FastClick;
		}
	}());


/***/ },

/***/ 1295:
/***/ function(module, exports) {

	'use strict';
	
	campaignLayoutService.$inject = ["$location", "split", "campaign", "campaignContributeService"];
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	exports.default = campaignLayoutService;
	/*@ngInject*/
	function campaignLayoutService($location, split, campaign, campaignContributeService) {
	  var LAYOUT_EXPERIMENT = 'campaign_page_layouts';
	  var NO_BACK_IT_ACTIVE_VARIANT = 'experiment_tinky_winky';
	
	  return {
	    load: function load() {
	      split.checkVariantState(LAYOUT_EXPERIMENT);
	    },
	    isPerkOnlyLayout: function isPerkOnlyLayout() {
	      if (!campaignContributeService.doesCampaignAcceptContributions()) return true;
	      if (campaign.isTechDesignEligible() && split.experimentBuckets[LAYOUT_EXPERIMENT] === NO_BACK_IT_ACTIVE_VARIANT) {
	        return true;
	      }
	      return false;
	    },
	    isPreviewLayout: function isPreviewLayout() {
	      return !!$location.absUrl().match(/\/project\/preview\/.+/);
	    }
	  };
	}

/***/ },

/***/ 1296:
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	
	campaignOverview.$inject = ["campaign", "i18n"];
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	exports.default = campaignOverview;
	
	__webpack_require__(1297);
	
	/*@ngInject*/
	function campaignOverview(campaign, i18n) {
	  return {
	    restrict: 'E',
	    scope: {},
	    template: __webpack_require__(1299),
	    link: function link(scope) {
	      scope.campaign = campaign;
	      scope.i18n = i18n;
	
	      scope.hasManyPills = function () {
	        return scope.campaign.category && scope.campaign.product_stage;
	      };
	    }
	  };
	}

/***/ },

/***/ 1297:
/***/ function(module, exports, __webpack_require__) {

	// style-loader: Adds some css to the DOM by adding a <style> tag
	
	// load the styles
	var content = __webpack_require__(1298);
	if(typeof content === 'string') content = [[module.id, content, '']];
	// add the styles to the DOM
	var update = __webpack_require__(80)(content, {});
	if(content.locals) module.exports = content.locals;
	// Hot Module Replacement
	if(false) {
		// When the styles change, update the <style> tags
		if(!content.locals) {
			module.hot.accept("!!./../node_modules/css-loader/index.js!./../node_modules/less-loader/index.js!./campaign-overview.less", function() {
				var newContent = require("!!./../node_modules/css-loader/index.js!./../node_modules/less-loader/index.js!./campaign-overview.less");
				if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];
				update(newContent);
			});
		}
		// When the module is disposed, remove the <style> tags
		module.hot.dispose(function() { update(); });
	}

/***/ },

/***/ 1298:
/***/ function(module, exports, __webpack_require__) {

	exports = module.exports = __webpack_require__(79)();
	// imports
	
	
	// module
	exports.push([module.id, "/* Antenna Font Family Variations */\n/* Benton Font Family Variations */\n/** Perk Store mobile header text **/\n/** Only mobile campaign/contributions **/\n/* We can define top-left-dimple or left-top-dimple etc as necessary */\n.raised-sizing {\n  font-family: \"Benton Sans\", \"Helvetica\", \"sans-serif\";\n  font-size: 12px;\n  font-weight: normal;\n  line-height: 18px;\n}\n@media (min-width: 1002px) {\n  .raised-sizing {\n    font-family: \"Benton Sans\", \"Helvetica\", \"sans-serif\";\n    font-size: 16px;\n    font-weight: normal;\n    line-height: 26px;\n    letter-spacing: 0;\n    line-height: 25px;\n  }\n}\n.amount-sizing {\n  font-family: \"Benton Sans\", \"Helvetica\", \"sans-serif\";\n  font-weight: bold;\n  font-size: 14px;\n  line-height: 20px;\n}\n@media (min-width: 1002px) {\n  .amount-sizing {\n    font-family: \"Benton Sans\", \"Helvetica\", \"sans-serif\";\n    font-size: 20px;\n    font-weight: bold;\n    line-height: 26px;\n  }\n}\n@media (min-width: 1002px) {\n  .video-heights-for-2-columns {\n    height: 415px;\n  }\n}\n@media (min-width: 1280px) {\n  .video-heights-for-2-columns {\n    height: 460px !important;\n  }\n}\n.body-section-header-text-sizing {\n  font-family: \"Benton Sans\", \"Helvetica\", \"sans-serif\";\n  font-size: 14px;\n  font-weight: normal;\n  line-height: 20px;\n}\n@media (min-width: 1280px) {\n  .body-section-header-text-sizing {\n    font-family: \"Benton Sans\", \"Helvetica\", \"sans-serif\";\n    font-size: 16px;\n    font-weight: normal;\n    line-height: 26px;\n    letter-spacing: 0;\n  }\n}\n.body-sub-section-header-title {\n  font-family: \"Benton Sans\", \"Helvetica\", \"sans-serif\";\n  font-size: 14px;\n  font-weight: normal;\n  line-height: 20px;\n  color: #a8a8a8;\n  margin-top: 20px;\n  margin-bottom: 20px;\n  padding-top: 5px;\n  padding-bottom: 5px;\n  text-transform: uppercase;\n  border-bottom: 1px solid #dddddd;\n}\n@media (min-width: 1280px) {\n  .body-sub-section-header-title {\n    font-family: \"Benton Sans\", \"Helvetica\", \"sans-serif\";\n    font-size: 16px;\n    font-weight: normal;\n    line-height: 26px;\n    letter-spacing: 0;\n  }\n}\n@media not all and (min-width: 768px) {\n  .body-sub-section-header-title {\n    margin-left: 20px;\n    margin-right: 20px;\n  }\n}\n.campaignOverview {\n  margin-bottom: 10px;\n}\n@media not all and (min-width: 768px) {\n  .campaignOverview {\n    margin-left: 20px;\n    margin-right: 20px;\n  }\n}\n.campaignOverview-header {\n  font-family: \"Benton Sans\", \"Helvetica\", \"sans-serif\";\n  font-size: 14px;\n  font-weight: normal;\n  line-height: 20px;\n  color: #a8a8a8;\n  margin-top: 20px;\n  margin-bottom: 20px;\n  padding-top: 5px;\n  padding-bottom: 5px;\n  text-transform: uppercase;\n  border-bottom: 1px solid #dddddd;\n}\n@media (min-width: 1280px) {\n  .campaignOverview-header {\n    font-family: \"Benton Sans\", \"Helvetica\", \"sans-serif\";\n    font-size: 16px;\n    font-weight: normal;\n    line-height: 26px;\n    letter-spacing: 0;\n  }\n}\n.campaignOverview-headerTitle {\n  float: left;\n}\n.campaignOverview-blockPills {\n  display: none;\n}\n.campaignOverview-inlinePills {\n  float: right;\n}\n@media not all and (min-width: 480px) {\n  .campaignOverview--manyPills .campaignOverview-header {\n    margin-bottom: 5px;\n  }\n  .campaignOverview--manyPills .campaignOverview-blockPills {\n    display: inline-block;\n    margin-bottom: 5px;\n  }\n  .campaignOverview--manyPills .campaignOverview-inlinePills {\n    display: none;\n  }\n}\n.campaignOverview-clear {\n  clear: both;\n}\n.campaignOverview-content {\n  overflow: auto;\n  font-family: \"Benton Sans\", \"Helvetica\", \"sans-serif\";\n  font-size: 12px;\n  font-weight: normal;\n  line-height: 18px;\n}\n@media (min-width: 1002px) {\n  .campaignOverview-content {\n    font-family: \"Benton Sans\", \"Helvetica\", \"sans-serif\";\n    font-size: 14px;\n    font-weight: normal;\n    line-height: 20px;\n  }\n}\n.campaignOverview-contentImage {\n  margin-bottom: 15px;\n}\n.campaignOverview-contentImage img {\n  width: 100%;\n}\n@media (min-width: 480px) {\n  .campaignOverview-contentImage {\n    float: left;\n    height: 183px;\n    margin-right: 20px;\n  }\n  .campaignOverview-contentImage img {\n    height: 100%;\n    width: auto;\n  }\n}\n@media (min-width: 1002px) {\n  .campaignOverview-contentImage {\n    height: 185px;\n  }\n}\n", ""]);
	
	// exports


/***/ },

/***/ 1299:
/***/ function(module, exports) {

	module.exports = "<div class=\"campaignOverview\" ng-class=\"{'campaignOverview--manyPills': hasManyPills()}\">\n  <div class=\"campaignOverview-header\">\n    <div class=\"campaignOverview-headerTitle\">\n      {{::i18n.t('overview')}}\n    </div>\n    <campaign-pills class=\"campaignOverview-inlinePills\"></campaign-pills>\n    <div class=\"campaignOverview-clear\"></div>\n  </div>\n  <campaign-pills class=\"campaignOverview-blockPills\"></campaign-pills>\n\n  <div class=\"campaignOverview-content\" gogo-test=\"overview\">\n    <div class=\"campaignOverview-contentImage\">\n      <img ng-src=\"{{campaign.overview_image_url}}\" gogo-test=\"overview_image\">\n    </div>\n    {{campaign.overview}}\n  </div>\n</div>\n";

/***/ },

/***/ 1300:
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	
	campaignPills.$inject = ["campaign"];
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	exports.default = campaignPills;
	
	__webpack_require__(1301);
	
	/*@ngInject*/
	function campaignPills(campaign) {
	  return {
	    restrict: 'E',
	    scope: {},
	    template: __webpack_require__(1303),
	    link: function link(scope) {
	      scope.campaign = campaign;
	    }
	  };
	}

/***/ },

/***/ 1301:
/***/ function(module, exports, __webpack_require__) {

	// style-loader: Adds some css to the DOM by adding a <style> tag
	
	// load the styles
	var content = __webpack_require__(1302);
	if(typeof content === 'string') content = [[module.id, content, '']];
	// add the styles to the DOM
	var update = __webpack_require__(80)(content, {});
	if(content.locals) module.exports = content.locals;
	// Hot Module Replacement
	if(false) {
		// When the styles change, update the <style> tags
		if(!content.locals) {
			module.hot.accept("!!./../node_modules/css-loader/index.js!./../node_modules/less-loader/index.js!./campaign-pills.less", function() {
				var newContent = require("!!./../node_modules/css-loader/index.js!./../node_modules/less-loader/index.js!./campaign-pills.less");
				if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];
				update(newContent);
			});
		}
		// When the module is disposed, remove the <style> tags
		module.hot.dispose(function() { update(); });
	}

/***/ },

/***/ 1302:
/***/ function(module, exports, __webpack_require__) {

	exports = module.exports = __webpack_require__(79)();
	// imports
	
	
	// module
	exports.push([module.id, ".campaignPills campaign-product-stage,\n.campaignPills campaign-category {\n  display: inline-block;\n}\n", ""]);
	
	// exports


/***/ },

/***/ 1303:
/***/ function(module, exports) {

	module.exports = "<div class=\"campaignPills\">\n  <campaign-category ng-if=\"campaign.category\"></campaign-category>\n  <campaign-product-stage ng-if=\"campaign.product_stage\"></campaign-product-stage>\n</div>\n";

/***/ },

/***/ 1304:
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	
	campaignPage.$inject = ["campaign"];
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	exports.default = campaignPage;
	
	__webpack_require__(1305);
	
	/*@ngInject*/
	function campaignPage(campaign) {
	  return {
	    restrict: 'E',
	    scope: {},
	    template: __webpack_require__(1307),
	    link: function link(scope) {
	      scope.campaign = campaign;
	    }
	  };
	}

/***/ },

/***/ 1305:
/***/ function(module, exports, __webpack_require__) {

	// style-loader: Adds some css to the DOM by adding a <style> tag
	
	// load the styles
	var content = __webpack_require__(1306);
	if(typeof content === 'string') content = [[module.id, content, '']];
	// add the styles to the DOM
	var update = __webpack_require__(80)(content, {});
	if(content.locals) module.exports = content.locals;
	// Hot Module Replacement
	if(false) {
		// When the styles change, update the <style> tags
		if(!content.locals) {
			module.hot.accept("!!./../node_modules/css-loader/index.js!./../node_modules/less-loader/index.js!./campaign-page.less", function() {
				var newContent = require("!!./../node_modules/css-loader/index.js!./../node_modules/less-loader/index.js!./campaign-page.less");
				if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];
				update(newContent);
			});
		}
		// When the module is disposed, remove the <style> tags
		module.hot.dispose(function() { update(); });
	}

/***/ },

/***/ 1306:
/***/ function(module, exports, __webpack_require__) {

	exports = module.exports = __webpack_require__(79)();
	// imports
	
	
	// module
	exports.push([module.id, "/* Antenna Font Family Variations */\n/* Benton Font Family Variations */\n/** Perk Store mobile header text **/\n/** Only mobile campaign/contributions **/\n/* We can define top-left-dimple or left-top-dimple etc as necessary */\n.campaignPage-hero {\n  margin-bottom: 30px;\n}\n.campaignPage .hidden--animated {\n  opacity: 0;\n  visibility: hidden;\n}\ncampaign-header-pitch {\n  position: relative;\n  float: left;\n  width: 100%;\n  min-height: 1px;\n  padding-left: 6px;\n  padding-right: 6px;\n}\n@media not all and (min-width: 480px) {\n  campaign-header-pitch {\n    padding-left: 0;\n    padding-right: 0;\n  }\n}\n@media (min-width: 480px) and (max-width: 767px) {\n  campaign-header-pitch {\n    position: relative;\n    float: left;\n    width: 100%;\n    min-height: 1px;\n    padding-left: 6px;\n    padding-right: 6px;\n  }\n}\n@media (min-width: 768px) {\n  campaign-header-pitch {\n    position: relative;\n    min-height: 1px;\n    padding-left: 10px;\n    padding-right: 10px;\n    float: left;\n    width: 58.33333333%;\n  }\n}\n@media (min-width: 1002px) {\n  campaign-header-pitch {\n    position: relative;\n    min-height: 1px;\n    padding-left: 15px;\n    padding-right: 15px;\n    float: left;\n    width: 58.33333333%;\n  }\n}\n@media (min-width: 1280px) {\n  campaign-header-pitch {\n    position: relative;\n    min-height: 1px;\n    padding-left: 20px;\n    padding-right: 20px;\n    float: left;\n    width: 58.33333333%;\n  }\n}\ncampaign-header-basics {\n  position: relative;\n  float: left;\n  width: 100%;\n  min-height: 1px;\n  padding-left: 6px;\n  padding-right: 6px;\n}\n@media not all and (min-width: 768px) {\n  campaign-header-basics {\n    margin-top: 20px;\n    padding-left: 0;\n    padding-right: 0;\n  }\n}\n@media (min-width: 480px) and (max-width: 767px) {\n  campaign-header-basics {\n    position: relative;\n    float: left;\n    width: 100%;\n    min-height: 1px;\n    padding-left: 6px;\n    padding-right: 6px;\n  }\n}\n@media (min-width: 768px) {\n  campaign-header-basics {\n    position: relative;\n    min-height: 1px;\n    padding-left: 10px;\n    padding-right: 10px;\n    float: left;\n    width: 41.66666667%;\n  }\n}\n@media (min-width: 1002px) {\n  campaign-header-basics {\n    position: relative;\n    min-height: 1px;\n    padding-left: 15px;\n    padding-right: 15px;\n    float: left;\n    width: 41.66666667%;\n  }\n}\n@media (min-width: 1280px) {\n  campaign-header-basics {\n    position: relative;\n    min-height: 1px;\n    padding-left: 20px;\n    padding-right: 20px;\n    float: left;\n    width: 41.66666667%;\n  }\n}\n", ""]);
	
	// exports


/***/ },

/***/ 1307:
/***/ function(module, exports) {

	module.exports = "<div class=\"campaignPage container container--mobileFullWidth\" gogo-test=\"campaign_page\">\n  <div class=\"campaignPage-hero row\">\n    <campaign-header-pitch></campaign-header-pitch>\n    <campaign-header-basics></campaign-header-basics>\n  </div>\n  <campaign-body></campaign-body>\n</div>\n<campaign-page-tracking></campaign-page-tracking>\n";

/***/ },

/***/ 1308:
/***/ function(module, exports) {

	'use strict';
	
	campaignPageTracking.$inject = ["gon", "ga", "$window", "gogoEvents"];
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	exports.default = campaignPageTracking;
	
	/*@ngInject*/
	function campaignPageTracking(gon, ga, $window, gogoEvents) {
	  return {
	    restrict: 'E',
	    scope: {},
	    link: function link() {
	      gaTracking();
	      if (gon.tracking_info) {
	        var trackingInfo = gon.tracking_info;
	        if (trackingInfo.fb_pixel_id) {
	          setupFacebookAnalytics(trackingInfo);
	        }
	        if (trackingInfo.google_analytics_id) {
	          setupGoogleTracking(trackingInfo);
	        }
	      }
	
	      function gaTracking() {
	        if (gon && gon.tracking_info && gon.tracking_info.google_analytics_id) {
	          // TODO EVENTS: id=iw1o3 fixtype=ga-create subsystem=ga-ecommerce . unify campaign creator
	          ga('create', gon.tracking_info.google_analytics_id, 'auto', { 'name': 'campaign' });
	          ga('campaign.require', 'ec');
	          ga('campaign.ec:addImpression', gon.ga_impression_data);
	          ga('campaign.ec:addProduct', gon.ga_impression_data);
	          ga('campaign.ec:setAction', 'detail');
	          // TODO EVENTS: id=oo8ee subsystem=campaigner-analytics fixtype=pageview . review campaigner ecommerce
	          ga('campaign.send', 'pageview', gon.pageview_data.analytics_friendly_url);
	        }
	
	        ga('require', 'ec');
	        ga('ec:addImpression', gon.ga_impression_data);
	        ga('ec:addProduct', gon.ga_impression_data);
	        ga('ec:setAction', 'detail');
	
	        var thetaEvent = {
	          thetaName: 'ga_ec_campaign_page_next/detail'
	        };
	
	        gogoEvents.track(_.merge(thetaEvent, gon.ga_impression_data), { skipGa: true });
	        // TODO EVENTS: id=dae4i fixtype=infra subsystem=campaign-page . unify contentGroup usage
	        ga('set', 'contentGroup1', 'Campaign');
	        // TODO EVENTS: id=ju6ph fixtype=pageview subsystem=campaign-page . review pageview
	        ga('send', 'pageview', gon.pageview_data.analytics_friendly_url);
	      }
	
	      function setupFacebookAnalytics(trackingInfo) {
	        $window.fb_param = {
	          'pixel_id': trackingInfo.fb_pixel_id,
	          'value': trackingInfo.amount,
	          'currency': trackingInfo.currency_iso_code
	        };
	      }
	
	      function setupGoogleTracking(trackingInfo) {
	        // TODO EVENTS: id=zoo6w fixtype=gaq subsystem=campaign-page . pageview also here
	        $window._gaq = [['campaign._setAccount', trackingInfo.google_analytics_id], ['campaign._trackPageview']];
	        setTimeout(pushAdjustedBounceEvent, 30000);
	      }
	
	      function pushAdjustedBounceEvent() {
	        // TODO EVENTS: id=zoo6y fixtype=gaq category=30_seconds category-new=TBD action=read subsystem=campaign-page . Upgrade from _gaq to modern usage
	        $window._gaq.push(['campaign._trackEvent', '30_seconds', 'read']);
	      }
	    }
	  };
	}

/***/ },

/***/ 1309:
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	
	campaignProductStage.$inject = ["campaign", "i18n", "$sce", "$popover"];
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	exports.default = campaignProductStage;
	
	__webpack_require__(1310);
	
	/*@ngInject*/
	function campaignProductStage(campaign, i18n, $sce, $popover) {
	  return {
	    restrict: 'E',
	    scope: {},
	    template: __webpack_require__(1312),
	    link: function link(scope, element) {
	      var _popover = $popover(element, {
	        html: true,
	        content: content(),
	        placement: 'top',
	        container: 'body',
	        trigger: 'manual',
	        autoClose: true
	      });
	      scope.popover = _popover.$scope;
	      scope.i18n = i18n;
	      scope.label = label();
	
	      function label() {
	        return i18n.t('campaign_page_next.product_stage.label.' + campaign.product_stage);
	      }
	
	      function content() {
	        return $sce.trustAsHtml(description() + '<br>' + learnMore());
	      }
	
	      function learnMore() {
	        var link = 'https://support.indiegogo.com/hc/en-us/articles/221613968';
	        return '<a href=\'' + link + '\' target=\'_blank\'>' + i18n.t('learn_more') + '</a>';
	      }
	
	      function description() {
	        return i18n.t('campaign_page_next.product_stage.popover_text.' + campaign.product_stage);
	      }
	    }
	  };
	}

/***/ },

/***/ 1310:
/***/ function(module, exports, __webpack_require__) {

	// style-loader: Adds some css to the DOM by adding a <style> tag
	
	// load the styles
	var content = __webpack_require__(1311);
	if(typeof content === 'string') content = [[module.id, content, '']];
	// add the styles to the DOM
	var update = __webpack_require__(80)(content, {});
	if(content.locals) module.exports = content.locals;
	// Hot Module Replacement
	if(false) {
		// When the styles change, update the <style> tags
		if(!content.locals) {
			module.hot.accept("!!./../node_modules/css-loader/index.js!./../node_modules/less-loader/index.js!./campaign-product-stage.less", function() {
				var newContent = require("!!./../node_modules/css-loader/index.js!./../node_modules/less-loader/index.js!./campaign-product-stage.less");
				if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];
				update(newContent);
			});
		}
		// When the module is disposed, remove the <style> tags
		module.hot.dispose(function() { update(); });
	}

/***/ },

/***/ 1311:
/***/ function(module, exports, __webpack_require__) {

	exports = module.exports = __webpack_require__(79)();
	// imports
	
	
	// module
	exports.push([module.id, ".campaignProductStage {\n  position: relative;\n}\n.campaignProductStage-pill {\n  text-transform: uppercase;\n  text-decoration: none;\n  cursor: pointer;\n}\n", ""]);
	
	// exports


/***/ },

/***/ 1312:
/***/ function(module, exports) {

	module.exports = "<div class=\"campaignProductStage\">\n  <div class=\"campaignProductStage-pill i-annotation-pill i-annotation-pill--entre i-annotation-pill--green\"\n       gogo-test=\"product_stage\"\n       ng-click=\"popover.$toggle()\"\n       ng-mouseover=\"popover.$show()\">\n    {{::label}}\n  </div>\n</div>\n";

/***/ },

/***/ 1313:
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	
	campaignCategory.$inject = ["campaign", "i18n"];
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	exports.default = campaignCategory;
	
	__webpack_require__(1314);
	
	/*@ngInject*/
	function campaignCategory(campaign, i18n) {
	  return {
	    restrict: 'E',
	    scope: {},
	    template: __webpack_require__(1316),
	    link: function link(scope) {
	      scope.campaign = campaign;
	      scope.i18n = i18n;
	
	      scope.label = function () {
	        return i18n.t(campaign.category_slug);
	      };
	
	      scope.link = function () {
	        return '/explore/#/explore/' + campaign.category_slug;
	      };
	    }
	  };
	}

/***/ },

/***/ 1314:
/***/ function(module, exports, __webpack_require__) {

	// style-loader: Adds some css to the DOM by adding a <style> tag
	
	// load the styles
	var content = __webpack_require__(1315);
	if(typeof content === 'string') content = [[module.id, content, '']];
	// add the styles to the DOM
	var update = __webpack_require__(80)(content, {});
	if(content.locals) module.exports = content.locals;
	// Hot Module Replacement
	if(false) {
		// When the styles change, update the <style> tags
		if(!content.locals) {
			module.hot.accept("!!./../node_modules/css-loader/index.js!./../node_modules/less-loader/index.js!./campaign-category.less", function() {
				var newContent = require("!!./../node_modules/css-loader/index.js!./../node_modules/less-loader/index.js!./campaign-category.less");
				if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];
				update(newContent);
			});
		}
		// When the module is disposed, remove the <style> tags
		module.hot.dispose(function() { update(); });
	}

/***/ },

/***/ 1315:
/***/ function(module, exports, __webpack_require__) {

	exports = module.exports = __webpack_require__(79)();
	// imports
	
	
	// module
	exports.push([module.id, "/* Antenna Font Family Variations */\n/* Benton Font Family Variations */\n/** Perk Store mobile header text **/\n/** Only mobile campaign/contributions **/\n/* We can define top-left-dimple or left-top-dimple etc as necessary */\n.raised-sizing {\n  font-family: \"Benton Sans\", \"Helvetica\", \"sans-serif\";\n  font-size: 12px;\n  font-weight: normal;\n  line-height: 18px;\n}\n@media (min-width: 1002px) {\n  .raised-sizing {\n    font-family: \"Benton Sans\", \"Helvetica\", \"sans-serif\";\n    font-size: 16px;\n    font-weight: normal;\n    line-height: 26px;\n    letter-spacing: 0;\n    line-height: 25px;\n  }\n}\n.amount-sizing {\n  font-family: \"Benton Sans\", \"Helvetica\", \"sans-serif\";\n  font-weight: bold;\n  font-size: 14px;\n  line-height: 20px;\n}\n@media (min-width: 1002px) {\n  .amount-sizing {\n    font-family: \"Benton Sans\", \"Helvetica\", \"sans-serif\";\n    font-size: 20px;\n    font-weight: bold;\n    line-height: 26px;\n  }\n}\n@media (min-width: 1002px) {\n  .video-heights-for-2-columns {\n    height: 415px;\n  }\n}\n@media (min-width: 1280px) {\n  .video-heights-for-2-columns {\n    height: 460px !important;\n  }\n}\n.campaignCategory-pill:hover {\n  text-decoration: none;\n  color: #a8a8a8;\n}\n", ""]);
	
	// exports


/***/ },

/***/ 1316:
/***/ function(module, exports) {

	module.exports = "<div class=\"campaignCategory\">\n  <a class=\"campaignCategory-pill i-annotation-pill i-annotation-pill--entre i-annotation-pill--white\" gogo-test=\"category\" href=\"{{link()}}\">\n    {{label()}}\n  </a>\n</div>\n";

/***/ },

/***/ 1317:
/***/ function(module, exports, __webpack_require__) {

	// style-loader: Adds some css to the DOM by adding a <style> tag
	
	// load the styles
	var content = __webpack_require__(1318);
	if(typeof content === 'string') content = [[module.id, content, '']];
	// add the styles to the DOM
	var update = __webpack_require__(80)(content, {});
	if(content.locals) module.exports = content.locals;
	// Hot Module Replacement
	if(false) {
		// When the styles change, update the <style> tags
		if(!content.locals) {
			module.hot.accept("!!./../node_modules/css-loader/index.js!./../node_modules/less-loader/index.js!./campaign-pitchmedia.less", function() {
				var newContent = require("!!./../node_modules/css-loader/index.js!./../node_modules/less-loader/index.js!./campaign-pitchmedia.less");
				if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];
				update(newContent);
			});
		}
		// When the module is disposed, remove the <style> tags
		module.hot.dispose(function() { update(); });
	}

/***/ },

/***/ 1318:
/***/ function(module, exports, __webpack_require__) {

	exports = module.exports = __webpack_require__(79)();
	// imports
	
	
	// module
	exports.push([module.id, "/* Antenna Font Family Variations */\n/* Benton Font Family Variations */\n/** Perk Store mobile header text **/\n/** Only mobile campaign/contributions **/\n/* We can define top-left-dimple or left-top-dimple etc as necessary */\n.raised-sizing {\n  font-family: \"Benton Sans\", \"Helvetica\", \"sans-serif\";\n  font-size: 12px;\n  font-weight: normal;\n  line-height: 18px;\n}\n@media (min-width: 1002px) {\n  .raised-sizing {\n    font-family: \"Benton Sans\", \"Helvetica\", \"sans-serif\";\n    font-size: 16px;\n    font-weight: normal;\n    line-height: 26px;\n    letter-spacing: 0;\n    line-height: 25px;\n  }\n}\n.amount-sizing {\n  font-family: \"Benton Sans\", \"Helvetica\", \"sans-serif\";\n  font-weight: bold;\n  font-size: 14px;\n  line-height: 20px;\n}\n@media (min-width: 1002px) {\n  .amount-sizing {\n    font-family: \"Benton Sans\", \"Helvetica\", \"sans-serif\";\n    font-size: 20px;\n    font-weight: bold;\n    line-height: 26px;\n  }\n}\n@media (min-width: 1002px) {\n  .video-heights-for-2-columns {\n    height: 415px;\n  }\n}\n@media (min-width: 1280px) {\n  .video-heights-for-2-columns {\n    height: 460px !important;\n  }\n}\n@media not all and (min-width: 480px) {\n  .campaignPitchMedia-image {\n    height: 200px;\n  }\n}\n@media (min-width: 480px) {\n  .campaignPitchMedia-image {\n    height: 273px;\n  }\n}\n@media (min-width: 1002px) {\n  .campaignPitchMedia-image {\n    height: 415px;\n  }\n}\n@media (min-width: 1280px) {\n  .campaignPitchMedia-image {\n    height: 460px !important;\n  }\n}\n", ""]);
	
	// exports


/***/ },

/***/ 1319:
/***/ function(module, exports, __webpack_require__) {

	// style-loader: Adds some css to the DOM by adding a <style> tag
	
	// load the styles
	var content = __webpack_require__(1320);
	if(typeof content === 'string') content = [[module.id, content, '']];
	// add the styles to the DOM
	var update = __webpack_require__(80)(content, {});
	if(content.locals) module.exports = content.locals;
	// Hot Module Replacement
	if(false) {
		// When the styles change, update the <style> tags
		if(!content.locals) {
			module.hot.accept("!!./../node_modules/css-loader/index.js!./../node_modules/less-loader/index.js!./campaign-video.less", function() {
				var newContent = require("!!./../node_modules/css-loader/index.js!./../node_modules/less-loader/index.js!./campaign-video.less");
				if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];
				update(newContent);
			});
		}
		// When the module is disposed, remove the <style> tags
		module.hot.dispose(function() { update(); });
	}

/***/ },

/***/ 1320:
/***/ function(module, exports, __webpack_require__) {

	exports = module.exports = __webpack_require__(79)();
	// imports
	
	
	// module
	exports.push([module.id, "/* Antenna Font Family Variations */\n/* Benton Font Family Variations */\n/** Perk Store mobile header text **/\n/** Only mobile campaign/contributions **/\n/* We can define top-left-dimple or left-top-dimple etc as necessary */\n.raised-sizing {\n  font-family: \"Benton Sans\", \"Helvetica\", \"sans-serif\";\n  font-size: 12px;\n  font-weight: normal;\n  line-height: 18px;\n}\n@media (min-width: 1002px) {\n  .raised-sizing {\n    font-family: \"Benton Sans\", \"Helvetica\", \"sans-serif\";\n    font-size: 16px;\n    font-weight: normal;\n    line-height: 26px;\n    letter-spacing: 0;\n    line-height: 25px;\n  }\n}\n.amount-sizing {\n  font-family: \"Benton Sans\", \"Helvetica\", \"sans-serif\";\n  font-weight: bold;\n  font-size: 14px;\n  line-height: 20px;\n}\n@media (min-width: 1002px) {\n  .amount-sizing {\n    font-family: \"Benton Sans\", \"Helvetica\", \"sans-serif\";\n    font-size: 20px;\n    font-weight: bold;\n    line-height: 26px;\n  }\n}\n@media (min-width: 1002px) {\n  .video-heights-for-2-columns {\n    height: 415px;\n  }\n}\n@media (min-width: 1280px) {\n  .video-heights-for-2-columns {\n    height: 460px !important;\n  }\n}\n@media not all and (min-width: 480px) {\n  .campaignVideo-youtube,\n  .campaignVideo-vimeo {\n    height: 200px;\n  }\n}\n@media (min-width: 480px) {\n  .campaignVideo-youtube,\n  .campaignVideo-vimeo {\n    height: 273px;\n  }\n}\n@media (min-width: 1002px) {\n  .campaignVideo-youtube,\n  .campaignVideo-vimeo {\n    height: 415px;\n  }\n}\n@media (min-width: 1280px) {\n  .campaignVideo-youtube,\n  .campaignVideo-vimeo {\n    height: 460px !important;\n  }\n}\n", ""]);
	
	// exports


/***/ },

/***/ 1321:
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	
	campaignGalleryThumbnails.$inject = ["$sce", "campaignGalleryService", "browser", "$timeout"];
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	exports.default = campaignGalleryThumbnails;
	
	__webpack_require__(1322);
	
	/*@ngInject*/
	function campaignGalleryThumbnails($sce, campaignGalleryService, browser, $timeout) {
	  return {
	    restrict: 'E',
	    scope: {},
	    template: __webpack_require__(1324),
	    link: function link(scope, element) {
	      scope.medias = [];
	      scope.mediasSubsetDesktopPlus = [];
	      scope.mediasSubsetDesktop = [];
	      scope.mediasSubsetTabletPlus = [];
	
	      var TABLET_PLUS_MAX = 9;
	      var DESKTOP_MAX = 12;
	      var DESKTOP_PLUS_MAX = 14;
	
	      campaignGalleryService.getGallery().then(function (gallery) {
	        gallery.forEach(function (media) {
	          return scope.medias.push(media);
	        });
	        scope.selectedMedia = scope.medias[0];
	        setMediaSubsets();
	      });
	
	      browser.onResize(function () {
	        scope.$apply();
	      });
	
	      scope.mediasSubset = function () {
	        if (browser.isDesktopPlus()) {
	          return scope.mediasSubsetDesktopPlus;
	        } else if (browser.isDesktop()) {
	          return scope.mediasSubsetDesktop;
	        } else {
	          return scope.mediasSubsetTabletPlus;
	        }
	      };
	
	      scope.showChevron = function () {
	        if (browser.isDesktopPlus()) {
	          return scope.medias.length > DESKTOP_PLUS_MAX;
	        } else if (browser.isDesktop()) {
	          return scope.medias.length > DESKTOP_MAX;
	        } else {
	          return scope.medias.length > TABLET_PLUS_MAX;
	        }
	      };
	
	      scope.thumbnailsFullWidth = function () {
	        if (browser.isDesktopPlus()) {
	          return scope.mediasSubsetDesktopPlus.length === DESKTOP_PLUS_MAX;
	        } else if (browser.isDesktop()) {
	          return scope.mediasSubsetDesktop.length === DESKTOP_MAX;
	        } else {
	          return scope.mediasSubsetTabletPlus.length === TABLET_PLUS_MAX;
	        }
	      };
	
	      scope.selectMedia = function (media) {
	        showAndFadeGalleryDescription();
	        scope.selectedMedia = media;
	      };
	
	      scope.videoHtml = function (media) {
	        return $sce.trustAsHtml(media.iframeHtml);
	      };
	
	      scope.descriptionHover = function () {
	        hideGalleryDescription();
	      };
	
	      scope.thumbnailHoverEnter = function (media) {
	        if (media === scope.selectedMedia) {
	          showGalleryDescription();
	        }
	      };
	
	      scope.thumbnailHoverLeave = function (media) {
	        if (media === scope.selectedMedia) {
	          showAndFadeGalleryDescription();
	        }
	      };
	
	      scope.isFirstThumbnail = function () {
	        return scope.selectedMedia === _.first(scope.medias);
	      };
	
	      scope.isLastThumbnail = function () {
	        return scope.selectedMedia === _.last(scope.medias);
	      };
	
	      scope.shiftRightAction = function () {
	        if (scope.isLastThumbnail()) {
	          // do nothing
	        } else if (scope.selectedMedia === _.last(scope.mediasSubset())) {
	            var nextElement = scope.medias[scope.medias.indexOf(scope.selectedMedia) + 1];
	            scope.mediasSubset().push(nextElement);
	            scope.mediasSubset().shift();
	            scope.selectedMedia = _.last(scope.mediasSubset());
	          } else {
	            scope.selectedMedia = scope.mediasSubset()[subsetCurrentIndex() + 1];
	          }
	        showAndFadeGalleryDescription();
	      };
	
	      scope.shiftLeftAction = function () {
	        if (scope.isFirstThumbnail()) {
	          // do nothing
	        } else if (scope.selectedMedia === _.first(scope.mediasSubset())) {
	            var previousElement = scope.medias[scope.medias.indexOf(scope.selectedMedia) - 1];
	            scope.mediasSubset().unshift(previousElement);
	            scope.mediasSubset().pop();
	            scope.selectedMedia = _.first(scope.mediasSubset());
	          } else {
	            scope.selectedMedia = scope.mediasSubset()[subsetCurrentIndex() - 1];
	          }
	        showAndFadeGalleryDescription();
	      };
	
	      function showGalleryDescription() {
	        galleryDescriptionElement().removeClass('campaignGalleryThumbnails-description--show');
	        galleryDescriptionElement().removeClass('campaignGalleryThumbnails-description--hidden');
	        galleryDescriptionElement().removeClass('campaignGalleryThumbnails-description--fade');
	        $timeout(function () {
	          galleryDescriptionElement().addClass('campaignGalleryThumbnails-description--show');
	        }, 100);
	      }
	
	      function showAndFadeGalleryDescription() {
	        galleryDescriptionElement().removeClass('campaignGalleryThumbnails-description--show');
	        galleryDescriptionElement().removeClass('campaignGalleryThumbnails-description--hidden');
	        galleryDescriptionElement().removeClass('campaignGalleryThumbnails-description--fade');
	        $timeout(function () {
	          galleryDescriptionElement().addClass('campaignGalleryThumbnails-description--fade');
	        }, 100);
	      }
	
	      function hideGalleryDescription() {
	        galleryDescriptionElement().removeClass('campaignGalleryThumbnails-description--show');
	        galleryDescriptionElement().removeClass('campaignGalleryThumbnails-description--fade');
	        galleryDescriptionElement().addClass('campaignGalleryThumbnails-description--hidden');
	      }
	
	      function galleryDescriptionElement() {
	        return element.find('#galleryDescription');
	      }
	
	      function subsetCurrentIndex() {
	        return scope.mediasSubset().indexOf(scope.selectedMedia);
	      }
	
	      function setMediaSubsets() {
	        if (scope.medias.length > TABLET_PLUS_MAX) {
	          scope.mediasSubsetTabletPlus = scope.medias.slice(0, TABLET_PLUS_MAX - 2);
	        } else {
	          scope.mediasSubsetTabletPlus = scope.medias.slice(0, TABLET_PLUS_MAX);
	        }
	        if (scope.medias.length > DESKTOP_MAX) {
	          scope.mediasSubsetDesktop = scope.medias.slice(0, DESKTOP_MAX - 2);
	        } else {
	          scope.mediasSubsetDesktop = scope.medias.slice(0, DESKTOP_MAX);
	        }
	        if (scope.medias.length > DESKTOP_PLUS_MAX) {
	          scope.mediasSubsetDesktopPlus = scope.medias.slice(0, DESKTOP_PLUS_MAX - 2);
	        } else {
	          scope.mediasSubsetDesktopPlus = scope.medias.slice(0, DESKTOP_PLUS_MAX);
	        }
	      }
	    }
	  };
	}

/***/ },

/***/ 1322:
/***/ function(module, exports, __webpack_require__) {

	// style-loader: Adds some css to the DOM by adding a <style> tag
	
	// load the styles
	var content = __webpack_require__(1323);
	if(typeof content === 'string') content = [[module.id, content, '']];
	// add the styles to the DOM
	var update = __webpack_require__(80)(content, {});
	if(content.locals) module.exports = content.locals;
	// Hot Module Replacement
	if(false) {
		// When the styles change, update the <style> tags
		if(!content.locals) {
			module.hot.accept("!!./../../node_modules/css-loader/index.js!./../../node_modules/less-loader/index.js!./campaign-gallery-thumbnails.less", function() {
				var newContent = require("!!./../../node_modules/css-loader/index.js!./../../node_modules/less-loader/index.js!./campaign-gallery-thumbnails.less");
				if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];
				update(newContent);
			});
		}
		// When the module is disposed, remove the <style> tags
		module.hot.dispose(function() { update(); });
	}

/***/ },

/***/ 1323:
/***/ function(module, exports, __webpack_require__) {

	exports = module.exports = __webpack_require__(79)();
	// imports
	
	
	// module
	exports.push([module.id, "/* Antenna Font Family Variations */\n/* Benton Font Family Variations */\n/** Perk Store mobile header text **/\n/** Only mobile campaign/contributions **/\n/* We can define top-left-dimple or left-top-dimple etc as necessary */\n.raised-sizing {\n  font-family: \"Benton Sans\", \"Helvetica\", \"sans-serif\";\n  font-size: 12px;\n  font-weight: normal;\n  line-height: 18px;\n}\n@media (min-width: 1002px) {\n  .raised-sizing {\n    font-family: \"Benton Sans\", \"Helvetica\", \"sans-serif\";\n    font-size: 16px;\n    font-weight: normal;\n    line-height: 26px;\n    letter-spacing: 0;\n    line-height: 25px;\n  }\n}\n.amount-sizing {\n  font-family: \"Benton Sans\", \"Helvetica\", \"sans-serif\";\n  font-weight: bold;\n  font-size: 14px;\n  line-height: 20px;\n}\n@media (min-width: 1002px) {\n  .amount-sizing {\n    font-family: \"Benton Sans\", \"Helvetica\", \"sans-serif\";\n    font-size: 20px;\n    font-weight: bold;\n    line-height: 26px;\n  }\n}\n@media (min-width: 1002px) {\n  .video-heights-for-2-columns {\n    height: 415px;\n  }\n}\n@media (min-width: 1280px) {\n  .video-heights-for-2-columns {\n    height: 460px !important;\n  }\n}\n.campaignGalleryThumbnails-displayContent {\n  text-align: center;\n  overflow: hidden;\n  position: relative;\n}\n@media not all and (min-width: 480px) {\n  .campaignGalleryThumbnails-displayContent {\n    height: 200px;\n  }\n}\n@media (min-width: 480px) {\n  .campaignGalleryThumbnails-displayContent {\n    height: 273px;\n  }\n}\n@media (min-width: 1002px) {\n  .campaignGalleryThumbnails-displayContent {\n    height: 415px;\n  }\n}\n@media (min-width: 1280px) {\n  .campaignGalleryThumbnails-displayContent {\n    height: 460px !important;\n  }\n}\n.campaignGalleryThumbnails-container {\n  position: absolute;\n  left: 0;\n  right: 0;\n  display: inline-block;\n  height: 100%;\n}\n.campaignGalleryThumbnails-media {\n  display: block;\n  position: relative;\n  height: 100%;\n}\n.campaignGalleryThumbnails-media--image {\n  display: inline-block;\n}\n.campaignGalleryThumbnails-image {\n  height: 100%;\n  max-width: 100%;\n}\n.campaignGalleryThumbnails-video {\n  height: 100%;\n}\n.campaignGalleryThumbnails-video iframe {\n  height: 100%;\n  width: 100%;\n}\n.campaignGalleryThumbnails-pitchVideo {\n  height: 100%;\n}\n.campaignGalleryThumbnails-description {\n  overflow: visible;\n  position: absolute;\n  z-index: 1000;\n  bottom: 0;\n  margin-left: auto;\n  margin-right: auto;\n  left: 0;\n  right: 0;\n  opacity: 0.7;\n}\n.campaignGalleryThumbnails-description--show {\n  visibility: visible;\n  opacity: 0.7;\n  z-index: 1000;\n  display: inline-block;\n}\n.campaignGalleryThumbnails-description--fade {\n  visibility: visible;\n  opacity: 0.7;\n  z-index: 1000;\n  display: inline-block;\n  animation: galleryDescriptionFade 1s 1;\n  -webkit-animation: galleryDescriptionFade 1s 1;\n  animation-fill-mode: forwards;\n  animation-delay: 3s;\n  -webkit-animation-delay: 3s;\n  /* Safari and Chrome */\n  -webkit-animation-fill-mode: forwards;\n}\n.campaignGalleryThumbnails-description--hidden {\n  opacity: 0;\n  visibility: hidden;\n  z-index: -1000;\n}\n@media not all and (min-width: 768px) {\n  .campaignGalleryThumbnails-description {\n    opacity: 0;\n    visibility: hidden;\n    z-index: -1000;\n  }\n}\n.campaignGalleryThumbnails-thumbnails {\n  padding-top: 5px;\n  text-align: center;\n  -webkit-user-select: none;\n  /* Chrome all / Safari all */\n  -moz-user-select: none;\n  /* Firefox all */\n  -ms-user-select: none;\n  /* IE 10+ */\n  user-select: none;\n}\n@media not all and (min-width: 768px) {\n  .campaignGalleryThumbnails-thumbnails {\n    white-space: nowrap;\n    overflow-x: scroll;\n  }\n}\n.campaignGalleryThumbnails-thumbnails::-webkit-scrollbar {\n  display: none;\n}\n.campaignGalleryThumbnails-thumbnailsDesktop {\n  display: box;\n  display: -webkit-flex;\n  display: -moz-flex;\n  display: -ms-flexbox;\n  display: -ms-flex;\n  display: flex;\n  box-align: center;\n  -ms-flex-align: center;\n  -webkit-align-items: center;\n  -moz-align-items: center;\n  -ms-align-items: center;\n  align-items: center;\n  box-pack: center;\n  -ms-flex-pack: center;\n  -webkit-justify-content: center;\n  -moz-justify-content: center;\n  -ms-justify-content: center;\n  justify-content: center;\n  padding-top: 10px;\n}\n.campaignGalleryThumbnails-thumbnailsDesktop--fullWidth {\n  display: box;\n  display: -webkit-flex;\n  display: -moz-flex;\n  display: -ms-flexbox;\n  display: -ms-flex;\n  display: flex;\n  box-align: center;\n  -ms-flex-align: center;\n  -webkit-align-items: center;\n  -moz-align-items: center;\n  -ms-align-items: center;\n  align-items: center;\n  box-pack: justify;\n  -ms-flex-pack: justify;\n  -webkit-justify-content: space-between;\n  -moz-justify-content: space-between;\n  -ms-justify-content: space-between;\n  justify-content: space-between;\n}\n.campaignGalleryThumbnails-thumbnailsDesktop--fullWidth .campaignGalleryThumbnails-thumbnail {\n  padding: 0;\n}\n@media not all and (min-width: 768px) {\n  .campaignGalleryThumbnails-thumbnailsDesktop {\n    display: none;\n  }\n}\n.campaignGalleryThumbnails-thumbnailsMobile {\n  display: none;\n}\n@media not all and (min-width: 768px) {\n  .campaignGalleryThumbnails-thumbnailsMobile {\n    display: block;\n  }\n}\n.campaignGalleryThumbnails-thumbnail {\n  display: inline-block;\n  padding-left: 3px;\n  padding-right: 2px;\n  cursor: pointer;\n  -webkit-box-sizing: border-box;\n  -moz-box-sizing: border-box;\n  box-sizing: border-box;\n}\n.campaignGalleryThumbnails-thumbnail--selected img {\n  border: 2px solid #eb1478;\n}\n.campaignGalleryThumbnails-chevron {\n  display: box;\n  display: -webkit-flex;\n  display: -moz-flex;\n  display: -ms-flexbox;\n  display: -ms-flex;\n  display: flex;\n  box-align: center;\n  -ms-flex-align: center;\n  -webkit-align-items: center;\n  -moz-align-items: center;\n  -ms-align-items: center;\n  align-items: center;\n  box-pack: center;\n  -ms-flex-pack: center;\n  -webkit-justify-content: center;\n  -moz-justify-content: center;\n  -ms-justify-content: center;\n  justify-content: center;\n  cursor: pointer;\n}\n.campaignGalleryThumbnails-chevron svg {\n  fill: #a8a8a8;\n  height: 30px;\n  width: 30px;\n}\n.campaignGalleryThumbnails-chevron--disabled {\n  cursor: default;\n}\n.campaignGalleryThumbnails-chevron--disabled svg {\n  fill: #dddddd;\n}\n.campaignGalleryThumbnails-chevron:not(.campaignGalleryThumbnails-chevron--disabled):hover svg {\n  fill: #6a6a6a;\n}\n@keyframes galleryDescriptionFade {\n  from {\n    opacity: 0.7;\n  }\n  to {\n    opacity: 0;\n  }\n}\n@-webkit-keyframes galleryDescriptionFade {\n  from {\n    opacity: 0.7;\n  }\n  to {\n    opacity: 0;\n  }\n}\n", ""]);
	
	// exports


/***/ },

/***/ 1324:
/***/ function(module, exports) {

	module.exports = "<div class=\"campaignGalleryThumbnails\">\n  <div class=\"campaignGalleryThumbnails-displayContent\"\n       gogo-test=\"display-content\">\n    <div class=\"campaignGalleryThumbnails-container\">\n      <div class=\"campaignGalleryThumbnails-media\"\n           ng-class=\"{'campaignGalleryThumbnails-media--image': selectedMedia.isImage() || selectedMedia.isPitchImage()}\">\n        <img ng-if=\"selectedMedia.isImage() || selectedMedia.isPitchImage()\"\n             class=\"campaignGalleryThumbnails-image\"\n             ng-src=\"{{selectedMedia.url}}\"/>\n        <div ng-if=\"selectedMedia.isVideo()\"\n             class=\"campaignGalleryThumbnails-video\"\n             ng-bind-html=\"videoHtml(selectedMedia)\"></div>\n        <campaign-video ng-if=\"selectedMedia.isPitchVideo()\"\n                        class=\"campaignGalleryThumbnails-pitchVideo campaignVideo\"\n                        overlay_url=\"{{selectedMedia.overlayUrl}}\"\n                        type=\"{{selectedMedia.type}}\"\n                        id=\"{{selectedMedia.typeId}}\"></campaign-video>\n        <gallery-description id=\"galleryDescription\"\n                             gogo-test=\"gallery_description\"\n                             ng-mouseover=\"descriptionHover()\"\n                             media=\"selectedMedia\"\n                             class=\"campaignGalleryThumbnails-description campaignGalleryThumbnails-description--fade\"></gallery-description>\n      </div>\n    </div>\n  </div>\n  <div class=\"campaignGalleryThumbnails-thumbnails campaignGalleryThumbnails-thumbnailsMobile\" gogo-test=\"thumbnails-mobile\">\n    <gallery-thumbnail media=\"media\"\n                       class=\"campaignGalleryThumbnails-thumbnail\"\n                       ng-class=\"{'campaignGalleryThumbnails-thumbnail--selected': selectedMedia === media}\"\n                       ng-repeat=\"media in medias\"\n                       ng-click=\"selectMedia(media)\"></gallery-thumbnail>\n  </div>\n  <div class=\"campaignGalleryThumbnails-thumbnails campaignGalleryThumbnails-thumbnailsDesktop\"\n       ng-class=\"{'campaignGalleryThumbnails-thumbnailsDesktop--fullWidth': thumbnailsFullWidth()}\"\n       gogo-test=\"thumbnails-desktop\">\n    <span class=\"campaignGalleryThumbnails-chevron\"\n          gogo-test=\"chevron-left\"\n          ng-show=\"showChevron()\"\n          ng-click=\"shiftLeftAction()\"\n          ng-class=\"{'campaignGalleryThumbnails-chevron--disabled': isFirstThumbnail()}\">\n      <svg><use xlink:href=\"#left-chevron\"></use></svg>\n    </span>\n    <gallery-thumbnail media=\"media\"\n                       class=\"campaignGalleryThumbnails-thumbnail\"\n                       ng-class=\"{'campaignGalleryThumbnails-thumbnail--selected': selectedMedia === media}\"\n                       ng-repeat=\"media in mediasSubset()\"\n                       ng-mouseover=\"thumbnailHoverEnter(media)\"\n                       ng-mouseleave=\"thumbnailHoverLeave(media)\"\n                       ng-click=\"selectMedia(media)\"></gallery-thumbnail>\n    <span class=\"campaignGalleryThumbnails-chevron\"\n          gogo-test=\"chevron-right\"\n          ng-show=\"showChevron()\"\n          ng-click=\"shiftRightAction()\"\n          ng-class=\"{'campaignGalleryThumbnails-chevron--disabled': isLastThumbnail()}\">\n      <svg><use xlink:href=\"#right-chevron\"></use></svg>\n    </span>\n  </div>\n</div>\n";

/***/ },

/***/ 1325:
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	
	campaignGalleryService.$inject = ["$http", "gon", "campaign", "GalleryMedia"];
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	exports.default = campaignGalleryService;
	
	var _privateApi = __webpack_require__(186);
	
	/*@ngInject*/
	function campaignGalleryService($http, gon, campaign, GalleryMedia) {
	  function buildMediaObjects(data) {
	    var videos = data.videos.map(function (video) {
	      return GalleryMedia.buildVideo(video);
	    });
	    var images = data.images.map(function (image) {
	      return GalleryMedia.buildImage(image);
	    });
	    var pitchMedia = void 0;
	    if (data.pitch_video) {
	      pitchMedia = GalleryMedia.buildPitchVideo(data.pitch_video, data.video_overlay);
	    } else if (data.pitch_image) {
	      pitchMedia = GalleryMedia.buildPitchImage(data.pitch_image);
	    }
	    return pitchMedia ? [pitchMedia].concat(videos).concat(images) : videos.concat(images);
	  }
	
	  function getGallery() {
	    return $http.get((0, _privateApi.privateApiCampaignGalleryPath)({ campaignId: campaign.id })).then(function (result) {
	      return buildMediaObjects(result.data);
	    });
	  }
	
	  return {
	    getGallery: getGallery
	  };
	} /* jshint expr: true */

/***/ },

/***/ 1326:
/***/ function(module, exports) {

	"use strict";
	
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	
	var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
	
	exports.default = GalleryMediaFactory;
	
	function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
	
	function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
	
	function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
	
	/*@ngInject*/
	function GalleryMediaFactory() {
	  var GalleryMedia = function () {
	    function GalleryMedia(_ref) {
	      var thumbnailUrl = _ref.thumbnailUrl;
	      var description = _ref.description;
	
	      _classCallCheck(this, GalleryMedia);
	
	      this.thumbnailUrl = thumbnailUrl;
	      this.description = description;
	    }
	
	    _createClass(GalleryMedia, [{
	      key: "isVideo",
	      value: function isVideo() {
	        return GalleryVideo.prototype.isPrototypeOf(this);
	      }
	    }, {
	      key: "isImage",
	      value: function isImage() {
	        return GalleryImage.prototype.isPrototypeOf(this);
	      }
	    }, {
	      key: "isPitchVideo",
	      value: function isPitchVideo() {
	        return GalleryPitchVideo.prototype.isPrototypeOf(this);
	      }
	    }, {
	      key: "isPitchImage",
	      value: function isPitchImage() {
	        return GalleryPitchImage.prototype.isPrototypeOf(this);
	      }
	    }], [{
	      key: "buildVideo",
	      value: function buildVideo(video) {
	        return new GalleryVideo({
	          thumbnailUrl: video.thumbnail_url,
	          description: video.description,
	          iframeHtml: video.html
	        });
	      }
	    }, {
	      key: "buildImage",
	      value: function buildImage(image) {
	        return new GalleryImage({
	          thumbnailUrl: image.thumbnail_url,
	          description: image.description,
	          url: image.full_url,
	          title: image.title
	        });
	      }
	    }, {
	      key: "buildPitchVideo",
	      value: function buildPitchVideo(pitchVideo, videoOverlay) {
	        if (videoOverlay) {
	          return new GalleryPitchVideo({
	            thumbnailUrl: videoOverlay.thumbnail_url,
	            type: pitchVideo.video_type,
	            typeId: pitchVideo.video_id,
	            overlayUrl: videoOverlay.full_url
	          });
	        } else {
	          return new GalleryPitchVideo({
	            thumbnailUrl: pitchVideo.thumbnail_url,
	            type: pitchVideo.video_type,
	            typeId: pitchVideo.video_id
	          });
	        }
	      }
	    }, {
	      key: "buildPitchImage",
	      value: function buildPitchImage(pitchImage) {
	        return new GalleryPitchImage({
	          thumbnailUrl: pitchImage.thumbnail_url,
	          url: pitchImage.full_url
	        });
	      }
	    }]);
	
	    return GalleryMedia;
	  }();
	
	  var GalleryVideo = function (_GalleryMedia) {
	    _inherits(GalleryVideo, _GalleryMedia);
	
	    // jshint ignore:line
	
	    function GalleryVideo(_ref2) {
	      var thumbnailUrl = _ref2.thumbnailUrl;
	      var description = _ref2.description;
	      var iframeHtml = _ref2.iframeHtml;
	
	      _classCallCheck(this, GalleryVideo);
	
	      var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(GalleryVideo).call(this, { thumbnailUrl: thumbnailUrl, description: description }));
	
	      _this.iframeHtml = iframeHtml;
	      return _this;
	    }
	
	    return GalleryVideo;
	  }(GalleryMedia);
	
	  var GalleryImage = function (_GalleryMedia2) {
	    _inherits(GalleryImage, _GalleryMedia2);
	
	    // jshint ignore:line
	
	    function GalleryImage(_ref3) {
	      var thumbnailUrl = _ref3.thumbnailUrl;
	      var description = _ref3.description;
	      var url = _ref3.url;
	      var title = _ref3.title;
	
	      _classCallCheck(this, GalleryImage);
	
	      var _this2 = _possibleConstructorReturn(this, Object.getPrototypeOf(GalleryImage).call(this, { thumbnailUrl: thumbnailUrl, description: description }));
	
	      _this2.url = url;
	      _this2.title = title;
	      return _this2;
	    }
	
	    return GalleryImage;
	  }(GalleryMedia);
	
	  var GalleryPitchVideo = function (_GalleryMedia3) {
	    _inherits(GalleryPitchVideo, _GalleryMedia3);
	
	    // jshint ignore:line
	
	    function GalleryPitchVideo(_ref4) {
	      var thumbnailUrl = _ref4.thumbnailUrl;
	      var description = _ref4.description;
	      var type = _ref4.type;
	      var typeId = _ref4.typeId;
	      var overlayUrl = _ref4.overlayUrl;
	
	      _classCallCheck(this, GalleryPitchVideo);
	
	      var _this3 = _possibleConstructorReturn(this, Object.getPrototypeOf(GalleryPitchVideo).call(this, { thumbnailUrl: thumbnailUrl, description: description }));
	
	      _this3.type = type;
	      _this3.typeId = typeId;
	      _this3.overlayUrl = overlayUrl;
	      return _this3;
	    }
	
	    return GalleryPitchVideo;
	  }(GalleryMedia);
	
	  var GalleryPitchImage = function (_GalleryMedia4) {
	    _inherits(GalleryPitchImage, _GalleryMedia4);
	
	    // jshint ignore:line
	
	    function GalleryPitchImage(_ref5) {
	      var thumbnailUrl = _ref5.thumbnailUrl;
	      var description = _ref5.description;
	      var url = _ref5.url;
	
	      _classCallCheck(this, GalleryPitchImage);
	
	      var _this4 = _possibleConstructorReturn(this, Object.getPrototypeOf(GalleryPitchImage).call(this, { thumbnailUrl: thumbnailUrl, description: description }));
	
	      _this4.url = url;
	      return _this4;
	    }
	
	    return GalleryPitchImage;
	  }(GalleryMedia);
	
	  GalleryMedia.GalleryVideo = GalleryVideo;
	  GalleryMedia.GalleryImage = GalleryImage;
	  GalleryMedia.GalleryPitchVideo = GalleryPitchVideo;
	  GalleryMedia.GalleryPitchImage = GalleryPitchImage;
	
	  return GalleryMedia;
	}

/***/ },

/***/ 1327:
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	exports.default = galleryThumbnail;
	
	__webpack_require__(1328);
	
	/*@ngInject*/
	function galleryThumbnail() {
	  return {
	    restrict: 'E',
	    scope: {
	      media: '='
	    },
	    template: __webpack_require__(1330)
	  };
	}

/***/ },

/***/ 1328:
/***/ function(module, exports, __webpack_require__) {

	// style-loader: Adds some css to the DOM by adding a <style> tag
	
	// load the styles
	var content = __webpack_require__(1329);
	if(typeof content === 'string') content = [[module.id, content, '']];
	// add the styles to the DOM
	var update = __webpack_require__(80)(content, {});
	if(content.locals) module.exports = content.locals;
	// Hot Module Replacement
	if(false) {
		// When the styles change, update the <style> tags
		if(!content.locals) {
			module.hot.accept("!!./../../node_modules/css-loader/index.js!./../../node_modules/less-loader/index.js!./gallery-thumbnail.less", function() {
				var newContent = require("!!./../../node_modules/css-loader/index.js!./../../node_modules/less-loader/index.js!./gallery-thumbnail.less");
				if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];
				update(newContent);
			});
		}
		// When the module is disposed, remove the <style> tags
		module.hot.dispose(function() { update(); });
	}

/***/ },

/***/ 1329:
/***/ function(module, exports, __webpack_require__) {

	exports = module.exports = __webpack_require__(79)();
	// imports
	
	
	// module
	exports.push([module.id, "/* Antenna Font Family Variations */\n/* Benton Font Family Variations */\n/** Perk Store mobile header text **/\n/** Only mobile campaign/contributions **/\n/* We can define top-left-dimple or left-top-dimple etc as necessary */\n.galleryThumbnail img {\n  height: 40px;\n  width: 40px;\n}\n", ""]);
	
	// exports


/***/ },

/***/ 1330:
/***/ function(module, exports) {

	module.exports = "<div class=\"galleryThumbnail\">\n  <img ng-src=\"{{::media.thumbnailUrl}}\"/>\n</div>\n";

/***/ },

/***/ 1331:
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	exports.default = galleryDescription;
	
	__webpack_require__(1332);
	
	/*@ngInject*/
	function galleryDescription() {
	  return {
	    restrict: 'E',
	    scope: {
	      media: '='
	    },
	    template: __webpack_require__(1334)
	  };
	}

/***/ },

/***/ 1332:
/***/ function(module, exports, __webpack_require__) {

	// style-loader: Adds some css to the DOM by adding a <style> tag
	
	// load the styles
	var content = __webpack_require__(1333);
	if(typeof content === 'string') content = [[module.id, content, '']];
	// add the styles to the DOM
	var update = __webpack_require__(80)(content, {});
	if(content.locals) module.exports = content.locals;
	// Hot Module Replacement
	if(false) {
		// When the styles change, update the <style> tags
		if(!content.locals) {
			module.hot.accept("!!./../../node_modules/css-loader/index.js!./../../node_modules/less-loader/index.js!./gallery-description.less", function() {
				var newContent = require("!!./../../node_modules/css-loader/index.js!./../../node_modules/less-loader/index.js!./gallery-description.less");
				if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];
				update(newContent);
			});
		}
		// When the module is disposed, remove the <style> tags
		module.hot.dispose(function() { update(); });
	}

/***/ },

/***/ 1333:
/***/ function(module, exports, __webpack_require__) {

	exports = module.exports = __webpack_require__(79)();
	// imports
	
	
	// module
	exports.push([module.id, "/* Antenna Font Family Variations */\n/* Benton Font Family Variations */\n/** Perk Store mobile header text **/\n/** Only mobile campaign/contributions **/\n/* We can define top-left-dimple or left-top-dimple etc as necessary */\n.galleryDescription {\n  font-family: \"Benton Sans\", \"Helvetica\", \"sans-serif\";\n  font-size: 12px;\n  font-weight: normal;\n  line-height: 18px;\n  background-color: #2a2a2a;\n  color: #ffffff;\n  text-align: left;\n}\n.galleryDescription-text {\n  padding: 10px;\n}\n", ""]);
	
	// exports


/***/ },

/***/ 1334:
/***/ function(module, exports) {

	module.exports = "<div ng-if=\"media.description\" class=\"galleryDescription\">\n  <div class=\"galleryDescription-text\" ng-bind=\"media.description\"></div>\n</div>\n";

/***/ },

/***/ 1335:
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	
	campaignHeaderPitch.$inject = ["campaign"];
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	exports.default = campaignHeaderPitch;
	/*@ngInject*/
	function campaignHeaderPitch(campaign) {
	  return {
	    restrict: 'E',
	    scope: {},
	    template: __webpack_require__(1336),
	    link: function link(scope) {
	      scope.campaign = campaign;
	    }
	  };
	}

/***/ },

/***/ 1336:
/***/ function(module, exports) {

	module.exports = "<div class=\"campaignHeaderPitch\">\n  <div ng-if=\"!campaign.gallery_available\">\n    <campaign-pitchmedia></campaign-pitchmedia>\n  </div>\n  <div ng-if=\"campaign.gallery_available\">\n    <split experiment=\"campaign_page_thumbnails\" variant=\"control\">\n      <campaign-pitchmedia></campaign-pitchmedia>\n    </split>\n    <split experiment=\"campaign_page_thumbnails\" variant=\"experiment\">\n      <campaign-gallery-thumbnails></campaign-gallery-thumbnails>\n    </split>\n  </div>\n</div>\n";

/***/ },

/***/ 1337:
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	
	campaignHeaderBasics.$inject = ["campaign", "i18n"];
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	
	__webpack_require__(1338);
	
	/*@ngInject*/
	function campaignHeaderBasics(campaign, i18n) {
	  return {
	    restrict: 'E',
	    scope: {},
	    template: __webpack_require__(1340),
	    link: function link(scope) {
	      scope.i18n = i18n;
	      scope.campaign = campaign;
	      scope.campaignIsInDemand = campaign.isInDemand();
	      scope.categoryIconRef = '';
	      scope.$watch('campaign.category_icon_name', function () {
	        scope.categoryIconRef = '#icon-icon-' + campaign.category_icon_name;
	      });
	    }
	  };
	}
	exports.default = campaignHeaderBasics;

/***/ },

/***/ 1338:
/***/ function(module, exports, __webpack_require__) {

	// style-loader: Adds some css to the DOM by adding a <style> tag
	
	// load the styles
	var content = __webpack_require__(1339);
	if(typeof content === 'string') content = [[module.id, content, '']];
	// add the styles to the DOM
	var update = __webpack_require__(80)(content, {});
	if(content.locals) module.exports = content.locals;
	// Hot Module Replacement
	if(false) {
		// When the styles change, update the <style> tags
		if(!content.locals) {
			module.hot.accept("!!./../node_modules/css-loader/index.js!./../node_modules/less-loader/index.js!./campaign-header-basics.less", function() {
				var newContent = require("!!./../node_modules/css-loader/index.js!./../node_modules/less-loader/index.js!./campaign-header-basics.less");
				if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];
				update(newContent);
			});
		}
		// When the module is disposed, remove the <style> tags
		module.hot.dispose(function() { update(); });
	}

/***/ },

/***/ 1339:
/***/ function(module, exports, __webpack_require__) {

	exports = module.exports = __webpack_require__(79)();
	// imports
	
	
	// module
	exports.push([module.id, "/* Antenna Font Family Variations */\n/* Benton Font Family Variations */\n/** Perk Store mobile header text **/\n/** Only mobile campaign/contributions **/\n/* We can define top-left-dimple or left-top-dimple etc as necessary */\n.raised-sizing {\n  font-family: \"Benton Sans\", \"Helvetica\", \"sans-serif\";\n  font-size: 12px;\n  font-weight: normal;\n  line-height: 18px;\n}\n@media (min-width: 1002px) {\n  .raised-sizing {\n    font-family: \"Benton Sans\", \"Helvetica\", \"sans-serif\";\n    font-size: 16px;\n    font-weight: normal;\n    line-height: 26px;\n    letter-spacing: 0;\n    line-height: 25px;\n  }\n}\n.amount-sizing {\n  font-family: \"Benton Sans\", \"Helvetica\", \"sans-serif\";\n  font-weight: bold;\n  font-size: 14px;\n  line-height: 20px;\n}\n@media (min-width: 1002px) {\n  .amount-sizing {\n    font-family: \"Benton Sans\", \"Helvetica\", \"sans-serif\";\n    font-size: 20px;\n    font-weight: bold;\n    line-height: 26px;\n  }\n}\n@media (min-width: 1002px) {\n  .video-heights-for-2-columns {\n    height: 415px;\n  }\n}\n@media (min-width: 1280px) {\n  .video-heights-for-2-columns {\n    height: 460px !important;\n  }\n}\n.campaignHeaderBasics {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: antialiased;\n  font-smoothing: antialiased;\n  display: box;\n  display: -webkit-flex;\n  display: -moz-flex;\n  display: -ms-flexbox;\n  display: -ms-flex;\n  display: flex;\n  box-pack: justify;\n  -ms-flex-pack: justify;\n  -webkit-justify-content: space-between;\n  -moz-justify-content: space-between;\n  -ms-justify-content: space-between;\n  justify-content: space-between;\n  box-orient: vertical;\n  -webkit-flex-direction: column;\n  -moz-flex-direction: column;\n  -ms-flex-direction: column;\n  flex-direction: column;\n}\n@media (min-width: 1002px) {\n  .campaignHeaderBasics {\n    height: 415px;\n  }\n}\n@media (min-width: 1280px) {\n  .campaignHeaderBasics {\n    height: 460px !important;\n  }\n}\n@media not all and (min-width: 768px) {\n  .campaignHeaderBasics {\n    margin-left: 20px;\n    margin-right: 20px;\n  }\n}\n.campaignHeaderBasics-title {\n  line-height: 22px;\n  font-family: \"Benton Sans Medium\", \"Helvetica\", \"sans-serif\";\n  font-size: 18px;\n  line-height: 28px;\n  font-weight: normal;\n  letter-spacing: 0;\n  line-height: 20px;\n}\n@media (min-width: 1002px) {\n  .campaignHeaderBasics-title {\n    font-family: \"Benton Sans Medium\", \"Helvetica\", \"sans-serif\";\n    font-size: 24px;\n    line-height: 35px;\n    letter-spacing: 0;\n    font-weight: normal;\n    line-height: 28px;\n  }\n}\n@media (min-width: 1280px) {\n  .campaignHeaderBasics-title {\n    font-family: \"Benton Sans Medium\", \"Helvetica\", \"sans-serif\";\n    font-size: 28px;\n    line-height: 35px;\n    letter-spacing: 0;\n    font-weight: normal;\n  }\n}\n.campaignHeaderBasics-assurance {\n  display: box;\n  display: -webkit-flex;\n  display: -moz-flex;\n  display: -ms-flexbox;\n  display: -ms-flex;\n  display: flex;\n  box-align: center;\n  -ms-flex-align: center;\n  -webkit-align-items: center;\n  -moz-align-items: center;\n  -ms-align-items: center;\n  align-items: center;\n  box-pack: justify;\n  -ms-flex-pack: justify;\n  -webkit-justify-content: space-between;\n  -moz-justify-content: space-between;\n  -ms-justify-content: space-between;\n  justify-content: space-between;\n  margin-top: 10px;\n}\n@media (min-width: 768px) {\n  .campaignHeaderBasics-assurance {\n    margin-top: 15px;\n  }\n}\n@media (min-width: 1280px) {\n  .campaignHeaderBasics-assurance {\n    margin-top: 20px;\n  }\n}\n.campaignHeaderBasics-trust {\n  box-flex: 1;\n  -webkit-flex: 1;\n  -moz-flex: 1;\n  -ms-flex: 1;\n  flex: 1;\n}\n.campaignHeaderBasics-bylineComponents {\n  display: box;\n  display: -webkit-flex;\n  display: -moz-flex;\n  display: -ms-flexbox;\n  display: -ms-flex;\n  display: flex;\n  box-pack: justify;\n  -ms-flex-pack: justify;\n  -webkit-justify-content: space-between;\n  -moz-justify-content: space-between;\n  -ms-justify-content: space-between;\n  justify-content: space-between;\n  -ms-flex-wrap: wrap;\n  -webkit-flex-wrap: wrap;\n  -moz-flex-wrap: wrap;\n  flex-wrap: wrap;\n  margin-top: 10px;\n}\n@media not all and (min-width: 768px) {\n  .campaignHeaderBasics-bylineComponents {\n    margin-top: 15px;\n  }\n}\n.campaignHeaderBasics-bylineComponents a {\n  margin-left: 5px;\n  color: #6a6a6a;\n}\n.campaignHeaderBasics-bylineComponent {\n  display: box;\n  display: -webkit-flex;\n  display: -moz-flex;\n  display: -ms-flexbox;\n  display: -ms-flex;\n  display: flex;\n  box-align: center;\n  -ms-flex-align: center;\n  -webkit-align-items: center;\n  -moz-align-items: center;\n  -ms-align-items: center;\n  align-items: center;\n  font-family: \"Benton Sans Medium\", \"Helvetica\", \"sans-serif\";\n  font-size: 14px;\n  line-height: 20px;\n  padding-right: 5px;\n}\n@media not all and (min-width: 768px) {\n  .campaignHeaderBasics-bylineComponent {\n    width: 50%;\n  }\n}\n.campaignHeaderBasics-bylineComponent svg {\n  height: 18px;\n  width: 18px;\n  fill: #6a6a6a;\n}\n.campaignHeaderBasics-tagline {\n  font-family: \"Benton Sans\", \"Helvetica\", \"sans-serif\";\n  font-size: 12px;\n  font-weight: normal;\n  line-height: 18px;\n  color: #6a6a6a;\n  margin-top: 5px;\n}\n@media (min-width: 1002px) {\n  .campaignHeaderBasics-tagline {\n    font-family: \"Benton Sans\", \"Helvetica\", \"sans-serif\";\n    font-size: 16px;\n    font-weight: normal;\n    line-height: 26px;\n    letter-spacing: 0;\n    line-height: 22px;\n    margin-top: 10px;\n  }\n}\n@media (min-width: 1280px) {\n  .campaignHeaderBasics-tagline {\n    font-family: \"Benton Sans\", \"Helvetica\", \"sans-serif\";\n    font-size: 20px;\n    line-height: 26px;\n    letter-spacing: 0;\n    font-weight: normal;\n  }\n}\n.campaignHeaderBasics-goalProgress {\n  margin-top: 20px;\n}\n@media (min-width: 768px) {\n  .campaignHeaderBasics-goalProgress {\n    margin-top: 30px;\n  }\n}\n@media (min-width: 1280px) {\n  .campaignHeaderBasics-goalProgress {\n    margin-top: 40px;\n  }\n}\n.campaignHeaderBasics campaign-actions {\n  width: 100%;\n}\n.campaignHeaderBasics-actions {\n  display: box;\n  display: -webkit-flex;\n  display: -moz-flex;\n  display: -ms-flexbox;\n  display: -ms-flex;\n  display: flex;\n  box-align: center;\n  -ms-flex-align: center;\n  -webkit-align-items: center;\n  -moz-align-items: center;\n  -ms-align-items: center;\n  align-items: center;\n  margin-top: 15px;\n}\n@media (min-width: 768px) {\n  .campaignHeaderBasics-actions {\n    margin-top: 5px;\n  }\n}\n.campaignHeaderBasics-contribute {\n  box-flex: 60;\n  -webkit-flex: 60;\n  -moz-flex: 60;\n  -ms-flex: 60;\n  flex: 60;\n  margin-right: 20px;\n}\n@media (min-width: 480px) {\n  .campaignHeaderBasics-contribute {\n    margin-right: 10px;\n  }\n}\n@media (min-width: 768px) {\n  .campaignHeaderBasics-contribute {\n    box-flex: 40;\n    -webkit-flex: 40;\n    -moz-flex: 40;\n    -ms-flex: 40;\n    flex: 40;\n    margin-right: 20px;\n  }\n}\n.campaignHeaderBasics-shareTools {\n  box-flex: 40;\n  -webkit-flex: 40;\n  -moz-flex: 40;\n  -ms-flex: 40;\n  flex: 40;\n}\n@media (min-width: 768px) {\n  .campaignHeaderBasics-shareTools {\n    box-flex: 60;\n    -webkit-flex: 60;\n    -moz-flex: 60;\n    -ms-flex: 60;\n    flex: 60;\n  }\n}\n", ""]);
	
	// exports


/***/ },

/***/ 1340:
/***/ function(module, exports) {

	module.exports = "<div class=\"campaignHeaderBasics\">\n  <div>\n  <campaign-state-label></campaign-state-label>\n  <div class=\"campaignHeaderBasics-title\" gogo-test=\"title\"\n       analytics-on=\"scrollby\"\n       analytics-name=\"campaign/title.scroll\"\n       analytics-category=\"campaign_page_scroll\"\n       analytics-event=\"title\"\n       scrollby-offset=\"3%\"\n       scrollby-continuous>\n    {{campaign.title}}\n  </div>\n\n  <div class=\"campaignHeaderBasics-tagline\" gogo-test=\"tagline\">\n    {{campaign.tagline}}\n  </div>\n\n  <div class=\"campaignHeaderBasics-assurance\" >\n    <campaign-header-trust></campaign-header-trust>\n    <div class=\"campaignHeaderBasics-verifiedNonProfit\" ng-if=\"campaign.nonprofit\" gogo-test=\"verified_nonprofit\">\n        <div class=\"i-annotation-pill i-pill-pending\">{{::i18n.t('verified_nonprofit')}}</div>\n    </div>\n  </div>\n  </div>\n\n  <div class=\"campaignHeaderBasics-goalProgress\">\n    <div ng-if=\"campaignIsInDemand\">\n      <indemand-progress></indemand-progress>\n    </div>\n    <div ng-if=\"!campaignIsInDemand\">\n      <campaign-goal-progress></campaign-goal-progress>\n    </div>\n  </div>\n\n  <div class=\"campaignHeaderBasics-actions\">\n    <campaign-actions></campaign-actions>\n  </div>\n</div>\n\n";

/***/ },

/***/ 1341:
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	exports.default = campaignStateLabel;
	
	__webpack_require__(1342);
	
	function campaignStateLabel(campaign, i18n) {
	  return {
	    scope: {},
	    restrict: 'E',
	    template: __webpack_require__(1344),
	    link: function link(scope) {
	      scope.i18n = i18n;
	      scope.campaignIsPublishedAndInDemand = campaign.isPublished() && campaign.isInDemand();
	      scope.campaignIsEnded = campaign.isEnded();
	
	      if (scope.campaignIsPublishedAndInDemand) {
	        scope.campaignStateLabel = 'indemand';
	      } else if (scope.campaignIsEnded) {
	        scope.campaignStateLabel = 'closed';
	      }
	    }
	  };
	}

/***/ },

/***/ 1342:
/***/ function(module, exports, __webpack_require__) {

	// style-loader: Adds some css to the DOM by adding a <style> tag
	
	// load the styles
	var content = __webpack_require__(1343);
	if(typeof content === 'string') content = [[module.id, content, '']];
	// add the styles to the DOM
	var update = __webpack_require__(80)(content, {});
	if(content.locals) module.exports = content.locals;
	// Hot Module Replacement
	if(false) {
		// When the styles change, update the <style> tags
		if(!content.locals) {
			module.hot.accept("!!./../node_modules/css-loader/index.js!./../node_modules/less-loader/index.js!./campaign-state-label.less", function() {
				var newContent = require("!!./../node_modules/css-loader/index.js!./../node_modules/less-loader/index.js!./campaign-state-label.less");
				if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];
				update(newContent);
			});
		}
		// When the module is disposed, remove the <style> tags
		module.hot.dispose(function() { update(); });
	}

/***/ },

/***/ 1343:
/***/ function(module, exports, __webpack_require__) {

	exports = module.exports = __webpack_require__(79)();
	// imports
	
	
	// module
	exports.push([module.id, "/* Antenna Font Family Variations */\n/* Benton Font Family Variations */\n/** Perk Store mobile header text **/\n/** Only mobile campaign/contributions **/\n/* We can define top-left-dimple or left-top-dimple etc as necessary */\ncampaign-state-label .campaignState {\n  font-family: \"Benton Sans Medium\", \"Helvetica\", \"sans-serif\";\n  font-size: 12px;\n  line-height: 18px;\n  font-weight: normal;\n  letter-spacing: 0;\n  margin: 0 0 10px 0;\n  border-bottom-width: 1px;\n  border-bottom-style: solid;\n}\n@media (min-width: 1002px) {\n  campaign-state-label .campaignState {\n    font-family: \"Benton Sans Medium\", \"Helvetica\", \"sans-serif\";\n    font-size: 16px;\n    line-height: 26px;\n    font-weight: normal;\n    letter-spacing: 0;\n    line-height: 25px;\n    border-bottom-width: 2px;\n  }\n}\n@media (min-width: 1280px) {\n  campaign-state-label .campaignState {\n    line-height: 22px;\n    font-family: \"Benton Sans Medium\", \"Helvetica\", \"sans-serif\";\n    font-size: 18px;\n    line-height: 28px;\n    font-weight: normal;\n    letter-spacing: 0;\n    line-height: 25px;\n  }\n}\ncampaign-state-label .campaignState--indemand {\n  color: #0eb4b6;\n  border-bottom-color: #0eb4b6;\n}\ncampaign-state-label .campaignState--closed {\n  color: #6a6a6a;\n  border-bottom-color: #a8a8a8;\n  text-transform: uppercase;\n}\n", ""]);
	
	// exports


/***/ },

/***/ 1344:
/***/ function(module, exports) {

	module.exports = "<div ng-if=\"campaignStateLabel\" class=\"campaignState\" ng-class=\"{ 'campaignState--indemand': campaignIsPublishedAndInDemand, 'campaignState--ended': campaignIsEnded }\" gogo-test=\"campaign_state_label\">\n  {{::i18n.t(campaignStateLabel)}}\n</div>\n";

/***/ },

/***/ 1345:
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	
	campaignShareButtons.$inject = ["$http", "gon", "i18n", "fb", "twitter", "ga", "gogoEvents", "$timeout", "browser", "$modal", "$sce", "$compile", "campaignAnalyticsService", "campaign", "split"];
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	exports.default = campaignShareButtons;
	
	__webpack_require__(1346);
	
	var _privateApi = __webpack_require__(186);
	
	/*@ngInject*/
	function campaignShareButtons($http, gon, i18n, fb, twitter, ga, gogoEvents, $timeout, browser, $modal, $sce, $compile, campaignAnalyticsService, campaign, split) {
	  return {
	    scope: {
	      pageLocation: '@'
	    },
	    restrict: 'E',
	    template: __webpack_require__(1348),
	    link: function link(scope, element) {
	      function gonGet(path) {
	        return _.get(gon, path, '/');
	      }
	
	      var currentShareExperiment = null;
	      split.projectVariant('facebook_share_experiment', gonGet('campaign.id')).then(function (response) {
	        var experiment = response.data.response.bucket;
	        if (experiment.indexOf('fse_') === 0) {
	          currentShareExperiment = experiment;
	        }
	      });
	
	      var changeFollowingStatus = function changeFollowingStatus(finalStatus, path) {
	        var originalStatus = scope.isStartingToFollowProject;
	        scope.isStartingToFollowProject = finalStatus;
	        $http.post(path).then(function () {
	          scope.isFollowingProject = finalStatus;
	        }, function () {
	          scope.isStartingToFollowProject = originalStatus;
	        });
	      };
	
	      scope.i18n = i18n;
	      scope.loggedIn = gonGet('share.account_id');
	      scope.isFollowingProject = gonGet('share.following');
	      scope.isStartingToFollowProject = scope.isFollowingProject;
	      scope.shareLinkUrl = gonGet('share.sharing_url');
	      scope.ga_impression_data = gon.ga_impression_data;
	      scope.toggleFollowing = function () {
	        if (scope.isFollowingProject) {
	          changeFollowingStatus(false, gon.urls.campaign_unfollow_path);
	        } else {
	          changeFollowingStatus(true, gon.urls.campaign_follow_path);
	        }
	      };
	
	      scope.campaign_category = campaignAnalyticsService.defaultAnalyticsAttrs().projectCategory;
	      scope.campaign_type = campaignAnalyticsService.campaignType();
	
	      fb.setUrls({ shareCount: (0, _privateApi.privateApiFacebookCountPath)({ id: campaign.id }) });
	
	      scope.fbShareCount = function () {
	        return fb.shareCount ? fb.shareCount : i18n.t('share');
	      };
	
	      scope.shareFacebook = function () {
	        // TODO EVENTS: id=neic3 subsystem=share fixtype=none category=campaign_page_share category-new=TBD action=click_fb_share label=dynamic name=click_fb_share . review
	        campaignAnalyticsService.sendShareEvent({ gaEventCategory: 'campaign_page_share',
	          gaEventAction: 'click_fb_share' }, { thetaName: 'click_fb_share' });
	
	        var options = gon.current_account ? { account_id: gon.current_account.account_id } : {};
	        options.utm_query_string = gon.fb_utm_query_string;
	
	        var shareUrl = gonGet('share.canonical_url');
	        if (currentShareExperiment) {
	          var shareExperimentBucket = ['c', 'e'][Math.floor(Math.random() * 2)];
	          shareUrl += "?" + currentShareExperiment + "=" + shareExperimentBucket;
	          options.iggref = { c: 'fbsc', e: 'fbse' }[shareExperimentBucket];
	        }
	
	        // TODO EVENTS: id=ushe3 subsystem=share fixtype=fb-share . review
	        fb.share(shareUrl, options).then(function () {
	          campaignAnalyticsService.sendShareEvent({ gaEventCategory: 'campaign_page_share',
	            gaEventAction: 'click_fb_share_success' }, { thetaName: 'click_fb_share_success' });
	        });
	      };
	
	      scope.shareTwitter = function () {
	        // TODO EVENTS: id=tae7i fixtype=none category=campaign_page_share category-new=TBD action=click_tw_share action-new=TBD label=dynamic name=click_fw_share subsystem=share . review
	        campaignAnalyticsService.sendShareEvent({ gaEventCategory: 'campaign_page_share',
	          gaEventAction: 'click_tw_share' }, { thetaName: 'click_tw_share' });
	
	        twitter.shareTwitter(gonGet('share.twitter_url'), i18n.t('help_make_it_happen_twitter_tooltip', { project_title: gonGet('share.project_title') }), gonGet('share.canonical_url'));
	      };
	
	      scope.shareEmailVisible = function () {
	        if (gon.current_account) {
	          return _.any(gon.campaign.team_members, function (member) {
	            return member.account_id == gon.current_account.account_id;
	          });
	        }
	        return false;
	      }();
	
	      scope.openEmbedModal = function () {
	        $modal({
	          scope: scope,
	          template: __webpack_require__(1102)
	        });
	        $timeout(function () {
	          $compile(angular.element('.i-project-card'))(scope);
	        });
	      };
	
	      scope.projectCardHtml = $sce.trustAsHtml(gonGet('embed_modal_info.card_html'));
	      scope.iframeString = gonGet('embed_modal_info.iframe_html');
	      scope.selectTextarea = function () {
	        element.get('textarea').select();
	      };
	
	      igg.externalService(function () {
	        fb.fetchShareCount();
	        twitter.onTweet(function () {
	          // TODO EVENTS: id=ulie5 fixtype=none category=campaign_page_share category-new=TBD action=click_tw_share action-new=TBD label=dynamic subsystem=share . review
	          campaignAnalyticsService.sendShareEvent({ gaEventCategory: 'campaign_page_share',
	            gaEventAction: 'click_tw_share' }, { thetaName: 'click_tw_share' });
	        });
	      });
	    }
	  };
	}

/***/ },

/***/ 1346:
/***/ function(module, exports, __webpack_require__) {

	// style-loader: Adds some css to the DOM by adding a <style> tag
	
	// load the styles
	var content = __webpack_require__(1347);
	if(typeof content === 'string') content = [[module.id, content, '']];
	// add the styles to the DOM
	var update = __webpack_require__(80)(content, {});
	if(content.locals) module.exports = content.locals;
	// Hot Module Replacement
	if(false) {
		// When the styles change, update the <style> tags
		if(!content.locals) {
			module.hot.accept("!!./../node_modules/css-loader/index.js!./../node_modules/less-loader/index.js!./campaign-share-buttons.less", function() {
				var newContent = require("!!./../node_modules/css-loader/index.js!./../node_modules/less-loader/index.js!./campaign-share-buttons.less");
				if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];
				update(newContent);
			});
		}
		// When the module is disposed, remove the <style> tags
		module.hot.dispose(function() { update(); });
	}

/***/ },

/***/ 1347:
/***/ function(module, exports, __webpack_require__) {

	exports = module.exports = __webpack_require__(79)();
	// imports
	
	
	// module
	exports.push([module.id, "/* Antenna Font Family Variations */\n/* Benton Font Family Variations */\n/** Perk Store mobile header text **/\n/** Only mobile campaign/contributions **/\n/* We can define top-left-dimple or left-top-dimple etc as necessary */\n.campaignShareButtons {\n  display: box;\n  display: -webkit-flex;\n  display: -moz-flex;\n  display: -ms-flexbox;\n  display: -ms-flex;\n  display: flex;\n  box-align: center;\n  -ms-flex-align: center;\n  -webkit-align-items: center;\n  -moz-align-items: center;\n  -ms-align-items: center;\n  align-items: center;\n}\n.campaignShareButtons-component {\n  padding-right: 10px;\n  display: none;\n}\n.campaignShareButtons-component:nth-child(1) {\n  display: inline-block;\n}\n.campaignShareButtons-component:nth-child(2) {\n  display: inline-block;\n}\n.campaignShareButtons-component--follow .share-icon {\n  border-radius: 2px;\n}\n.campaignShareButtons-component--follow--following:hover .share-component .share-icon {\n  background-color: #eb1478;\n}\n.campaignShareButtons-component--follow--following .share-icon {\n  border-color: #eb1478;\n}\n.campaignShareButtons-component--follow--following .share-icon svg {\n  fill: #eb1478;\n}\n.campaignShareButtons .share-hoverLabel {\n  width: 100px;\n  margin-left: -30px;\n  position: absolute;\n}\n@media (min-width: 768px) {\n  .campaignShareButtons .campaignShareButtons-component {\n    display: none;\n  }\n  .campaignShareButtons .campaignShareButtons-component:nth-child(1) {\n    display: inline-block;\n  }\n  .campaignShareButtons .campaignShareButtons-component:nth-child(2) {\n    display: inline-block;\n  }\n  .campaignShareButtons .campaignShareButtons-component:nth-child(3) {\n    display: inline-block;\n  }\n}\n@media (min-width: 1002px) {\n  .campaignShareButtons .campaignShareButtons-component {\n    display: none;\n  }\n  .campaignShareButtons .campaignShareButtons-component:nth-child(1) {\n    display: inline-block;\n  }\n  .campaignShareButtons .campaignShareButtons-component:nth-child(2) {\n    display: inline-block;\n  }\n  .campaignShareButtons .campaignShareButtons-component:nth-child(3) {\n    display: inline-block;\n  }\n  .campaignShareButtons .campaignShareButtons-component:nth-child(4) {\n    display: inline-block;\n  }\n  .campaignShareButtons .campaignShareButtons-component:nth-child(5) {\n    display: inline-block;\n  }\n}\n@media (min-width: 1280px) {\n  .campaignShareButtons .campaignShareButtons-component {\n    display: inline-block;\n  }\n}\n", ""]);
	
	// exports


/***/ },

/***/ 1348:
/***/ function(module, exports) {

	module.exports = "<div class=\"campaignShareButtons\">\n  <!-- # TODO EVENTS: id=pleasehelp . review -->\n  <div ng-click=\"toggleFollowing()\"\n       class=\"campaignShareButtons-component campaignShareButtons-component--follow\"\n       ng-if=\"loggedIn\"\n       ng-class=\"{'campaignShareButtons-component--follow--following': isFollowingProject}\"\n       analytics-on=\"click\"\n       analytics-name=\"{{isFollowingProject ? 'campaign_page_unfollow_click' : 'campaign_page_follow_click'}}\"\n       analytics-category=\"campaign_page_share\"\n       analytics-event=\"{{isFollowingProject ? 'unfollow' : 'follow'}}\"\n       analytics-label=\"{{campaign_type}}_{{campaign_category}}\">\n    <share-item ng-if=\"isFollowingProject\"\n                icon=\"#icon-icon-following\"\n                hover-label=\"{{i18n.t('unfollow')}}\"></share-item>\n    <share-item ng-if=\"!isFollowingProject\"\n                icon=\"#icon-icon-follow\"\n                hover-label=\"{{i18n.t('follow')}}\"></share-item>\n  </div>\n  <div ng-if=\"!loggedIn\"\n       campaign-login-modal\n       class=\"campaignShareButtons-component campaignShareButtons-component--follow\"\n       banner=\"i18n.t('campaign_page_next.login_follow')\">\n    <share-item icon=\"#icon-icon-follow\"\n                hover-label=\"{{i18n.t('follow')}}\"></share-item>\n  </div>\n\n  <div class=\"campaignShareButtons-component\">\n    <share-item ng-click=\"shareFacebook()\"\n                icon=\"#icon-icon-facebook\"\n                hover-label=\"{{fbShareCount()}}\"\n                gogo-test=\"facebook_share\"></share-item>\n  </div>\n\n  <div class=\"campaignShareButtons-component\">\n    <share-item ng-click=\"shareTwitter()\"\n                icon=\"#icon-icon-twitter\"\n                hover-label=\"{{i18n.t('tweet')}}\"\n                gogo-test=\"twitter_share\"></share-item>\n  </div>\n\n  <div email-importer\n       ng-if=\"shareEmailVisible\"\n       class=\"campaignShareButtons-component\"\n       analytics-on=\"click\"\n       analytics-name=\"click_email_importer\"\n       analytics-category=\"campaign_page_share\"\n       analytics-event=\"click_email_importer\"\n       analytics-label=\"{{campaign_type}}_{{campaign_category}}\">\n    <share-item icon=\"#icon-icon-mail\"\n                hover-label=\"{{i18n.t('email_importer')}}\"></share-item>\n  </div>\n\n  <!-- # TODO EVENTS: id=pleasehelp . review -->\n  <div ng-click=\"openEmbedModal()\"\n       class=\"campaignShareButtons-component\"\n       gogo-test=\"embed_share\"\n       analytics-on=\"click\"\n       analytics-name=\"campaign_page_embed_click\"\n       analytics-category=\"campaign_page_share\"\n       analytics-event=\"embed\"\n       analytics-label=\"{{campaign_type}}_{{campaign_category}}\">\n    <share-item icon=\"#icon-icon-embed\"\n                hover-label=\"{{i18n.t('embed_capitalized')}}\"></share-item>\n  </div>\n\n  <!-- # TODO EVENTS: id=pleasehelp . review -->\n  <div copy-url=\"{{shareLinkUrl}}\"\n       class=\"campaignShareButtons-component\"\n       gogo-test=\"link_share\"\n       analytics-on=\"click\"\n       analytics-name=\"campaign_page_linkshare_click\"\n       analytics-category=\"campaign_page_share\"\n       analytics-event=\"link\"\n       analytics-label=\"{{campaign_type}}_{{campaign_category}}\">\n    <share-item icon=\"#icon-icon-link\"\n                hover-label=\"{{i18n.t('link')}}\"></share-item>\n  </div>\n</div>\n";

/***/ },

/***/ 1349:
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	
	campaignContribute.$inject = ["campaign", "i18n", "browser", "campaignAnalyticsService", "campaignContributeService"];
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	/*@ngInject*/
	function campaignContribute(campaign, i18n, browser, campaignAnalyticsService, campaignContributeService) {
	  return {
	    restrict: 'E',
	    scope: {},
	    template: __webpack_require__(1350),
	    link: function link(scope) {
	      scope.campaign = campaign;
	      scope.i18n = i18n;
	      scope.campaignContributionPath = campaignContributeService.contributionPath();
	      scope.campaign_category = campaignAnalyticsService.defaultAnalyticsAttrs().projectCategory;
	      scope.campaign_type = campaignAnalyticsService.campaignType();
	      scope.gogoTestLabel = browser.isMobile() ? 'mobile_contribute_cta' : 'contribute_cta';
	    }
	  };
	}
	exports.default = campaignContribute;

/***/ },

/***/ 1350:
/***/ function(module, exports) {

	module.exports = "<div class=\"campaignContribute\">\n  <a class=\"i-cta-1 i-cta-1--fullWidth\"\n     ng-href=\"{{campaignContributionPath}}\"\n     gogo-test=\"{{::gogoTestLabel}}\"\n     analytics-on=\"click\"\n     analytics-name=\"campaign/contribute.click\"\n     analytics-category=\"campaign_page_contribute\"\n     analytics-event=\"contribute_button\"\n     analytics-label=\"{{campaign_type}}_{{campaign_category}}\">\n    {{::i18n.t('campaign_page_contribute.back_it')}}\n  </a>\n</div>\n";

/***/ },

/***/ 1351:
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	
	campaignViewPerks.$inject = ["i18n", "campaignModalService", "campaignAnalyticsService", "$timeout"];
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	exports.default = campaignViewPerks;
	/*@ngInject*/
	function campaignViewPerks(i18n, campaignModalService, campaignAnalyticsService, $timeout) {
	  return {
	    restrict: 'E',
	    scope: {},
	    template: __webpack_require__(1352),
	    link: function link(scope) {
	      var VERTICAL_PERKS_SECTION_ID = '#vertical_perks_section';
	      var SHOW_PERKS_DELAY = 700;
	      scope.i18n = i18n;
	      scope.campaignCategory = campaignAnalyticsService.defaultAnalyticsAttrs().projectCategory;
	      scope.campaignType = campaignAnalyticsService.campaignType();
	      scope.closeModalAndScrollToPerks = closeModalAndScrollToPerks;
	
	      function closeModalAndScrollToPerks() {
	        campaignModalService.hideModal().then(function () {
	          $timeout(function () {
	            angular.element(VERTICAL_PERKS_SECTION_ID)[0].scrollIntoView();
	          }, SHOW_PERKS_DELAY);
	        });
	      }
	    }
	  };
	}

/***/ },

/***/ 1352:
/***/ function(module, exports) {

	module.exports = "<div class=\"campaignViewPerks\">\n  <a ng-click=\"closeModalAndScrollToPerks()\"\n     gogo-test=\"mobile_view_perks_cta\"\n     class=\"i-cta-1 i-cta-1--fullWidth\"\n     analytics-on=\"click\"\n     analytics-name=\"campaign/contribute.mobile_story_viewperks\"\n     analytics-category=\"campaign_page_contribute\"\n     analytics-event=\"mobile_story_viewperks\"\n     analytics-label=\"{{campaignType}}_{{campaignCategory}}\">\n    {{::i18n.t('campaign_page_next.view_perks')}}\n  </a>\n</div>\n";

/***/ },

/***/ 1353:
/***/ function(module, exports) {

	"use strict";
	
	campaignContributeService.$inject = ["gon", "browser", "campaign"];
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	exports.default = campaignContributeService;
	/*@ngInject*/
	function campaignContributeService(gon, browser, campaign) {
	  return {
	    contributionPath: contributionPath,
	    baseUrl: baseUrl,
	    doesCampaignAcceptContributions: doesCampaignAcceptContributions
	  };
	
	  function contributionPath() {
	    if (gon.pay_flow_split_test) {
	      return baseUrl();
	    } else {
	      return baseUrl() + "?nonperk_amt=100";
	    }
	  }
	
	  function baseUrl() {
	    if (browser.isMobile()) {
	      return gon.urls.campaign_contribution_path;
	    } else {
	      return gon.urls.desktop_campaign_contribution_path;
	    }
	  }
	
	  function doesCampaignAcceptContributions() {
	    var isLive = !campaign.isEnded();
	    var isInDemandWithNoPerks = campaign.isInDemand() && campaign.perks.length === 0;
	    return isLive && (isInDemandWithNoPerks || !campaign.isInDemand());
	  }
	}

/***/ },

/***/ 1354:
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	
	campaignTrustInfo.$inject = ["i18n", "browser", "campaign", "campaignModalService", "trustPassportService"];
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	exports.default = campaignTrustInfo;
	
	__webpack_require__(1355);
	
	/*@ngInject*/
	function campaignTrustInfo(i18n, browser, campaign, campaignModalService, trustPassportService) {
	  return {
	    restrict: 'E',
	    scope: {},
	    template: __webpack_require__(1357),
	    link: function link(scope) {
	      scope.hideModal = function () {
	        campaignModalService.hideModal();
	      };
	
	      scope.i18n = i18n;
	      scope.browser = browser;
	      scope.owner = trustPassportService.owner;
	
	      scope.hasDescription = !!scope.owner.description;
	
	      scope.hasAnyImpacts = trustPassportService.hasImpacts;
	      scope.hasWebsites = trustPassportService.websites.length > 0;
	      scope.commentsCount = scope.owner.comments_count || 0;
	      scope.campaignsCount = scope.owner.campaigns_count || 0;
	      scope.contributionsCount = scope.owner.contributions_count || 0;
	
	      scope.hasAnyVerifications = trustPassportService.hasVerifications;
	      scope.facebookFriendsCount = scope.owner.facebook_friends_count || 0;
	      scope.hasAdminVerification = scope.owner.admin_verified;
	      scope.hasEmailVerification = scope.owner.email_verified;
	      scope.facebookProfileUrl = scope.owner.facebook_profile_url;
	      scope.linkedinProfileUrl = scope.owner.linkedin_profile_url;
	
	      scope.hasAnyOtherTeamMembers = trustPassportService.otherTeamMembers.length > 0;
	      scope.otherTeamMembers = trustPassportService.otherTeamMembers;
	
	      scope.websites = [];
	      var websiteGaAction = function websiteGaAction(url) {
	        var urlMatcher = new RegExp('(.+)\\..+');
	        var domain = urlMatcher.exec(url)[1];
	        var gaActions = {
	          'facebook': 'FBPage',
	          'twitter': 'Twitter',
	          'youtube': 'Youtube',
	          'imdb': 'IMDb'
	        };
	
	        var gaAction = gaActions[domain];
	        return gaAction || 'Website';
	      };
	
	      _.each(trustPassportService.websites, function (website) {
	        scope.websites.push(_.merge(website, { gaAction: websiteGaAction(website.text) }));
	      });
	    }
	  };
	}

/***/ },

/***/ 1355:
/***/ function(module, exports, __webpack_require__) {

	// style-loader: Adds some css to the DOM by adding a <style> tag
	
	// load the styles
	var content = __webpack_require__(1356);
	if(typeof content === 'string') content = [[module.id, content, '']];
	// add the styles to the DOM
	var update = __webpack_require__(80)(content, {});
	if(content.locals) module.exports = content.locals;
	// Hot Module Replacement
	if(false) {
		// When the styles change, update the <style> tags
		if(!content.locals) {
			module.hot.accept("!!./../node_modules/css-loader/index.js!./../node_modules/less-loader/index.js!./campaign-trust-info.less", function() {
				var newContent = require("!!./../node_modules/css-loader/index.js!./../node_modules/less-loader/index.js!./campaign-trust-info.less");
				if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];
				update(newContent);
			});
		}
		// When the module is disposed, remove the <style> tags
		module.hot.dispose(function() { update(); });
	}

/***/ },

/***/ 1356:
/***/ function(module, exports, __webpack_require__) {

	exports = module.exports = __webpack_require__(79)();
	// imports
	
	
	// module
	exports.push([module.id, "/* Antenna Font Family Variations */\n/* Benton Font Family Variations */\n/** Perk Store mobile header text **/\n/** Only mobile campaign/contributions **/\n/* We can define top-left-dimple or left-top-dimple etc as necessary */\n.campaignTrustInfo-section {\n  width: 250px;\n  margin-bottom: 20px;\n}\n.campaignTrustInfo-sectionTitle {\n  font-family: \"Benton Sans Medium\", \"Helvetica\", \"sans-serif\";\n  font-size: 12px;\n  line-height: 18px;\n  font-weight: normal;\n  letter-spacing: 0;\n  margin-bottom: 10px;\n}\n.campaignTrustInfo-sectionContent {\n  font-family: \"Benton Sans\", \"Helvetica\", \"sans-serif\";\n  font-size: 12px;\n  font-weight: normal;\n  line-height: 18px;\n}\n.campaignTrustInfo-row {\n  display: box;\n  display: -webkit-flex;\n  display: -moz-flex;\n  display: -ms-flexbox;\n  display: -ms-flex;\n  display: flex;\n  box-pack: start;\n  -ms-flex-pack: start;\n  -webkit-justify-content: flex-start;\n  -moz-justify-content: flex-start;\n  -ms-justify-content: flex-start;\n  justify-content: flex-start;\n  -ms-flex-wrap: wrap;\n  -webkit-flex-wrap: wrap;\n  -moz-flex-wrap: wrap;\n  flex-wrap: wrap;\n  margin-bottom: 10px;\n}\n.campaignTrustInfo-campaigner {\n  display: box;\n  display: -webkit-flex;\n  display: -moz-flex;\n  display: -ms-flexbox;\n  display: -ms-flex;\n  display: flex;\n  -webkit-align-items: top;\n  -moz-align-items: top;\n  -ms-align-items: top;\n  align-items: top;\n  margin-bottom: 15px;\n}\n.campaignTrustInfo-campaignerAvatar {\n  border-radius: 50%;\n  width: 50px;\n  height: 50px;\n}\n.campaignTrustInfo-campaignerDetails {\n  box-flex: 1;\n  -webkit-flex: 1;\n  -moz-flex: 1;\n  -ms-flex: 1;\n  flex: 1;\n  margin-left: 15px;\n  color: #6a6a6a;\n  font-family: \"Benton Sans\", \"Helvetica\", \"sans-serif\";\n  font-size: 12px;\n  font-weight: normal;\n  line-height: 18px;\n}\n.campaignTrustInfo-campaignerDetails-name {\n  font-family: \"Benton Sans Medium\", \"Helvetica\", \"sans-serif\";\n  font-size: 12px;\n  line-height: 18px;\n  font-weight: normal;\n  letter-spacing: 0;\n}\n.campaignTrustInfo-campaignerDetails-role {\n  text-transform: capitalize;\n}\n", ""]);
	
	// exports


/***/ },

/***/ 1357:
/***/ function(module, exports) {

	module.exports = "<div class=\"campaignTrustModal campaignTrustInfo\">\n  <div ng-class=\"{'modal-dialog': browser.isTabletPlus()}\">\n    <div ng-class=\"{'modal-content': browser.isTabletPlus()}\">\n      <div class=\"campaignTrustModal-header\">\n        <div class=\"campaignTrustModal-header--title\">\n          {{::i18n.t('campaign_page_next.trust.about')}}\n        </div>\n        <a class=\"campaignTrustModal-header--close\" ng-click=\"hideModal()\" aria-hidden=\"true\">\n          <svg-icon icon=\"icon-icon-close\"></svg-icon>\n        </a>\n      </div>\n\n      <div class=\"campaignTrustInfo-section campaignTrustInfo-section-campaigner\">\n        <div class=\"campaignTrustInfo-campaigner\">\n          <img class=\"campaignTrustInfo-campaignerAvatar\" ng-src=\"{{owner.avatar_url}}\">\n          <div class=\"campaignTrustInfo-campaignerDetails\">\n            <div class=\"campaignTrustInfo-campaignerDetails-name\">\n              {{::owner.name}}\n            </div>\n            <div class=\"campaignTrustInfo-campaignerDetails-role\">\n              {{::owner.role}}\n            </div>\n            <div class=\"campaignTrustInfo-campaignerDetails-fullProfileLink\">\n              <a href=\"{{::owner.profile_url}}\" target=\"_blank\">{{::i18n.t('campaign_page_next.trust.view_full_profile')}}</a>\n            </div>\n          </div>\n        </div>\n      </div>\n\n      <div ng-if=\"hasDescription\" class=\"campaignTrustInfo-section campaignTrustInfo-section-about\">\n        <div class=\"campaignTrustInfo-sectionTitle\">\n          {{::i18n.t('campaign_page_next.trust.about_campaigner', { name: owner.first_name })}}\n        </div>\n        <div class=\"campaignTrustInfo-sectionContent\">\n          {{::owner.description}}\n        </div>\n      </div>\n\n      <div ng-if=\"hasAnyVerifications\" class=\"campaignTrustInfo-section campaignTrustInfo-section-verifications\">\n        <div class=\"campaignTrustInfo-sectionTitle\">\n          {{::i18n.t('campaign_page_next.trust.verifications')}}\n        </div>\n        <div class=\"campaignTrustInfo-sectionContent\">\n          <div ng-if=\"hasEmailVerification\">\n            {{::i18n.t('campaign_page_next.trust.email_verified')}}\n          </div>\n          <div ng-if=\"facebookProfileUrl\">\n            <a href=\"{{::facebookProfileUrl}}\" target=\"_blank\" rel=\"nofollow\">\n              {{::i18n.t('campaign_page_next.trust.facebook_friends_count', { count: facebookFriendsCount }) }}\n            </a>\n          </div>\n          <div ng-if=linkedinProfileUrl>\n            <a href=\"{{::linkedinProfileUrl}}\" target=\"_blank\" rel=\"nofollow\">\n              {{::i18n.t('campaign_page_next.trust.linkedin_verified')}}\n            </a>\n          </div>\n          <div ng-if=\"hasAdminVerification\">\n            {{::i18n.t('campaign_page_next.trust.admin_verified')}}\n          </div>\n        </div>\n      </div>\n\n      <div ng-if=\"hasAnyImpacts\" class=\"campaignTrustInfo-section campaignTrustInfo-section-impacts\">\n        <div class=\"campaignTrustInfo-sectionTitle\">\n          {{::i18n.t('campaign_page_next.trust.impact')}}\n        </div>\n        <div class=\"campaignTrustInfo-sectionContent\">\n          <div ng-if=\"campaignsCount > 0\">\n            {{::i18n.t('campaign_page_next.trust.campaigns_count', { count: campaignsCount })}}\n          </div>\n          <div ng-if=\"contributionsCount > 0\">\n            {{::i18n.t('campaign_page_next.trust.contributions_count', { count: contributionsCount })}}\n          </div>\n          <div ng-if=\"commentsCount > 0\">\n            {{::i18n.t('campaign_page_next.trust.comments_count', { count: commentsCount })}}\n          </div>\n        </div>\n      </div>\n\n      <div class=\"campaignTrustInfo-row\">\n        <div ng-if=\"hasAnyOtherTeamMembers\" class=\"campaignTrustInfo-section campaignTrustInfo-section-team\">\n          <div class=\"campaignTrustInfo-sectionTitle\">\n            {{::i18n.t('campaign_page_next.trust.team')}}\n          </div>\n          <div class=\"campaignTrustInfo-sectionContent\">\n            <div class=\"campaignTrustInfo-campaigner\" ng-repeat=\"teamMember in otherTeamMembers\">\n              <img class=\"campaignTrustInfo-campaignerAvatar\" ng-src=\"{{teamMember.avatar_url}}\">\n              <div class=\"campaignTrustInfo-campaignerDetails\">\n                <div class=\"campaignTrustInfo-campaignerDetails-name\">\n                  {{::teamMember.name}}\n                </div>\n                <div class=\"campaignTrustInfo-campaignerDetails-role\">\n                  {{::teamMember.role}}\n                </div>\n                <div class=\"campaignTrustInfo-campaignerDetails-fullProfileLink\">\n                  <a href=\"{{::teamMember.profile_url}}\" target=\"_blank\">{{::i18n.t('campaign_page_next.trust.view_full_profile')}}</a>\n                </div>\n              </div>\n            </div>\n          </div>\n        </div>\n\n        <campaign-supported-by></campaign-supported-by>\n      </div>\n\n      <div class=\"campaignTrustInfo-section campaignTrustInfo-websites\" ng-if=\"hasWebsites\">\n        <div class=\"campaignTrustInfo-sectionTitle\">{{::i18n.t('websites')}}</div>\n        <a target=\"blank\" class=\"campaignTrustInfo-website\" ng-repeat=\"website in websites\" ng-href=\"{{website.url}}\"\n            analytics-on=\"click\"\n            analytics-name=\"trust_{{website.gaAction}}_click\"\n            analytics-category=\"Trust\"\n            analytics-event=\"{{website.gaAction}}\">\n          {{website.text}}\n        </a>\n      </div>\n    </div>\n  </div>\n</div>\n";

/***/ },

/***/ 1358:
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	
	campaignTrustQuestion.$inject = ["$http", "campaignModalService", "trustPassportService", "vcRecaptchaService", "i18n", "browser"];
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	exports.default = campaignTrustQuestion;
	
	__webpack_require__(1359);
	
	/*@ngInject*/
	function campaignTrustQuestion($http, campaignModalService, trustPassportService, vcRecaptchaService, i18n, browser) {
	  return {
	    restrict: 'E',
	    scope: {},
	    template: __webpack_require__(1361),
	    link: function link(scope) {
	      scope.hideModal = function () {
	        campaignModalService.hideModal();
	      };
	      scope.browser = browser;
	      scope.owner = trustPassportService.owner;
	      scope.grecaptchaSiteKey = trustPassportService.grecaptchaSiteKey;
	      scope.i18n = i18n;
	      scope.messageSent = false;
	      scope.messageFailed = false;
	      scope.message = {
	        text: ''
	      };
	      var recaptchaId = null;
	      var recaptchaSuccess = false;
	
	      scope.sendMessageDisabled = function () {
	        return !(scope.message.text.length > 0 && trustPassportService.isRecaptchaReadyForId(recaptchaId) && recaptchaSuccess);
	      };
	
	      scope.onRecaptchaSuccess = function () {
	        recaptchaSuccess = true;
	      };
	
	      scope.setReCaptchaReady = function (widgetId) {
	        recaptchaId = widgetId;
	        trustPassportService.registerRecaptchaId(widgetId);
	      };
	
	      scope.sendMessage = function () {
	        var captchaResponse = null;
	
	        if (trustPassportService.isRecaptchaReadyForId(recaptchaId)) {
	          captchaResponse = vcRecaptchaService.getResponse(recaptchaId);
	        } else {
	          captchaResponse = true;
	        }
	
	        $http.post(trustPassportService.contactOwnerEndpointUrl, { comment: { text: scope.message.text }, grecaptcha: captchaResponse }).then(function () {
	          scope.messageSent = true;
	          scope.message.text = '';
	          scope.messageFailed = false;
	        }, function () {
	          scope.messageFailed = true;
	        }).finally(function () {
	          if (trustPassportService.isRecaptchaReadyForId(recaptchaId)) {
	            vcRecaptchaService.reload();
	          }
	        });
	      };
	    }
	  };
	}

/***/ },

/***/ 1359:
/***/ function(module, exports, __webpack_require__) {

	// style-loader: Adds some css to the DOM by adding a <style> tag
	
	// load the styles
	var content = __webpack_require__(1360);
	if(typeof content === 'string') content = [[module.id, content, '']];
	// add the styles to the DOM
	var update = __webpack_require__(80)(content, {});
	if(content.locals) module.exports = content.locals;
	// Hot Module Replacement
	if(false) {
		// When the styles change, update the <style> tags
		if(!content.locals) {
			module.hot.accept("!!./../node_modules/css-loader/index.js!./../node_modules/less-loader/index.js!./campaign-trust-question.less", function() {
				var newContent = require("!!./../node_modules/css-loader/index.js!./../node_modules/less-loader/index.js!./campaign-trust-question.less");
				if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];
				update(newContent);
			});
		}
		// When the module is disposed, remove the <style> tags
		module.hot.dispose(function() { update(); });
	}

/***/ },

/***/ 1360:
/***/ function(module, exports, __webpack_require__) {

	exports = module.exports = __webpack_require__(79)();
	// imports
	
	
	// module
	exports.push([module.id, "/* Antenna Font Family Variations */\n/* Benton Font Family Variations */\n/** Perk Store mobile header text **/\n/** Only mobile campaign/contributions **/\n/* We can define top-left-dimple or left-top-dimple etc as necessary */\n@media not all and (min-width: 768px) {\n  .campaignTrustQuestion .campaignTrustModal-header {\n    display: none;\n  }\n}\n@media not all and (min-width: 768px) {\n  .campaignTrustQuestion {\n    padding: 10px 20px;\n  }\n}\n.campaignTrustQuestion-message {\n  padding-top: 20px;\n  font-family: \"Benton Sans\", \"Helvetica\", \"sans-serif\";\n  font-size: 12px;\n  font-weight: normal;\n  line-height: 18px;\n}\n.campaignTrustQuestion-message--textarea textarea {\n  height: 250px;\n  padding: 15px;\n  resize: none;\n}\n@media not all and (min-width: 768px) {\n  .campaignTrustQuestion-message--textarea textarea {\n    font-size: 16px;\n    /* disable ios zoom on input select */\n  }\n}\n.campaignTrustQuestion-message--charCounter {\n  text-align: right;\n}\n.campaignTrustQuestion-reply {\n  font-family: \"Benton Sans\", \"Helvetica\", \"sans-serif\";\n  font-size: 12px;\n  font-weight: normal;\n  line-height: 18px;\n  padding-top: 20px;\n  padding-bottom: 20px;\n}\n.campaignTrustQuestion-verifySend {\n  display: box;\n  display: -webkit-flex;\n  display: -moz-flex;\n  display: -ms-flexbox;\n  display: -ms-flex;\n  display: flex;\n  box-pack: justify;\n  -ms-flex-pack: justify;\n  -webkit-justify-content: space-between;\n  -moz-justify-content: space-between;\n  -ms-justify-content: space-between;\n  justify-content: space-between;\n  box-align: end;\n  -ms-flex-align: end;\n  -webkit-align-items: flex-end;\n  -moz-align-items: flex-end;\n  -ms-align-items: flex-end;\n  align-items: flex-end;\n}\n.campaignTrustQuestion-verifySend--captcha .g-recaptcha {\n  transform: scale(0.95);\n  -webkit-transform: scale(0.95);\n  transform-origin: 0 0;\n  -webkit-transform-origin: 0 0;\n}\n.campaignTrustQuestion-verifySend--captcha #rc-imageselect {\n  transform: scale(0.4);\n  -webkit-transform: scale(0.4);\n  transform-origin: 0 0;\n  -webkit-transform-origin: 0 0;\n}\n@media not all and (min-width: 768px) {\n  .campaignTrustQuestion-verifySend {\n    display: block;\n  }\n  .campaignTrustQuestion-verifySend--captcha {\n    display: box;\n    display: -webkit-flex;\n    display: -moz-flex;\n    display: -ms-flexbox;\n    display: -ms-flex;\n    display: flex;\n    box-pack: center;\n    -ms-flex-pack: center;\n    -webkit-justify-content: center;\n    -moz-justify-content: center;\n    -ms-justify-content: center;\n    justify-content: center;\n  }\n  .campaignTrustQuestion-verifySend--send {\n    padding-top: 10px;\n  }\n  .campaignTrustQuestion-verifySend--send button {\n    height: 50px;\n    width: 100%;\n  }\n}\n.campaignTrustQuestion-errorSection {\n  margin-bottom: 40px;\n  position: relative;\n}\n", ""]);
	
	// exports


/***/ },

/***/ 1361:
/***/ function(module, exports) {

	module.exports = "<div class='campaignTrustModal campaignTrustQuestion'>\n  <div ng-class=\"{'modal-dialog': browser.isTabletPlus()}\">\n    <div ng-class=\"{'modal-content': browser.isTabletPlus()}\">\n      <div class=\"campaignTrustModal-header\">\n        <div class=\"campaignTrustModal-header--title\">\n          {{::i18n.t('campaign_page_next.trust.ask_question_title')}}\n        </div>\n        <a class=\"campaignTrustModal-header--close\" ng-click=\"hideModal()\" aria-hidden=\"true\">\n          <svg-icon icon=\"icon-icon-close\"></svg-icon>\n        </a>\n      </div>\n\n      <div class=\"campaignTrustQuestion-errorSection\" ng-if=\"messageFailed\">\n        <div class=\"messageNotification messageNotification--error\">\n          <div class=\"messageNotification-header\">{{::i18n.t('trust_passport.sorry_somethings_wrong_on_our_end')}}</div>\n          {{::i18n.t('trust_passport.try_sending_your_message_in_a_few_minutes')}}\n        </div>\n      </div>\n      <div ng-show=\"!messageSent\">\n        <div class=\"campaignTrust\">\n          <img class=\"campaignTrust-avatar\" ng-src=\"{{::owner.avatar_url}}\">\n          <div class=\"campaignTrust-details\">\n            <div class=\"campaignTrust-detailsName\">\n              {{::owner.name}}\n            </div>\n            <div class=\"campaignTrust-detailsRole\">\n              {{::owner.role}}\n            </div>\n          </div>\n        </div>\n        <div class=\"campaignTrustQuestion-message\">\n          <div class=\"campaignTrustQuestion-message--textarea\">\n            <textarea ng-model=\"message.text\" maxlength=\"500\"></textarea>\n          </div>\n          <div class=\"campaignTrustQuestion-message--charCounter ng-binding\">{{message.text | charCounter:500}}</div>\n        </div>\n        <div class=\"campaignTrustQuestion-reply\">\n          {{::i18n.t('trust_passport.campaign_owner_will_be_able_to_reply_directly', {owner: owner.name})}}\n        </div>\n        <div class=\"campaignTrustQuestion-verifySend\">\n          <div class=\"campaignTrustQuestion-verifySend--captcha\">\n            <div class=\"g-recaptcha\" vc-recaptcha key=\"grecaptchaSiteKey\" on-create=\"setReCaptchaReady(widgetId)\" on-success=\"onRecaptchaSuccess(response)\"></div>\n          </div>\n          <div class=\"campaignTrustQuestion-verifySend--send\">\n            <button class=\"i-cta-1\"\n                    ng-disabled=\"sendMessageDisabled()\"\n                    ng-click=\"sendMessage()\">\n              {{::i18n.t('send_message')}}\n            </button>\n          </div>\n        </div>\n      </div>\n      <div ng-show=\"messageSent\">\n        <div class=\"messageNotification messageNotification--success\">\n          <div class=\"messageNotification-header\">{{::i18n.t('trust_passport.your_message_has_been_sent')}}</div>\n          {{::i18n.t('trust_passport.the_campaign_owner_has_received_your_message')}}\n        </div>\n      </div>\n    </div>\n  </div>\n</div>\n";

/***/ },

/***/ 1362:
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	
	campaignTrust.$inject = ["trustPassportService", "campaignModalService", "i18n", "campaign"];
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	exports.default = campaignTrust;
	
	__webpack_require__(1363);
	
	/*@ngInject*/
	function campaignTrust(trustPassportService, campaignModalService, i18n, campaign) {
	  return {
	    restrict: 'E',
	    scope: {},
	    template: __webpack_require__(1365),
	    link: function link(scope) {
	      scope.i18n = i18n;
	      scope.campaign = campaign;
	      scope.owner = trustPassportService.owner;
	      scope.loggedIn = trustPassportService.loggedIn;
	      scope.loginUrl = trustPassportService.loginUrl;
	      scope.showTrustQuestionModal = function () {
	        campaignModalService.createModal({
	          title: i18n.t('campaign_page_next.trust.ask_question_title'),
	          scope: scope,
	          content: '<campaign-trust-question></campaign-trust-question>'
	        });
	        campaignModalService.showModal();
	      };
	
	      scope.showTrustInfoModal = function () {
	        campaignModalService.createModal({
	          title: i18n.t('campaign_page_next.trust.about'),
	          scope: scope,
	          content: '<campaign-trust-info></campaign-trust-info>'
	        });
	        campaignModalService.showModal();
	      };
	    }
	  };
	}

/***/ },

/***/ 1363:
/***/ function(module, exports, __webpack_require__) {

	// style-loader: Adds some css to the DOM by adding a <style> tag
	
	// load the styles
	var content = __webpack_require__(1364);
	if(typeof content === 'string') content = [[module.id, content, '']];
	// add the styles to the DOM
	var update = __webpack_require__(80)(content, {});
	if(content.locals) module.exports = content.locals;
	// Hot Module Replacement
	if(false) {
		// When the styles change, update the <style> tags
		if(!content.locals) {
			module.hot.accept("!!./../node_modules/css-loader/index.js!./../node_modules/less-loader/index.js!./campaign-trust.less", function() {
				var newContent = require("!!./../node_modules/css-loader/index.js!./../node_modules/less-loader/index.js!./campaign-trust.less");
				if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];
				update(newContent);
			});
		}
		// When the module is disposed, remove the <style> tags
		module.hot.dispose(function() { update(); });
	}

/***/ },

/***/ 1364:
/***/ function(module, exports, __webpack_require__) {

	exports = module.exports = __webpack_require__(79)();
	// imports
	
	
	// module
	exports.push([module.id, "/* Antenna Font Family Variations */\n/* Benton Font Family Variations */\n/** Perk Store mobile header text **/\n/** Only mobile campaign/contributions **/\n/* We can define top-left-dimple or left-top-dimple etc as necessary */\n.campaignTrust {\n  display: box;\n  display: -webkit-flex;\n  display: -moz-flex;\n  display: -ms-flexbox;\n  display: -ms-flex;\n  display: flex;\n  box-align: center;\n  -ms-flex-align: center;\n  -webkit-align-items: center;\n  -moz-align-items: center;\n  -ms-align-items: center;\n  align-items: center;\n}\n.campaignTrust-avatar {\n  border-radius: 50%;\n  width: 50px;\n}\n.campaignTrust-details {\n  box-flex: 1;\n  -webkit-flex: 1;\n  -moz-flex: 1;\n  -ms-flex: 1;\n  flex: 1;\n  margin-left: 10px;\n}\n.campaignTrust-detailsName {\n  font-family: \"Benton Sans Medium\", \"Helvetica\", \"sans-serif\";\n  font-size: 12px;\n  line-height: 18px;\n  font-weight: normal;\n  letter-spacing: 0;\n  color: #6a6a6a;\n}\n.campaignTrust-detailsLocation {\n  font-family: \"Benton Sans\", \"Helvetica\", \"sans-serif\";\n  font-size: 12px;\n  font-weight: normal;\n  line-height: 18px;\n  color: #6a6a6a;\n}\n.campaignTrust-detailsLinks {\n  display: box;\n  display: -webkit-flex;\n  display: -moz-flex;\n  display: -ms-flexbox;\n  display: -ms-flex;\n  display: flex;\n  box-pack: start;\n  -ms-flex-pack: start;\n  -webkit-justify-content: flex-start;\n  -moz-justify-content: flex-start;\n  -ms-justify-content: flex-start;\n  justify-content: flex-start;\n  -ms-flex-line-pack: center;\n  -webkit-align-content: center;\n  -moz-align-content: center;\n  -ms-align-content: center;\n  align-content: center;\n  font-family: \"Benton Sans\", \"Helvetica\", \"sans-serif\";\n  font-size: 12px;\n  font-weight: normal;\n  line-height: 18px;\n  color: #eb1478;\n}\n.campaignTrust-detailsLinks-delimeter {\n  color: #6a6a6a;\n  padding: 0 5px;\n}\n.campaignTrust-detailsLinks a:hover {\n  cursor: pointer;\n}\n@media (min-width: 1280px) {\n  .campaignTrust-details > div {\n    font-size: 14px;\n    line-height: 18px;\n  }\n}\n.campaignTrustModal .modal-dialog {\n  margin-top: 40px;\n  width: 600px;\n}\n.campaignTrustModal .modal-content {\n  padding: 70px 40px 40px 40px;\n  background-color: #ffffff;\n  border-radius: 0;\n  border: none;\n  -webkit-box-shadow: none;\n  box-shadow: none;\n}\n.campaignTrustModal .campaignTrust-detailsName {\n  font-family: \"Benton Sans Medium\", \"Helvetica\", \"sans-serif\";\n  font-size: 12px;\n  line-height: 18px;\n  font-weight: normal;\n  letter-spacing: 0;\n}\n.campaignTrustModal .campaignTrust-detailsRole {\n  font-family: \"Benton Sans\", \"Helvetica\", \"sans-serif\";\n  font-size: 12px;\n  font-weight: normal;\n  line-height: 18px;\n  color: #6a6a6a;\n}\n.campaignTrustModal-header {\n  display: box;\n  display: -webkit-flex;\n  display: -moz-flex;\n  display: -ms-flexbox;\n  display: -ms-flex;\n  display: flex;\n  box-pack: justify;\n  -ms-flex-pack: justify;\n  -webkit-justify-content: space-between;\n  -moz-justify-content: space-between;\n  -ms-justify-content: space-between;\n  justify-content: space-between;\n  box-align: center;\n  -ms-flex-align: center;\n  -webkit-align-items: center;\n  -moz-align-items: center;\n  -ms-align-items: center;\n  align-items: center;\n  background-color: #f5f5f5;\n  position: absolute;\n  width: 100%;\n  left: 0;\n  top: 0;\n  height: 50px;\n  border: 1px solid #dddddd;\n}\n.campaignTrustModal-header--title {\n  font-family: \"Benton Sans\", \"Helvetica\", \"sans-serif\";\n  font-weight: bold;\n  font-size: 14px;\n  line-height: 20px;\n  color: #6a6a6a;\n  padding-left: 20px;\n}\n.campaignTrustModal-header--close {\n  padding-right: 20px;\n}\n.campaignTrustModal-header--close svg {\n  cursor: pointer;\n  width: 22px;\n  height: 22px;\n  fill: #a8a8a8;\n}\n.campaignTrustModal-header--close:hover svg {\n  fill: #fa1681;\n}\n", ""]);
	
	// exports


/***/ },

/***/ 1365:
/***/ function(module, exports) {

	module.exports = "<div class=\"campaignTrust\">\n  <img class=\"campaignTrust-avatar\" ng-src=\"{{owner.avatar_url}}\">\n  <div class=\"campaignTrust-details\">\n    <div class=\"campaignTrust-detailsName\">\n      {{owner.name}}\n    </div>\n    <div class=\"campaignTrust-detailsLocation\">\n      {{campaign.location}}\n    </div>\n    <div class=\"campaignTrust-detailsLinks\">\n      <a class=\"campaignTrust-detailsLinks-info\"\n         analytics-on=\"click\"\n         analytics-name=\"campaign.trust/bio.click\"\n         analytics-category=\"campaign_page_trust\"\n         analytics-event=\"bio_click\"\n         analytics-label=\"tbd_backer_type\"\n         ng-click=\"showTrustInfoModal()\">{{::i18n.t('campaign_page_next.trust.about')}}</a>\n      <div class=\"campaignTrust-detailsLinks-delimeter\">|</div>\n      <a ng-if=\"loggedIn\"\n         gogo-test=\"question-logged-in\"\n         analytics-on=\"click\"\n         analytics-name=\"campaign.trust/contact.click\"\n         analytics-category=\"campaign_page_trust\"\n         analytics-event=\"contact_click\"\n         analytics-label=\"tbd_backer_type\"\n         ng-click=\"showTrustQuestionModal()\">{{::i18n.t('campaign_page_next.trust.ask_question')}}</a>\n      <a ng-if=\"!loggedIn\"\n         campaign-login-modal\n         banner=\"i18n.t('campaign_page_next.login_ask_question')\"\n         gogo-test=\"question-not-logged-in\">{{::i18n.t('campaign_page_next.trust.ask_question')}}</a>\n    </div>\n  </div>\n</div>\n";

/***/ },

/***/ 1366:
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	
	campaignGoalProgress.$inject = ["$filter", "$sce", "campaign", "i18n", "campaignGoal"];
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	
	__webpack_require__(1367);
	
	/*@ngInject*/
	function campaignGoalProgress($filter, $sce, campaign, i18n, campaignGoal) {
	  return {
	    restrict: 'E',
	    scope: {},
	    template: __webpack_require__(1369),
	    link: function link(scope) {
	      scope.barFillWidth = barFillWidth();
	      scope.campaignIsNotPublished = !campaign.isPublished();
	      scope.currencyCode = campaign.currency.iso_code;
	      scope.detailsGoalHtml = detailsGoalHtml();
	      scope.detailsGoalType = goalType();
	      scope.detailsTimeLeftHtml = timeLeftHtml();
	      scope.raisedAmount = raisedAmount();
	      scope.raisedBackers = raisedBackers();
	      scope.campaignGoal = campaignGoal;
	
	      function barFillWidth() {
	        var percent = percentFunded();
	        if (percent < 0) return 0;
	        if (percent > 100) return 100;
	        return percent;
	      }
	
	      function detailsGoalHtml() {
	        var percent = "<em>" + Math.round(percentFunded()) + "%</em>";
	        var goal = showAsCurrency(campaign.goal);
	        return $sce.trustAsHtml(i18n.t('x_of_y', { x: percent, y: goal }) + '&nbsp;');
	      }
	
	      function goalType() {
	        return {
	          fixed: i18n.t("fixed_goal"),
	          flexible: i18n.t("flexible_goal")
	        }[campaign.funding_type];
	      }
	
	      function timeLeftHtml() {
	        var timeDiff = moment(campaign.funding_ends_at).diff(moment.now());
	        if (timeDiff < 0) {
	          return i18n.t('no_time_left_html');
	        } else {
	          var timeRemaining = moment.duration(timeDiff);
	          var remainingText = i18n.locale === 'en' ? '&nbsp;left' : '';
	          var html = timeRemaining.humanize().replace(/(\d+)/, function (_, num) {
	            return '<em>' + num + '</em>';
	          }) + remainingText;
	          return $sce.trustAsHtml(html);
	        }
	      }
	
	      function raisedAmount() {
	        return showAsCurrency(campaign.collected_funds);
	      }
	
	      function raisedBackers() {
	        return i18n.t('campaign_page_next.goal_progress.raised_by_number_backers', { num_backers: campaign.contributions_count });
	      }
	
	      function percentFunded() {
	        return campaign.goal === 0 ? 0 : campaign.collected_funds / campaign.goal * 100;
	      }
	
	      function showAsCurrency(amount) {
	        return $filter('iggCurrency')(amount, campaign.currency.iso_num, 'noIso');
	      }
	    }
	  };
	}
	exports.default = campaignGoalProgress;

/***/ },

/***/ 1367:
/***/ function(module, exports, __webpack_require__) {

	// style-loader: Adds some css to the DOM by adding a <style> tag
	
	// load the styles
	var content = __webpack_require__(1368);
	if(typeof content === 'string') content = [[module.id, content, '']];
	// add the styles to the DOM
	var update = __webpack_require__(80)(content, {});
	if(content.locals) module.exports = content.locals;
	// Hot Module Replacement
	if(false) {
		// When the styles change, update the <style> tags
		if(!content.locals) {
			module.hot.accept("!!./../node_modules/css-loader/index.js!./../node_modules/less-loader/index.js!./campaign-goal-progress.less", function() {
				var newContent = require("!!./../node_modules/css-loader/index.js!./../node_modules/less-loader/index.js!./campaign-goal-progress.less");
				if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];
				update(newContent);
			});
		}
		// When the module is disposed, remove the <style> tags
		module.hot.dispose(function() { update(); });
	}

/***/ },

/***/ 1368:
/***/ function(module, exports, __webpack_require__) {

	exports = module.exports = __webpack_require__(79)();
	// imports
	
	
	// module
	exports.push([module.id, "/* Antenna Font Family Variations */\n/* Benton Font Family Variations */\n/** Perk Store mobile header text **/\n/** Only mobile campaign/contributions **/\n/* We can define top-left-dimple or left-top-dimple etc as necessary */\n.raised-sizing {\n  font-family: \"Benton Sans\", \"Helvetica\", \"sans-serif\";\n  font-size: 12px;\n  font-weight: normal;\n  line-height: 18px;\n}\n@media (min-width: 1002px) {\n  .raised-sizing {\n    font-family: \"Benton Sans\", \"Helvetica\", \"sans-serif\";\n    font-size: 16px;\n    font-weight: normal;\n    line-height: 26px;\n    letter-spacing: 0;\n    line-height: 25px;\n  }\n}\n.amount-sizing {\n  font-family: \"Benton Sans\", \"Helvetica\", \"sans-serif\";\n  font-weight: bold;\n  font-size: 14px;\n  line-height: 20px;\n}\n@media (min-width: 1002px) {\n  .amount-sizing {\n    font-family: \"Benton Sans\", \"Helvetica\", \"sans-serif\";\n    font-size: 20px;\n    font-weight: bold;\n    line-height: 26px;\n  }\n}\n@media (min-width: 1002px) {\n  .video-heights-for-2-columns {\n    height: 415px;\n  }\n}\n@media (min-width: 1280px) {\n  .video-heights-for-2-columns {\n    height: 460px !important;\n  }\n}\n.campaignGoalProgress {\n  color: #2a2a2a;\n}\n.campaignGoalProgress em {\n  font-family: \"Benton Sans Medium\", \"Helvetica\", \"sans-serif\";\n}\n.campaignGoalProgress-raised {\n  font-family: \"Benton Sans\", \"Helvetica\", \"sans-serif\";\n  font-size: 12px;\n  font-weight: normal;\n  line-height: 18px;\n}\n@media (min-width: 1002px) {\n  .campaignGoalProgress-raised {\n    font-family: \"Benton Sans\", \"Helvetica\", \"sans-serif\";\n    font-size: 16px;\n    font-weight: normal;\n    line-height: 26px;\n    letter-spacing: 0;\n    line-height: 25px;\n  }\n}\n.campaignGoalProgress-raisedAmount {\n  font-family: \"Benton Sans\", \"Helvetica\", \"sans-serif\";\n  font-weight: bold;\n  font-size: 14px;\n  line-height: 20px;\n}\n@media (min-width: 1002px) {\n  .campaignGoalProgress-raisedAmount {\n    font-family: \"Benton Sans\", \"Helvetica\", \"sans-serif\";\n    font-size: 20px;\n    font-weight: bold;\n    line-height: 26px;\n  }\n}\n.campaignGoalProgress-bar {\n  height: 10px;\n  background-color: #dddddd;\n  margin-bottom: 5px;\n  margin-top: 5px;\n}\n.campaignGoalProgress-barFill {\n  background-color: #0eb4b6;\n  height: 100%;\n}\n.campaignGoalProgress-barFill--ended {\n  background-color: #a8a8a8;\n}\n.campaignGoalProgress-details {\n  font-family: \"Benton Sans\", \"Helvetica\", \"sans-serif\";\n  font-size: 12px;\n  font-weight: normal;\n  line-height: 18px;\n  line-height: 20px;\n  display: box;\n  display: -webkit-flex;\n  display: -moz-flex;\n  display: -ms-flexbox;\n  display: -ms-flex;\n  display: flex;\n  box-pack: justify;\n  -ms-flex-pack: justify;\n  -webkit-justify-content: space-between;\n  -moz-justify-content: space-between;\n  -ms-justify-content: space-between;\n  justify-content: space-between;\n}\n@media (min-width: 1002px) {\n  .campaignGoalProgress-details {\n    font-family: \"Benton Sans\", \"Helvetica\", \"sans-serif\";\n    font-size: 14px;\n    font-weight: normal;\n    line-height: 20px;\n    line-height: 25px;\n  }\n}\n.campaignGoalProgress-detailsGoal {\n  display: box;\n  display: -webkit-flex;\n  display: -moz-flex;\n  display: -ms-flexbox;\n  display: -ms-flex;\n  display: flex;\n  box-pack: start;\n  -ms-flex-pack: start;\n  -webkit-justify-content: flex-start;\n  -moz-justify-content: flex-start;\n  -ms-justify-content: flex-start;\n  justify-content: flex-start;\n  -ms-flex-wrap: wrap;\n  -webkit-flex-wrap: wrap;\n  -moz-flex-wrap: wrap;\n  flex-wrap: wrap;\n}\n.campaignGoalProgress-detailsGoal em {\n  font-family: \"Benton Sans Medium\", \"Helvetica\", \"sans-serif\";\n  font-size: 12px;\n  line-height: 18px;\n  font-weight: normal;\n  letter-spacing: 0;\n}\n@media (min-width: 1002px) {\n  .campaignGoalProgress-detailsGoal em {\n    font-family: \"Benton Sans Medium\", \"Helvetica\", \"sans-serif\";\n    font-size: 14px;\n    line-height: 20px;\n  }\n}\n.campaignGoalProgress-detailsTimeLeft {\n  width: 120px;\n  display: box;\n  display: -webkit-flex;\n  display: -moz-flex;\n  display: -ms-flexbox;\n  display: -ms-flex;\n  display: flex;\n  box-pack: end;\n  -ms-flex-pack: end;\n  -webkit-justify-content: flex-end;\n  -moz-justify-content: flex-end;\n  -ms-justify-content: flex-end;\n  justify-content: flex-end;\n}\n", ""]);
	
	// exports


/***/ },

/***/ 1369:
/***/ function(module, exports) {

	module.exports = "<div class=\"campaignGoalProgress\">\n  <div class=\"campaignGoalProgress-raised\">\n    <span class=\"campaignGoalProgress-raisedAmount\" gogo-test=\"raised\">{{::raisedAmount}}</span> {{::currencyCode}} <span gogo-test=\"backers\">{{::raisedBackers}}</span>\n  </div>\n  <div class=\"campaignGoalProgress-bar\">\n    <div class=\"campaignGoalProgress-barFill\" ng-style=\"{width: barFillWidth + '%'}\" ng-class=\"{'campaignGoalProgress-barFill--ended': campaignIsNotPublished}\"></div>\n  </div>\n  <div class=\"campaignGoalProgress-details\">\n    <div class=\"campaignGoalProgress-detailsGoal\">\n      <div ng-bind-html=\"detailsGoalHtml\" gogo-test=\"percent_funded\"></div>\n      <div gogo-test=\"funding_type\" igg-popover=\"\" text=\"{{detailsGoalType}}\" placement=\"top\">{{campaignGoal.fundingBlurb()}}</div>\n    </div>\n    <div class=\"campaignGoalProgress-detailsTimeLeft\" gogo-test=\"time_left\" ng-hide=\"campaignIsNotPublished\">\n      <div ng-bind-html=\"detailsTimeLeftHtml\"></div>\n    </div>\n  </div>\n</div>\n";

/***/ },

/***/ 1370:
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	
	campaignPerks.$inject = ["browser", "i18n", "gogoEvents", "campaignPerksService"];
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	exports.default = campaignPerks;
	
	__webpack_require__(1371);
	
	/*@ngInject*/
	function campaignPerks(browser, i18n, gogoEvents, campaignPerksService) {
	  return {
	    restrict: 'EA',
	    scope: {},
	    template: __webpack_require__(1373),
	    link: function link(scope) {
	      scope.gogoTestLabel = function () {
	        return browser.isMobile() ? 'mobile_perk' : 'perk';
	      };
	      scope.gogoTestContainerLabel = function () {
	        return browser.isMobile() ? 'mobile_perks' : 'perks';
	      };
	
	      campaignPerksService.fetchPerks().then(function () {
	        if (campaignPerksService.hasSecretPerk) {
	          // TODO EVENTS: id=aim2g fixtype=none category=Campaign.Page action=View.load.with.Secret.Perk name=campaign_page_view_load_with_secret_perk subsystem=campaign-page . review
	          gogoEvents.track({
	            thetaName: 'campaign_page_view_load_with_secret_perk',
	            gaEventCategory: 'Campaign Page',
	            gaEventAction: 'View load with Secret Perk'
	          });
	        }
	      });
	
	      scope.perksService = campaignPerksService;
	      scope.perksTitle = i18n.t('perks');
	
	      var showSecretPerkMessage = true;
	      scope.shouldShowSecretPerkMessage = function () {
	        return !!campaignPerksService.secretPerkMessage() && showSecretPerkMessage;
	      };
	      scope.hideSecretPerkMessage = function () {
	        return showSecretPerkMessage = false;
	      };
	    }
	  };
	}

/***/ },

/***/ 1371:
/***/ function(module, exports, __webpack_require__) {

	// style-loader: Adds some css to the DOM by adding a <style> tag
	
	// load the styles
	var content = __webpack_require__(1372);
	if(typeof content === 'string') content = [[module.id, content, '']];
	// add the styles to the DOM
	var update = __webpack_require__(80)(content, {});
	if(content.locals) module.exports = content.locals;
	// Hot Module Replacement
	if(false) {
		// When the styles change, update the <style> tags
		if(!content.locals) {
			module.hot.accept("!!./../node_modules/css-loader/index.js!./../node_modules/less-loader/index.js!./campaign-perks.less", function() {
				var newContent = require("!!./../node_modules/css-loader/index.js!./../node_modules/less-loader/index.js!./campaign-perks.less");
				if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];
				update(newContent);
			});
		}
		// When the module is disposed, remove the <style> tags
		module.hot.dispose(function() { update(); });
	}

/***/ },

/***/ 1372:
/***/ function(module, exports, __webpack_require__) {

	exports = module.exports = __webpack_require__(79)();
	// imports
	
	
	// module
	exports.push([module.id, "/* Antenna Font Family Variations */\n/* Benton Font Family Variations */\n/** Perk Store mobile header text **/\n/** Only mobile campaign/contributions **/\n/* We can define top-left-dimple or left-top-dimple etc as necessary */\n.raised-sizing {\n  font-family: \"Benton Sans\", \"Helvetica\", \"sans-serif\";\n  font-size: 12px;\n  font-weight: normal;\n  line-height: 18px;\n}\n@media (min-width: 1002px) {\n  .raised-sizing {\n    font-family: \"Benton Sans\", \"Helvetica\", \"sans-serif\";\n    font-size: 16px;\n    font-weight: normal;\n    line-height: 26px;\n    letter-spacing: 0;\n    line-height: 25px;\n  }\n}\n.amount-sizing {\n  font-family: \"Benton Sans\", \"Helvetica\", \"sans-serif\";\n  font-weight: bold;\n  font-size: 14px;\n  line-height: 20px;\n}\n@media (min-width: 1002px) {\n  .amount-sizing {\n    font-family: \"Benton Sans\", \"Helvetica\", \"sans-serif\";\n    font-size: 20px;\n    font-weight: bold;\n    line-height: 26px;\n  }\n}\n@media (min-width: 1002px) {\n  .video-heights-for-2-columns {\n    height: 415px;\n  }\n}\n@media (min-width: 1280px) {\n  .video-heights-for-2-columns {\n    height: 460px !important;\n  }\n}\n.body-section-header-text-sizing {\n  font-family: \"Benton Sans\", \"Helvetica\", \"sans-serif\";\n  font-size: 14px;\n  font-weight: normal;\n  line-height: 20px;\n}\n@media (min-width: 1280px) {\n  .body-section-header-text-sizing {\n    font-family: \"Benton Sans\", \"Helvetica\", \"sans-serif\";\n    font-size: 16px;\n    font-weight: normal;\n    line-height: 26px;\n    letter-spacing: 0;\n  }\n}\n.body-sub-section-header-title {\n  font-family: \"Benton Sans\", \"Helvetica\", \"sans-serif\";\n  font-size: 14px;\n  font-weight: normal;\n  line-height: 20px;\n  color: #a8a8a8;\n  margin-top: 20px;\n  margin-bottom: 20px;\n  padding-top: 5px;\n  padding-bottom: 5px;\n  text-transform: uppercase;\n  border-bottom: 1px solid #dddddd;\n}\n@media (min-width: 1280px) {\n  .body-sub-section-header-title {\n    font-family: \"Benton Sans\", \"Helvetica\", \"sans-serif\";\n    font-size: 16px;\n    font-weight: normal;\n    line-height: 26px;\n    letter-spacing: 0;\n  }\n}\n@media not all and (min-width: 768px) {\n  .body-sub-section-header-title {\n    margin-left: 20px;\n    margin-right: 20px;\n  }\n}\n.campaignPerks-title {\n  font-family: \"Benton Sans\", \"Helvetica\", \"sans-serif\";\n  font-size: 14px;\n  font-weight: normal;\n  line-height: 20px;\n  color: #a8a8a8;\n  margin-top: 20px;\n  margin-bottom: 20px;\n  padding-top: 5px;\n  padding-bottom: 5px;\n  text-transform: uppercase;\n  border-bottom: 1px solid #dddddd;\n}\n@media (min-width: 1280px) {\n  .campaignPerks-title {\n    font-family: \"Benton Sans\", \"Helvetica\", \"sans-serif\";\n    font-size: 16px;\n    font-weight: normal;\n    line-height: 26px;\n    letter-spacing: 0;\n  }\n}\n@media not all and (min-width: 768px) {\n  .campaignPerks-title {\n    margin-left: 20px;\n    margin-right: 20px;\n  }\n}\nperk {\n  /* Legacy Perks { */\n  /* } */\n}\nperk .perksLabel {\n  /* Legacy Perks*/\n  display: none;\n}\n@media (max-width: 768px) {\n  perk .perksLabel {\n    display: block;\n    font-family: \"Benton Sans Medium\", \"Helvetica\", \"sans-serif\";\n    font-size: 16px;\n    line-height: 26px;\n    font-weight: normal;\n    letter-spacing: 0;\n    border-bottom: 1px solid #dddddd;\n    padding: 5px 20px;\n    color: #a8a8a8;\n    text-transform: uppercase;\n  }\n}\nperk .perkItem {\n  /* Legacy Perks */\n  background-color: #ffffff;\n  position: relative;\n  width: 100%;\n}\n@media (min-width: 768px) {\n  perk .perkItem {\n    border: 1px solid #dddddd;\n  }\n}\nperk .perkItem-campaignPerkContainer {\n  padding-bottom: 10px;\n}\n@media (min-width: 768px) {\n  perk .perkItem-campaignPerkContainer:hover .perkItem {\n    cursor: pointer;\n    background-color: rgba(245, 245, 245, 0.7);\n  }\n  perk .perkItem-campaignPerkContainer:hover perk-share-banner {\n    display: block;\n  }\n}\n@media (max-width: 767px) {\n  perk .perkItem.open .i-toggle-caret {\n    -webkit-transform: rotate(-180deg);\n    -ms-transform: rotate(-180deg);\n    transform: rotate(-180deg);\n  }\n}\nperk .perkItem .i-soldout-mask {\n  cursor: auto;\n}\nperk .perkItem .i-soldout-mask .i-text {\n  font-family: \"Benton Sans Black\", \"Helvetica\", \"sans-serif\";\n  font-size: 24px;\n  line-height: 34px;\n}\nperk .perkItem-contributewrap {\n  padding: 20px;\n}\n@media (max-width: 1001px) {\n  perk .perkItem-topPerk {\n    text-transform: uppercase;\n  }\n}\nperk .perkItem-topPerk {\n  font-family: \"Benton Sans\", \"Helvetica\", \"sans-serif\";\n  font-weight: bold;\n  font-size: 14px;\n  line-height: 20px;\n  color: #eb1478;\n  margin-bottom: 5px;\n}\nperk .perkItem-retailAmount {\n  text-decoration: line-through;\n}\nperk .perkItem-title {\n  font-family: \"Benton Sans\", \"Helvetica\", \"sans-serif\";\n  font-size: 16px;\n  font-weight: bold;\n  line-height: 26px;\n  letter-spacing: 0;\n  margin-top: 10px;\n}\nperk .perkItem-description {\n  margin-bottom: 10px;\n  word-wrap: break-word;\n}\nperk .perkItem-getThisPerkButtonWrapper {\n  display: table-cell;\n  display: box;\n  display: -webkit-flex;\n  display: -moz-flex;\n  display: -ms-flexbox;\n  display: -ms-flex;\n  display: flex;\n}\nperk .perkItem-getThisPerkButton {\n  font-family: \"Benton Sans\", \"Helvetica\", \"sans-serif\";\n  font-weight: bold;\n  font-size: 14px;\n  line-height: 20px;\n  padding: 10px 45px;\n  margin: 15px auto 0;\n}\nperk .perkItem-getThisPerkButton:hover {\n  background-color: #eb1478;\n}\nperk .perkItem-selectNoPerk {\n  margin: 0 10px;\n}\nperk .perkItem-perkAmount {\n  font-family: \"Benton Sans Black\", \"Helvetica\", \"sans-serif\";\n  font-size: 24px;\n  line-height: 34px;\n  margin-top: 10px;\n}\nperk .perkItem-discount {\n  color: #eb1478;\n}\n@media (max-width: 767px) {\n  perk .perkImage {\n    width: 100%;\n    height: 100%;\n  }\n}\nperk .perkImageWrapper {\n  position: relative;\n}\nperk .perkImageOverlay {\n  position: absolute;\n  background-color: rgba(42, 42, 42, 0.05);\n  top: 0;\n  bottom: 0;\n  left: 0;\n  right: 0;\n}\nperk .shipsTo-label,\nperk .perkItem-lineItem-label {\n  font-family: \"Benton Sans\", \"Helvetica\", \"sans-serif\";\n  font-size: 12px;\n  font-weight: bold;\n  line-height: 18px;\n}\nperk .shipsTo-value,\nperk .perkItem-lineItem-value {\n  font-family: \"Benton Sans\", \"Helvetica\", \"sans-serif\";\n  font-size: 12px;\n  font-weight: normal;\n  line-height: 18px;\n}\nperk .campaignPage-bannerFold {\n  border-style: solid;\n  border-width: 10px 10px 0 0;\n  border-color: #0C8385 transparent transparent transparent;\n  right: 6px;\n  position: absolute;\n}\nperk .secretPerk-banner {\n  text-align: center;\n  padding-top: 15px;\n}\n@media (min-width: 768px) {\n  perk .secretPerk-banner {\n    background-color: #0eb4b6;\n    color: #ffffff;\n    min-width: auto;\n    height: auto;\n    position: absolute;\n    right: -10px;\n    margin-top: -30px;\n    z-index: 81;\n    padding: 0;\n  }\n  perk .secretPerk-banner-soldOut {\n    background-color: #B0E0E0;\n    pointer-events: none;\n    cursor: default;\n  }\n}\n@media (min-width: 768px) {\n  perk .secretPerk-bannerFold {\n    border-style: solid;\n    border-width: 10px 10px 0 0;\n    border-color: #0C8385 transparent transparent transparent;\n    right: 6px;\n    position: absolute;\n    right: 0;\n  }\n  perk .secretPerk-bannerFold-soldOut {\n    border-color: #9ECACB transparent transparent transparent;\n    cursor: default;\n  }\n}\nperk .secretPerk-bannerText {\n  font-family: \"Benton Sans Medium\", \"Helvetica\", \"sans-serif\";\n  font-size: 12px;\n  line-height: 18px;\n  font-weight: normal;\n  letter-spacing: 0;\n  padding: 10px 20px 10px 5px;\n  vertical-align: middle;\n  color: #0eb4b6;\n}\n@media (min-width: 768px) {\n  perk .secretPerk-bannerText {\n    font-family: \"Benton Sans Medium\", \"Helvetica\", \"sans-serif\";\n    font-size: 12px;\n    line-height: 18px;\n    font-weight: normal;\n    letter-spacing: 0;\n    padding: 10px 20px 10px 5px;\n    vertical-align: middle;\n    color: #ffffff;\n  }\n}\nperk .secretPerk-shades svg {\n  width: 40px;\n  height: 30px;\n  vertical-align: middle;\n  fill: #0eb4b6;\n  padding-left: 10px;\n}\n@media (min-width: 768px) {\n  perk .secretPerk-shades svg {\n    width: 40px;\n    height: 30px;\n    vertical-align: middle;\n    fill: #ffffff;\n    padding-left: 10px;\n  }\n}\n.secretPerk-hidden {\n  padding: 20px;\n  background-color: #FFEAB9;\n  font-family: \"Benton Sans\", \"Helvetica\", \"sans-serif\";\n  font-size: 12px;\n  font-weight: normal;\n  line-height: 18px;\n  position: relative;\n}\n.secretPerk-hidden .secretPerk-hidden-close svg {\n  width: 15px;\n  height: 15px;\n  position: absolute;\n  top: 8px;\n  right: 8px;\n  cursor: pointer;\n}\n.secretPerk-hidden .secretPerk-hidden-close svg:hover {\n  fill: #eb1478;\n}\n", ""]);
	
	// exports


/***/ },

/***/ 1373:
/***/ function(module, exports) {

	module.exports = "<div ng-if=\"perksService.perks.length > 0\" class=\"campaignPerks\" gogo-test=\"{{gogoTestContainerLabel()}}\">\n  <div class=\"campaignPerks-title\">{{::perksTitle}}</div>\n  <div class=\"secretPerk-hidden am-collapse\" ng-if=\"shouldShowSecretPerkMessage()\" gogo-test=\"secret_perk\">\n    <span>{{ perksService.secretPerkMessage() }}</span>\n    <svg-icon icon=\"icon-icon-close\" class=\"secretPerk-hidden-close\" ng-click=\"hideSecretPerkMessage()\"></svg-icon>\n  </div>\n  <campaign-next-perk ng-repeat=\"perk in perksService.perks\"\n                      perk=\"perk\"\n                      gogo-test=\"{{gogoTestLabel()}}_{{$index}}\">\n  </campaign-next-perk>\n</div>\n";

/***/ },

/***/ 1374:
/***/ function(module, exports, __webpack_require__) {

	"use strict";
	
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	
	var _privateApi = __webpack_require__(186);
	
	function perkService($window, $http, gon, perkFactory, browser, campaign, i18n) {
	  var Perk = perkFactory;
	  var service = { hasSecretPerk: false };
	
	  var secretPerkToken = function () {
	    var searchParams = $window.location.search;
	    if (searchParams) {
	      var i = void 0,
	          val = void 0,
	          params = searchParams.substring(1).split("&");
	      for (i = 0; i < params.length; i++) {
	        val = params[i].split("=");
	        if (val[0] == 'secret_perk_token') {
	          return val[1];
	        }
	      }
	    }
	  }();
	
	  var setThePerks = function setThePerks(perks) {
	    var collapsible = browser.isMobile();
	    var processedPerks = _.map(perks, function (perkAttrs) {
	      return new Perk(_.merge(perkAttrs, { collapsible: collapsible }), { createDropdownCountryObjects: false });
	    });
	    if (processedPerks[0]) {
	      processedPerks[0].expanded = true;
	      service.hasSecretPerk = !!processedPerks[0].secret;
	    }
	    service.perks = processedPerks;
	  };
	
	  setThePerks(campaign.perks);
	
	  var secretPerkStatus = gon.secret_perk_status;
	
	  service.secretPerkMessage = function () {
	    return {
	      hidden: i18n.t('secret_perk.hidden'),
	      unavailable: i18n.t('secret_perk.unavailable')
	    }[secretPerkStatus];
	  };
	
	  var fetchPromise = void 0;
	  service.fetchPerks = function () {
	    var secretPerkParam = secretPerkToken ? '?secret_perk_token=' + secretPerkToken : '';
	    if (!fetchPromise) {
	      fetchPromise = $http.get((0, _privateApi.privateApiCampaignPerksPath)({ campaignId: campaign.id }) + secretPerkParam).then(function (response) {
	        secretPerkStatus = response.data.secret_perk_status;
	        setThePerks(response.data.response);
	      });
	    }
	    return fetchPromise;
	  };
	
	  return service;
	} /* @ngInject */
	
	exports.default = perkService;

/***/ },

/***/ 1375:
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	
	indemandProgress.$inject = ["$filter", "campaign", "i18n"];
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	
	__webpack_require__(1376);
	
	/*@ngInject*/
	function indemandProgress($filter, campaign, i18n) {
	  return {
	    restrict: 'E',
	    scope: {},
	    template: __webpack_require__(1378),
	    link: function link(scope) {
	      scope.currencyCode = campaign.currency.iso_code;
	      scope.fundingDate = fundingDate();
	      scope.i18n = i18n;
	      scope.percentFunded = percentFundedText();
	      scope.raisedAmount = raisedAmount();
	
	      function percentFundedText() {
	        return Math.round(percentFunded()) + "%";
	      }
	
	      function raisedAmount() {
	        return showAsCurrency(campaign.forever_funding_combined_balance);
	      }
	
	      function percentFunded() {
	        if (campaign.is_external_campaign) {
	          return campaign.external_campaign_info.percentage_raised;
	        } else if (campaign.goal === 0) {
	          return 0;
	        } else {
	          return campaign.collected_funds / campaign.goal * 100;
	        }
	      }
	
	      function showAsCurrency(amount) {
	        return $filter('iggCurrency')(amount, campaign.currency.iso_num, 'noIso');
	      }
	
	      function fundingDate() {
	        return $filter('date')(campaign.funding_ends_at, 'MMMM d, yyyy');
	      }
	    }
	  };
	}
	exports.default = indemandProgress;

/***/ },

/***/ 1376:
/***/ function(module, exports, __webpack_require__) {

	// style-loader: Adds some css to the DOM by adding a <style> tag
	
	// load the styles
	var content = __webpack_require__(1377);
	if(typeof content === 'string') content = [[module.id, content, '']];
	// add the styles to the DOM
	var update = __webpack_require__(80)(content, {});
	if(content.locals) module.exports = content.locals;
	// Hot Module Replacement
	if(false) {
		// When the styles change, update the <style> tags
		if(!content.locals) {
			module.hot.accept("!!./../node_modules/css-loader/index.js!./../node_modules/less-loader/index.js!./indemand-progress.less", function() {
				var newContent = require("!!./../node_modules/css-loader/index.js!./../node_modules/less-loader/index.js!./indemand-progress.less");
				if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];
				update(newContent);
			});
		}
		// When the module is disposed, remove the <style> tags
		module.hot.dispose(function() { update(); });
	}

/***/ },

/***/ 1377:
/***/ function(module, exports, __webpack_require__) {

	exports = module.exports = __webpack_require__(79)();
	// imports
	
	
	// module
	exports.push([module.id, "/* Antenna Font Family Variations */\n/* Benton Font Family Variations */\n/** Perk Store mobile header text **/\n/** Only mobile campaign/contributions **/\n/* We can define top-left-dimple or left-top-dimple etc as necessary */\n.raised-sizing {\n  font-family: \"Benton Sans\", \"Helvetica\", \"sans-serif\";\n  font-size: 12px;\n  font-weight: normal;\n  line-height: 18px;\n}\n@media (min-width: 1002px) {\n  .raised-sizing {\n    font-family: \"Benton Sans\", \"Helvetica\", \"sans-serif\";\n    font-size: 16px;\n    font-weight: normal;\n    line-height: 26px;\n    letter-spacing: 0;\n    line-height: 25px;\n  }\n}\n.amount-sizing {\n  font-family: \"Benton Sans\", \"Helvetica\", \"sans-serif\";\n  font-weight: bold;\n  font-size: 14px;\n  line-height: 20px;\n}\n@media (min-width: 1002px) {\n  .amount-sizing {\n    font-family: \"Benton Sans\", \"Helvetica\", \"sans-serif\";\n    font-size: 20px;\n    font-weight: bold;\n    line-height: 26px;\n  }\n}\n@media (min-width: 1002px) {\n  .video-heights-for-2-columns {\n    height: 415px;\n  }\n}\n@media (min-width: 1280px) {\n  .video-heights-for-2-columns {\n    height: 460px !important;\n  }\n}\n.indemandProgress {\n  color: #2a2a2a;\n}\n.indemandProgress em {\n  font-family: \"Benton Sans Medium\", \"Helvetica\", \"sans-serif\";\n}\n.indemandProgress-raised {\n  font-family: \"Benton Sans\", \"Helvetica\", \"sans-serif\";\n  font-size: 12px;\n  font-weight: normal;\n  line-height: 18px;\n}\n@media (min-width: 1002px) {\n  .indemandProgress-raised {\n    font-family: \"Benton Sans\", \"Helvetica\", \"sans-serif\";\n    font-size: 16px;\n    font-weight: normal;\n    line-height: 26px;\n    letter-spacing: 0;\n    line-height: 25px;\n  }\n}\n.indemandProgress-raisedAmount {\n  font-family: \"Benton Sans\", \"Helvetica\", \"sans-serif\";\n  font-weight: bold;\n  font-size: 14px;\n  line-height: 20px;\n}\n@media (min-width: 1002px) {\n  .indemandProgress-raisedAmount {\n    font-family: \"Benton Sans\", \"Helvetica\", \"sans-serif\";\n    font-size: 20px;\n    font-weight: bold;\n    line-height: 26px;\n  }\n}\n.indemandProgress-history {\n  display: flex;\n}\n.indemandProgress-historyDetails {\n  font-family: \"Benton Sans\", \"Helvetica\", \"sans-serif\";\n  font-size: 12px;\n  font-weight: normal;\n  line-height: 18px;\n}\n@media (min-width: 1002px) {\n  .indemandProgress-historyDetails {\n    font-family: \"Benton Sans\", \"Helvetica\", \"sans-serif\";\n    font-size: 14px;\n    font-weight: normal;\n    line-height: 20px;\n  }\n}\n", ""]);
	
	// exports


/***/ },

/***/ 1378:
/***/ function(module, exports) {

	module.exports = "<div class=\"indemandProgress\">\n  <div class=\"indemandProgress-raised\">\n    <span class=\"indemandProgress-raisedAmount\" gogo-test=\"raised\">{{::raisedAmount}}</span> {{::currencyCode}} <span>{{::i18n.t('total_funds_raised')}}</span>\n  </div>\n  <div class=\"indemandProgress-history\">\n    <div class=\"indemandProgress-historyDetails\">\n      <span gogo-test=\"percent_funded\">\n        <em>{{percentFunded}}</em>\n      </span>\n      {{::i18n.t('funded_on')}}\n      <span gogo-test=\"funding_date\">\n        {{::fundingDate}}\n      </span>\n    </div>\n    <div class=\"indemandProgress-historyPopover\">\n      <indemand-campaign-history-popover></indemand-campaign-history-popover>\n    </div>\n  </div>\n</div>\n";

/***/ },

/***/ 1379:
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	
	indemandCampaignHistoryPopover.$inject = ["$filter", "campaign", "i18n", "$popover"];
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	
	__webpack_require__(1380);
	
	/*@ngInject*/
	function indemandCampaignHistoryPopover($filter, campaign, i18n, $popover) {
	  return {
	    restrict: 'E',
	    scope: {},
	    template: __webpack_require__(1382),
	    link: function link(scope, element) {
	
	      scope.popoverContent = null;
	
	      scope.$watch(function () {
	        return campaign;
	      }, function () {
	        if (!campaign.is_external_campaign) {
	          return;
	        }
	        scope.popoverContent = i18n.t('funders_originally_pledged_on_another_platform', {
	          funders: campaign.external_campaign_info.number_of_funders,
	          funds_raised: $filter('iggCurrency')(campaign.external_campaign_info.funds_raised, campaign.currency.iso_num)
	        });
	      });
	    }
	  };
	}
	exports.default = indemandCampaignHistoryPopover;

/***/ },

/***/ 1380:
/***/ function(module, exports, __webpack_require__) {

	// style-loader: Adds some css to the DOM by adding a <style> tag
	
	// load the styles
	var content = __webpack_require__(1381);
	if(typeof content === 'string') content = [[module.id, content, '']];
	// add the styles to the DOM
	var update = __webpack_require__(80)(content, {});
	if(content.locals) module.exports = content.locals;
	// Hot Module Replacement
	if(false) {
		// When the styles change, update the <style> tags
		if(!content.locals) {
			module.hot.accept("!!./../node_modules/css-loader/index.js!./../node_modules/less-loader/index.js!./indemand-campaign-history-popover.less", function() {
				var newContent = require("!!./../node_modules/css-loader/index.js!./../node_modules/less-loader/index.js!./indemand-campaign-history-popover.less");
				if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];
				update(newContent);
			});
		}
		// When the module is disposed, remove the <style> tags
		module.hot.dispose(function() { update(); });
	}

/***/ },

/***/ 1381:
/***/ function(module, exports, __webpack_require__) {

	exports = module.exports = __webpack_require__(79)();
	// imports
	
	
	// module
	exports.push([module.id, "/* Antenna Font Family Variations */\n/* Benton Font Family Variations */\n/** Perk Store mobile header text **/\n/** Only mobile campaign/contributions **/\n/* We can define top-left-dimple or left-top-dimple etc as necessary */\n.indemandCampaignHistoryPopover {\n  display: inline-block;\n  margin-left: 5px;\n}\n", ""]);
	
	// exports


/***/ },

/***/ 1382:
/***/ function(module, exports) {

	module.exports = "<div class=\"indemandCampaignHistoryPopover\" id=\"indemandCampaignHistoryPopover\" ng-if=\"popoverContent\" igg-popover placement=\"top\">\n  {{popoverContent}}\n</div>\n";

/***/ },

/***/ 1383:
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	
	reportThisCampaign.$inject = ["$window", "campaign", "i18n", "$sce"];
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	
	__webpack_require__(1384);
	
	/*@ngInject*/
	function reportThisCampaign($window, campaign, i18n, $sce) {
	  return {
	    restrict: 'E',
	    scope: {},
	    template: __webpack_require__(1386),
	    link: function link(scope) {
	      scope.i18n = i18n;
	      scope.description = description();
	
	      function description() {
	        var html = i18n.t('campaign_page_next.trust.prohibited_blurb', {
	          let_us_know_url: reportLink(),
	          contains_prohibited_content_url: termsLink()
	        });
	        return $sce.trustAsHtml(html);
	      }
	
	      function reportLink() {
	        return 'https://support.indiegogo.com/hc/en-us/requests/new?ticket_form_id=68803&subject=' + i18n.t('prohibited_content') + '&campaign=' + campaign.id + '&description=' + $window.location;
	      }
	
	      function termsLink() {
	        return 'https://www.indiegogo.com/about/terms';
	      }
	    }
	  };
	}
	exports.default = reportThisCampaign;

/***/ },

/***/ 1384:
/***/ function(module, exports, __webpack_require__) {

	// style-loader: Adds some css to the DOM by adding a <style> tag
	
	// load the styles
	var content = __webpack_require__(1385);
	if(typeof content === 'string') content = [[module.id, content, '']];
	// add the styles to the DOM
	var update = __webpack_require__(80)(content, {});
	if(content.locals) module.exports = content.locals;
	// Hot Module Replacement
	if(false) {
		// When the styles change, update the <style> tags
		if(!content.locals) {
			module.hot.accept("!!./../node_modules/css-loader/index.js!./../node_modules/less-loader/index.js!./report-this-campaign.less", function() {
				var newContent = require("!!./../node_modules/css-loader/index.js!./../node_modules/less-loader/index.js!./report-this-campaign.less");
				if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];
				update(newContent);
			});
		}
		// When the module is disposed, remove the <style> tags
		module.hot.dispose(function() { update(); });
	}

/***/ },

/***/ 1385:
/***/ function(module, exports, __webpack_require__) {

	exports = module.exports = __webpack_require__(79)();
	// imports
	
	
	// module
	exports.push([module.id, "/* Antenna Font Family Variations */\n/* Benton Font Family Variations */\n/** Perk Store mobile header text **/\n/** Only mobile campaign/contributions **/\n/* We can define top-left-dimple or left-top-dimple etc as necessary */\n.reportThisCampaign {\n  background-color: #dddddd;\n  margin-bottom: 15px;\n  padding: 10px 15px;\n}\n@media (min-width: 1002px) {\n  .reportThisCampaign {\n    display: box;\n    display: -webkit-flex;\n    display: -moz-flex;\n    display: -ms-flexbox;\n    display: -ms-flex;\n    display: flex;\n  }\n}\n.reportThisCampaign-content {\n  box-flex: 3;\n  -webkit-flex: 3;\n  -moz-flex: 3;\n  -ms-flex: 3;\n  flex: 3;\n}\n.reportThisCampaign-content-description {\n  font-family: \"Benton Sans\", \"Helvetica\", \"sans-serif\";\n  font-size: 14px;\n  font-weight: normal;\n  line-height: 20px;\n}\n.reportThisCampaign-content-description a {\n  cursor: pointer;\n}\n", ""]);
	
	// exports


/***/ },

/***/ 1386:
/***/ function(module, exports) {

	module.exports = "<div class=\"reportThisCampaign\"\n     analytics-on=\"scrollby\"\n     scrollby-offset=\"50%\"\n     analytics-name=\"campaign/report-campaign.scroll\"\n     analytics-category=\"campaign_page_scroll\"\n     analytics-event=\"report-campaign\">\n  <div class=\"reportThisCampaign-content\">\n    <div class=\"reportThisCampaign-content-description\" ng-bind-html=\"description\"></div>\n  </div>\n</div>\n";

/***/ },

/***/ 1387:
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	
	campaignStoryLink.$inject = ["campaignModalService", "i18n", "campaignAnalyticsService"];
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	exports.default = campaignStoryLink;
	
	__webpack_require__(1388);
	
	/*@ngInject*/
	function campaignStoryLink(campaignModalService, i18n, campaignAnalyticsService) {
	  return {
	    restrict: 'E',
	    scope: {},
	    template: __webpack_require__(1390),
	    link: function link(scope) {
	      scope.i18n = i18n;
	      scope.showModal = showModal;
	      scope.campaignCategory = campaignAnalyticsService.defaultAnalyticsAttrs().projectCategory;
	      scope.campaignType = campaignAnalyticsService.campaignType();
	
	      function showModal() {
	        campaignModalService.createModal({
	          scope: scope,
	          title: i18n.t('story'),
	          showBackItOnMobile: true,
	          content: '<campaign-description></campaign-description>'
	        });
	        campaignModalService.showModal();
	      }
	    }
	  };
	}

/***/ },

/***/ 1388:
/***/ function(module, exports, __webpack_require__) {

	// style-loader: Adds some css to the DOM by adding a <style> tag
	
	// load the styles
	var content = __webpack_require__(1389);
	if(typeof content === 'string') content = [[module.id, content, '']];
	// add the styles to the DOM
	var update = __webpack_require__(80)(content, {});
	if(content.locals) module.exports = content.locals;
	// Hot Module Replacement
	if(false) {
		// When the styles change, update the <style> tags
		if(!content.locals) {
			module.hot.accept("!!./../node_modules/css-loader/index.js!./../node_modules/less-loader/index.js!./campaign-story-link.less", function() {
				var newContent = require("!!./../node_modules/css-loader/index.js!./../node_modules/less-loader/index.js!./campaign-story-link.less");
				if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];
				update(newContent);
			});
		}
		// When the module is disposed, remove the <style> tags
		module.hot.dispose(function() { update(); });
	}

/***/ },

/***/ 1389:
/***/ function(module, exports, __webpack_require__) {

	exports = module.exports = __webpack_require__(79)();
	// imports
	
	
	// module
	exports.push([module.id, "/* Antenna Font Family Variations */\n/* Benton Font Family Variations */\n/** Perk Store mobile header text **/\n/** Only mobile campaign/contributions **/\n/* We can define top-left-dimple or left-top-dimple etc as necessary */\n.campaignStoryLink {\n  display: box;\n  display: -webkit-flex;\n  display: -moz-flex;\n  display: -ms-flexbox;\n  display: -ms-flex;\n  display: flex;\n  box-pack: center;\n  -ms-flex-pack: center;\n  -webkit-justify-content: center;\n  -moz-justify-content: center;\n  -ms-justify-content: center;\n  justify-content: center;\n  box-align: center;\n  -ms-flex-align: center;\n  -webkit-align-items: center;\n  -moz-align-items: center;\n  -ms-align-items: center;\n  align-items: center;\n  -ms-flex-line-pack: center;\n  -webkit-align-content: center;\n  -moz-align-content: center;\n  -ms-align-content: center;\n  align-content: center;\n  font-family: \"Benton Sans Medium\", \"Helvetica\", \"sans-serif\";\n  font-size: 14px;\n  line-height: 20px;\n  height: 32px;\n  border-top: 1px solid #dddddd;\n  border-bottom: 1px solid #dddddd;\n  text-transform: uppercase;\n  color: #eb1478;\n}\n", ""]);
	
	// exports


/***/ },

/***/ 1390:
/***/ function(module, exports) {

	module.exports = "<div class=\"campaignStoryLink\">\n  <div ng-click=\"showModal()\"\n       gogo-test=\"read_story\"\n       analytics-on=\"click\"\n       analytics-name=\"mobile_view_story\"\n       analytics-category=\"campaign_page_contribute \"\n       analytics-event=\"campaign/mobile_view_story.link\"\n       analytics-label=\"{{campaignType}}_{{campaignCategory}}\">\n    {{::i18n.t('read_the_story')}}</div>\n</div>\n";

/***/ },

/***/ 1391:
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	exports.default = campaignModal;
	
	__webpack_require__(1392);
	
	/*@ngInject*/
	function campaignModal() {
	  return {
	    restrict: 'E',
	    scope: {},
	    transclude: true,
	    template: "<div ng-transclude class='campaignModal'></div>"
	  };
	}

/***/ },

/***/ 1392:
/***/ function(module, exports, __webpack_require__) {

	// style-loader: Adds some css to the DOM by adding a <style> tag
	
	// load the styles
	var content = __webpack_require__(1393);
	if(typeof content === 'string') content = [[module.id, content, '']];
	// add the styles to the DOM
	var update = __webpack_require__(80)(content, {});
	if(content.locals) module.exports = content.locals;
	// Hot Module Replacement
	if(false) {
		// When the styles change, update the <style> tags
		if(!content.locals) {
			module.hot.accept("!!./../../node_modules/css-loader/index.js!./../../node_modules/less-loader/index.js!./campaign-modal.less", function() {
				var newContent = require("!!./../../node_modules/css-loader/index.js!./../../node_modules/less-loader/index.js!./campaign-modal.less");
				if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];
				update(newContent);
			});
		}
		// When the module is disposed, remove the <style> tags
		module.hot.dispose(function() { update(); });
	}

/***/ },

/***/ 1393:
/***/ function(module, exports, __webpack_require__) {

	exports = module.exports = __webpack_require__(79)();
	// imports
	
	
	// module
	exports.push([module.id, "/* Antenna Font Family Variations */\n/* Benton Font Family Variations */\n/** Perk Store mobile header text **/\n/** Only mobile campaign/contributions **/\n/* We can define top-left-dimple or left-top-dimple etc as necessary */\n.campaignModal-mobile {\n  display: none;\n}\n@media not all and (min-width: 768px) {\n  .campaignModal-mobile {\n    display: block;\n    background-color: #ffffff;\n    width: 100%;\n    height: 100%;\n    overflow: auto;\n    -webkit-overflow-scrolling: touch;\n    padding: 60px 10px 60px 10px;\n  }\n}\n.campaignModal-actions {\n  display: none;\n}\n@media (max-width: 767px) {\n  .campaignModal-actions {\n    display: block;\n    width: 100%;\n    height: 50px;\n    bottom: 0;\n    left: 0;\n    position: absolute;\n    background-color: #ffffff;\n    box-shadow: 0 0 3px 1px rgba(0, 0, 0, 0.1);\n    z-index: 1050;\n  }\n  .campaignModal-actions .campaignActions {\n    margin-top: 0;\n    padding: 5px;\n  }\n}\n@media not all and (min-width: 768px) {\n  campaign-modal {\n    width: 100%;\n  }\n  body.modal-open {\n    /* work around for scrolling issue on mobile browsers */\n    position: fixed;\n    width: 100%;\n  }\n  body.modal-open img {\n    max-width: 100% !important;\n  }\n}\n.modal-backdrop.ng-leave-active {\n  opacity: 0;\n  /* make sure backdrop fades correctly */\n}\n", ""]);
	
	// exports


/***/ },

/***/ 1394:
/***/ function(module, exports) {

	'use strict';
	
	campaignModalService.$inject = ["$modal", "browser"];
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	exports.default = campaignModalService;
	/* jshint expr: true */
	/*@ngInject*/
	function campaignModalService($modal, browser) {
	  var service = {
	    scope: null,
	    title: '',
	    content: '',
	    instance: null,
	    createModal: createModal,
	    showModal: showModal,
	    hideModal: hideModal
	  };
	
	  return service;
	
	  function createModal(options) {
	    service.scope = options.scope;
	    if (options.title) service.title = options.title;
	    if (options.content) service.content = options.content;
	    if (browser.isMobile()) {
	      var backItHtml = function backItHtml() {
	        if (options.showBackItOnMobile) {
	          return '<campaign-actions-modal class="campaignModal-actions"></campaign-actions-modal>';
	        } else {
	          return '';
	        }
	      };
	      var template = ['<div class="modal" gogo-test="mobile_modal">', '<campaign-modal class=\'campaignModal-mobile\'>' + service.content + '</campaign-modal>', '<campaign-modal-close title=\'' + service.title + '\'></campaign-modal-close>', backItHtml(), '</div>'].join('');
	      service.instance = $modal({
	        template: template,
	        scope: service.scope,
	        animation: 'am-slide-right',
	        backdrop: false,
	        show: false
	      });
	    } else {
	      service.instance = $modal({
	        template: '<div class=\'modal\'><campaign-modal class=\'campaignModal-desktop\'>' + service.content + '</campaign-modal>',
	        scope: service.scope,
	        animation: 'am-fade',
	        show: false
	      });
	    }
	  }
	
	  function showModal() {
	    return service.instance.$promise.then(function () {
	      service.instance.show();
	    });
	  }
	
	  function hideModal() {
	    return service.instance.$promise.then(function () {
	      service.instance.hide();
	    });
	  }
	}

/***/ },

/***/ 1395:
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	
	campaignModalClose.$inject = ["campaignModalService", "i18n"];
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	exports.default = campaignModalClose;
	
	__webpack_require__(1396);
	
	/*@ngInject*/
	function campaignModalClose(campaignModalService, i18n) {
	  return {
	    restrict: 'E',
	    scope: {
	      title: '@'
	    },
	    template: __webpack_require__(1398),
	    link: function link(scope) {
	      scope.i18n = i18n;
	      scope.closeModal = function () {
	        campaignModalService.hideModal();
	      };
	    }
	  };
	}

/***/ },

/***/ 1396:
/***/ function(module, exports, __webpack_require__) {

	// style-loader: Adds some css to the DOM by adding a <style> tag
	
	// load the styles
	var content = __webpack_require__(1397);
	if(typeof content === 'string') content = [[module.id, content, '']];
	// add the styles to the DOM
	var update = __webpack_require__(80)(content, {});
	if(content.locals) module.exports = content.locals;
	// Hot Module Replacement
	if(false) {
		// When the styles change, update the <style> tags
		if(!content.locals) {
			module.hot.accept("!!./../../node_modules/css-loader/index.js!./../../node_modules/less-loader/index.js!./campaign-modal-close.less", function() {
				var newContent = require("!!./../../node_modules/css-loader/index.js!./../../node_modules/less-loader/index.js!./campaign-modal-close.less");
				if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];
				update(newContent);
			});
		}
		// When the module is disposed, remove the <style> tags
		module.hot.dispose(function() { update(); });
	}

/***/ },

/***/ 1397:
/***/ function(module, exports, __webpack_require__) {

	exports = module.exports = __webpack_require__(79)();
	// imports
	
	
	// module
	exports.push([module.id, "/* Antenna Font Family Variations */\n/* Benton Font Family Variations */\n/** Perk Store mobile header text **/\n/** Only mobile campaign/contributions **/\n/* We can define top-left-dimple or left-top-dimple etc as necessary */\n.campaignModalClose {\n  display: none;\n}\n@media (max-width: 767px) {\n  .campaignModalClose {\n    display: box;\n    display: -webkit-flex;\n    display: -moz-flex;\n    display: -ms-flexbox;\n    display: -ms-flex;\n    display: flex;\n    box-align: center;\n    -ms-flex-align: center;\n    -webkit-align-items: center;\n    -moz-align-items: center;\n    -ms-align-items: center;\n    align-items: center;\n    font-family: \"Benton Sans\", \"Helvetica\", \"sans-serif\";\n    font-size: 16px;\n    font-weight: bold;\n    line-height: 26px;\n    letter-spacing: 0;\n    width: 100%;\n    top: 0;\n    position: absolute;\n    border-bottom: 1px solid #dddddd;\n    z-index: 1050;\n    height: 50px;\n    color: #6a6a6a;\n    background-color: #f5f5f5;\n    line-height: 24px;\n  }\n  .campaignModalClose svg-icon {\n    width: 26px;\n    height: 26px;\n  }\n  .campaignModalClose svg {\n    fill: #6a6a6a;\n    width: 40px;\n    height: 15px;\n  }\n}\n", ""]);
	
	// exports


/***/ },

/***/ 1398:
/***/ function(module, exports) {

	module.exports = "<div class=\"campaignModalClose\" ng-click=\"closeModal()\" gogo-test=\"close_modal\">\n  <a><svg-icon icon=\"left-chevron\"></svg-icon></a>\n  {{::title}}\n</div>\n";

/***/ },

/***/ 1399:
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	
	campaignActions.$inject = ["campaignLayoutService"];
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	exports.default = campaignActions;
	
	__webpack_require__(1400);
	
	/*@ngInject*/
	function campaignActions(campaignLayoutService) {
	  return {
	    restrict: 'E',
	    scope: {},
	    template: __webpack_require__(1402),
	    link: function link(scope) {
	      scope.shouldShowContributeButton = function () {
	        return !campaignLayoutService.isPerkOnlyLayout();
	      };
	    }
	  };
	}

/***/ },

/***/ 1400:
/***/ function(module, exports, __webpack_require__) {

	// style-loader: Adds some css to the DOM by adding a <style> tag
	
	// load the styles
	var content = __webpack_require__(1401);
	if(typeof content === 'string') content = [[module.id, content, '']];
	// add the styles to the DOM
	var update = __webpack_require__(80)(content, {});
	if(content.locals) module.exports = content.locals;
	// Hot Module Replacement
	if(false) {
		// When the styles change, update the <style> tags
		if(!content.locals) {
			module.hot.accept("!!./../node_modules/css-loader/index.js!./../node_modules/less-loader/index.js!./campaign-actions.less", function() {
				var newContent = require("!!./../node_modules/css-loader/index.js!./../node_modules/less-loader/index.js!./campaign-actions.less");
				if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];
				update(newContent);
			});
		}
		// When the module is disposed, remove the <style> tags
		module.hot.dispose(function() { update(); });
	}

/***/ },

/***/ 1401:
/***/ function(module, exports, __webpack_require__) {

	exports = module.exports = __webpack_require__(79)();
	// imports
	
	
	// module
	exports.push([module.id, "/* Antenna Font Family Variations */\n/* Benton Font Family Variations */\n/** Perk Store mobile header text **/\n/** Only mobile campaign/contributions **/\n/* We can define top-left-dimple or left-top-dimple etc as necessary */\n.campaignActions {\n  display: box;\n  display: -webkit-flex;\n  display: -moz-flex;\n  display: -ms-flexbox;\n  display: -ms-flex;\n  display: flex;\n  box-align: center;\n  -ms-flex-align: center;\n  -webkit-align-items: center;\n  -moz-align-items: center;\n  -ms-align-items: center;\n  align-items: center;\n  margin-top: 20px;\n}\n@media not all and (min-width: 768px) {\n  .campaignActions {\n    margin-top: 15px;\n  }\n}\n.campaignActions-contribute {\n  box-flex: 60;\n  -webkit-flex: 60;\n  -moz-flex: 60;\n  -ms-flex: 60;\n  flex: 60;\n  margin-right: 20px;\n}\n@media (min-width: 480px) {\n  .campaignActions-contribute {\n    margin-right: 10px;\n  }\n}\n@media (min-width: 768px) {\n  .campaignActions-contribute {\n    box-flex: 40;\n    -webkit-flex: 40;\n    -moz-flex: 40;\n    -ms-flex: 40;\n    flex: 40;\n    margin-right: 20px;\n  }\n}\n.campaignActions-shareTools {\n  box-flex: 40;\n  -webkit-flex: 40;\n  -moz-flex: 40;\n  -ms-flex: 40;\n  flex: 40;\n}\n@media (min-width: 768px) {\n  .campaignActions-shareTools {\n    box-flex: 60;\n    -webkit-flex: 60;\n    -moz-flex: 60;\n    -ms-flex: 60;\n    flex: 60;\n  }\n}\n", ""]);
	
	// exports


/***/ },

/***/ 1402:
/***/ function(module, exports) {

	module.exports = "<div class=\"campaignActions\">\n  <div class=\"campaignActions-contribute\" ng-if=\"shouldShowContributeButton()\">\n    <campaign-contribute></campaign-contribute>\n  </div>\n  <div class=\"campaignActions-shareTools\">\n    <campaign-share-buttons></campaign-share-buttons>\n  </div>\n</div>\n";

/***/ },

/***/ 1403:
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	
	campaignActionsModal.$inject = ["split", "campaign", "campaignLayoutService"];
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	exports.default = campaignActionsModal;
	
	__webpack_require__(1404);
	
	/*@ngInject*/
	function campaignActionsModal(split, campaign, campaignLayoutService) {
	  return {
	    restrict: 'E',
	    scope: {},
	    transclude: true,
	    template: __webpack_require__(1406),
	    link: function link(scope) {
	      scope.shouldShowBackItCta = function () {
	        return !campaignLayoutService.isPerkOnlyLayout();
	      };
	      scope.showViewPerksCta = function () {
	        return campaign.isPublished() && campaign.perks_available;
	      };
	    }
	  };
	}

/***/ },

/***/ 1404:
/***/ function(module, exports, __webpack_require__) {

	// style-loader: Adds some css to the DOM by adding a <style> tag
	
	// load the styles
	var content = __webpack_require__(1405);
	if(typeof content === 'string') content = [[module.id, content, '']];
	// add the styles to the DOM
	var update = __webpack_require__(80)(content, {});
	if(content.locals) module.exports = content.locals;
	// Hot Module Replacement
	if(false) {
		// When the styles change, update the <style> tags
		if(!content.locals) {
			module.hot.accept("!!./../node_modules/css-loader/index.js!./../node_modules/less-loader/index.js!./campaign-actions-modal.less", function() {
				var newContent = require("!!./../node_modules/css-loader/index.js!./../node_modules/less-loader/index.js!./campaign-actions-modal.less");
				if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];
				update(newContent);
			});
		}
		// When the module is disposed, remove the <style> tags
		module.hot.dispose(function() { update(); });
	}

/***/ },

/***/ 1405:
/***/ function(module, exports, __webpack_require__) {

	exports = module.exports = __webpack_require__(79)();
	// imports
	
	
	// module
	exports.push([module.id, "/* Antenna Font Family Variations */\n/* Benton Font Family Variations */\n/** Perk Store mobile header text **/\n/** Only mobile campaign/contributions **/\n/* We can define top-left-dimple or left-top-dimple etc as necessary */\n.campaignActionsModal {\n  display: box;\n  display: -webkit-flex;\n  display: -moz-flex;\n  display: -ms-flexbox;\n  display: -ms-flex;\n  display: flex;\n  box-align: center;\n  -ms-flex-align: center;\n  -webkit-align-items: center;\n  -moz-align-items: center;\n  -ms-align-items: center;\n  align-items: center;\n  margin-top: 5px;\n  margin-left: 5px;\n}\n.campaignActionsModal-contribute {\n  box-flex: 60;\n  -webkit-flex: 60;\n  -moz-flex: 60;\n  -ms-flex: 60;\n  flex: 60;\n  margin-right: 20px;\n}\n.campaignActionsModal-shareTools {\n  box-flex: 40;\n  -webkit-flex: 40;\n  -moz-flex: 40;\n  -ms-flex: 40;\n  flex: 40;\n}\n", ""]);
	
	// exports


/***/ },

/***/ 1406:
/***/ function(module, exports) {

	module.exports = "<div class=\"campaignActionsModal\">\n  <div class=\"campaignActionsModal-contribute\">\n    <campaign-view-perks ng-if=\"showViewPerksCta()\"></campaign-view-perks>\n    <campaign-contribute ng-if=\"!showViewPerksCta() && shouldShowBackItCta()\"></campaign-contribute>\n  </div>\n  <div class=\"campaignActionsModal-shareTools\">\n    <campaign-share-buttons></campaign-share-buttons>\n  </div>\n</div>\n";

/***/ },

/***/ 1407:
/***/ function(module, exports) {

	'use strict';
	
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	exports.default = campaignLoginModal;
	/*@ngInject*/
	function campaignLoginModal() {
	  return {
	    restrict: 'A',
	    scope: {
	      banner: '='
	    },
	    transclude: true,
	    template: '<span class="campaignLoginModal" ng-click="openModal()" ng-transclude></span><session-modal banner="banner" status="status"></session-modal>',
	    link: function link(scope) {
	      scope.status = {
	        startingForm: 'signupForm',
	        open: false
	      };
	
	      scope.openModal = function () {
	        scope.status.open = true;
	      };
	    }
	  };
	}

/***/ },

/***/ 1408:
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	
	campaignBackers.$inject = ["$http", "i18n", "campaign"];
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	exports.default = campaignBackers;
	
	__webpack_require__(1409);
	
	var _privateApi = __webpack_require__(186);
	
	/*@ngInject*/
	function campaignBackers($http, i18n, campaign) {
	  return {
	    restrict: 'E',
	    scope: {},
	    template: __webpack_require__(1411),
	    link: function link(scope) {
	      scope.i18n = i18n;
	
	      $http.get((0, _privateApi.privateApiCampaignPledgesPath)({ campaignId: campaign.id })).then(function (result) {
	        scope.pledges = result.data.response;
	        scope.pagination = result.data.pagination;
	      });
	
	      scope.seeMore = function () {
	        $http.get((0, _privateApi.privateApiCampaignPledgesPath)({ campaignId: campaign.id }) + '?page=' + scope.pagination.next).then(function (result) {
	          scope.pledges = scope.pledges.concat(result.data.response);
	          scope.pagination = result.data.pagination;
	        });
	      };
	    }
	  };
	}

/***/ },

/***/ 1409:
/***/ function(module, exports, __webpack_require__) {

	// style-loader: Adds some css to the DOM by adding a <style> tag
	
	// load the styles
	var content = __webpack_require__(1410);
	if(typeof content === 'string') content = [[module.id, content, '']];
	// add the styles to the DOM
	var update = __webpack_require__(80)(content, {});
	if(content.locals) module.exports = content.locals;
	// Hot Module Replacement
	if(false) {
		// When the styles change, update the <style> tags
		if(!content.locals) {
			module.hot.accept("!!./../node_modules/css-loader/index.js!./../node_modules/less-loader/index.js!./campaign-backers.less", function() {
				var newContent = require("!!./../node_modules/css-loader/index.js!./../node_modules/less-loader/index.js!./campaign-backers.less");
				if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];
				update(newContent);
			});
		}
		// When the module is disposed, remove the <style> tags
		module.hot.dispose(function() { update(); });
	}

/***/ },

/***/ 1410:
/***/ function(module, exports, __webpack_require__) {

	exports = module.exports = __webpack_require__(79)();
	// imports
	
	
	// module
	exports.push([module.id, "/* Antenna Font Family Variations */\n/* Benton Font Family Variations */\n/** Perk Store mobile header text **/\n/** Only mobile campaign/contributions **/\n/* We can define top-left-dimple or left-top-dimple etc as necessary */\n.campaignBackers {\n  padding-bottom: 10px;\n}\n.campaignBackers-none {\n  font-family: \"Benton Sans\", \"Helvetica\", \"sans-serif\";\n  font-size: 14px;\n  font-weight: normal;\n  line-height: 20px;\n}\n.campaignBackers-pledge {\n  padding-top: 15px;\n  padding-bottom: 15px;\n  border-bottom: 1px solid #dddddd;\n  display: box;\n  display: -webkit-flex;\n  display: -moz-flex;\n  display: -ms-flexbox;\n  display: -ms-flex;\n  display: flex;\n  box-align: center;\n  -ms-flex-align: center;\n  -webkit-align-items: center;\n  -moz-align-items: center;\n  -ms-align-items: center;\n  align-items: center;\n  box-pack: justify;\n  -ms-flex-pack: justify;\n  -webkit-justify-content: space-between;\n  -moz-justify-content: space-between;\n  -ms-justify-content: space-between;\n  justify-content: space-between;\n}\n.campaignBackers-pledge:first-child {\n  padding-top: 0;\n}\n.campaignBackers-pledge-backer {\n  display: box;\n  display: -webkit-flex;\n  display: -moz-flex;\n  display: -ms-flexbox;\n  display: -ms-flex;\n  display: flex;\n  box-align: center;\n  -ms-flex-align: center;\n  -webkit-align-items: center;\n  -moz-align-items: center;\n  -ms-align-items: center;\n  align-items: center;\n}\n.campaignBackers-pledge-backer-image img {\n  height: 40px;\n  width: 40px;\n  border-radius: 50%;\n}\n.campaignBackers-pledge-backer-details {\n  margin-left: 10px;\n  box-flex: 1;\n  -webkit-flex: 1;\n  -moz-flex: 1;\n  -ms-flex: 1;\n  flex: 1;\n}\n.campaignBackers-pledge-backer-details-text {\n  color: #6a6a6a;\n  font-family: \"Benton Sans\", \"Helvetica\", \"sans-serif\";\n  font-weight: bold;\n  font-size: 14px;\n  line-height: 20px;\n}\n@media not all and (min-width: 1280px) {\n  .campaignBackers-pledge-backer-details-text {\n    font-family: \"Benton Sans\", \"Helvetica\", \"sans-serif\";\n    font-size: 12px;\n    font-weight: bold;\n    line-height: 18px;\n  }\n}\n.campaignBackers-pledge-backer-details-text--link {\n  color: #eb1478;\n}\n.campaignBackers-pledge-backer-details-note {\n  color: #a8a8a8;\n  font-family: \"Benton Sans\", \"Helvetica\", \"sans-serif\";\n  font-size: 14px;\n  font-weight: normal;\n  line-height: 20px;\n}\n@media not all and (min-width: 1280px) {\n  .campaignBackers-pledge-backer-details-note {\n    font-family: \"Benton Sans\", \"Helvetica\", \"sans-serif\";\n    font-size: 12px;\n    font-weight: normal;\n    line-height: 18px;\n  }\n}\n.campaignBackers-pledge-amount {\n  color: #6a6a6a;\n}\n.campaignBackers-pledge-amount-bold {\n  font-family: \"Benton Sans\", \"Helvetica\", \"sans-serif\";\n  font-size: 16px;\n  font-weight: bold;\n  line-height: 26px;\n  letter-spacing: 0;\n}\n@media not all and (min-width: 1280px) {\n  .campaignBackers-pledge-amount-bold {\n    font-family: \"Benton Sans\", \"Helvetica\", \"sans-serif\";\n    font-weight: bold;\n    font-size: 14px;\n    line-height: 20px;\n  }\n}\n.campaignBackers-pledge-amount-regular {\n  font-family: \"Benton Sans\", \"Helvetica\", \"sans-serif\";\n  font-size: 16px;\n  font-weight: normal;\n  line-height: 26px;\n  letter-spacing: 0;\n}\n@media not all and (min-width: 1280px) {\n  .campaignBackers-pledge-amount-regular {\n    font-family: \"Benton Sans\", \"Helvetica\", \"sans-serif\";\n    font-size: 14px;\n    font-weight: normal;\n    line-height: 20px;\n  }\n}\n.campaignBackers-seeMore {\n  border-bottom: 1px solid #dddddd;\n  text-transform: uppercase;\n  height: 30px;\n  display: box;\n  display: -webkit-flex;\n  display: -moz-flex;\n  display: -ms-flexbox;\n  display: -ms-flex;\n  display: flex;\n  box-align: center;\n  -ms-flex-align: center;\n  -webkit-align-items: center;\n  -moz-align-items: center;\n  -ms-align-items: center;\n  align-items: center;\n  box-pack: center;\n  -ms-flex-pack: center;\n  -webkit-justify-content: center;\n  -moz-justify-content: center;\n  -ms-justify-content: center;\n  justify-content: center;\n  font-family: \"Benton Sans Medium\", \"Helvetica\", \"sans-serif\";\n  font-size: 14px;\n  line-height: 20px;\n}\n", ""]);
	
	// exports


/***/ },

/***/ 1411:
/***/ function(module, exports) {

	module.exports = "<div class=\"campaignBackers\">\n  <div class=\"campaignBackers-none\" ng-if=\"pledges.length === 0\">\n    {{::i18n.t('campaign_has_no_contributors')}}\n  </div>\n\n  <div class=\"campaignBackers-pledge\" ng-if=\"pledges.length > 0\" ng-repeat=\"pledge in pledges\">\n    <div class=\"campaignBackers-pledge-backer\">\n      <div class=\"campaignBackers-pledge-backer-image\">\n        <img ng-src=\"{{pledge.pledger_image_url}}\"/>\n      </div>\n      <div class=\"campaignBackers-pledge-backer-details\">\n        <a class=\"campaignBackers-pledge-backer-details-text campaignBackers-pledge-backer-details-text--link\"\n           ng-if=\"pledge.pledger_profile_url\" ng-href=\"{{pledge.pledger_profile_url}}\">{{pledge.pledger_display_name}}</a>\n        <div class=\"campaignBackers-pledge-backer-details-text\"\n             ng-if=\"!pledge.pledger_profile_url\">{{pledge.pledger_display_name}}</div>\n        <div class=\"campaignBackers-pledge-backer-details-text campaignBackers-pledge-backer-details-text--link\"\n             ng-if=\"pledge.pledge_details_url\">\n          <a ng-if=\"pledge.order_id\" ng-href=\"{{pledge.pledge_details_url}}\">{{::i18n.t('view_order')}}</a>\n          <a ng-if=\"!pledge.order_id\" ng-href=\"{{pledge.pledge_details_url}}\">{{::i18n.t('view_donation')}}</a>\n        </div>\n        <div class=\"campaignBackers-pledge-backer-details-note\">{{pledge.time_ago}}</div>\n      </div>\n    </div>\n\n    <div class=\"campaignBackers-pledge-amount\">\n      <div ng-if=\"pledge.display_amount\">\n        <span class=\"campaignBackers-pledge-amount-bold\">\n          {{pledge.display_amount}}\n        </span>\n        <span class=\"campaignBackers-pledge-amount-regular\">\n          {{pledge.display_amount_iso_code}}\n        </span>\n      </div>\n      <div class=\"campaignBackers-pledge-amount-bold\" ng-if=\"!pledge.display_amount\">{{::i18n.t('private_caps')}}</div>\n    </div>\n  </div>\n\n  <div class=\"campaignBackers-seeMore\" ng-if=\"pagination.next\">\n    <a href=\"\" ng-click=\"seeMore()\">{{::i18n.t('campaign_page_next.see_more_backers')}}</a>\n  </div>\n</div>\n";

/***/ },

/***/ 1412:
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	
	campaignPartnerBadge.$inject = ["i18n"];
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	exports.default = campaignPartnerBadge;
	
	__webpack_require__(1413);
	
	/*@ngInject*/
	function campaignPartnerBadge(i18n) {
	  return {
	    restrict: 'E',
	    scope: {
	      partner: '='
	    },
	    template: __webpack_require__(1415),
	    link: function link(scope) {
	      scope.viewInfoText = i18n.t('campaign_page_next.trust.view_info');
	      scope.logo = function () {
	        return _.get(scope.partner, 'square_logo_image_url', scope.partner.square_logo_missing_image_url);
	      };
	    }
	  };
	}

/***/ },

/***/ 1413:
/***/ function(module, exports, __webpack_require__) {

	// style-loader: Adds some css to the DOM by adding a <style> tag
	
	// load the styles
	var content = __webpack_require__(1414);
	if(typeof content === 'string') content = [[module.id, content, '']];
	// add the styles to the DOM
	var update = __webpack_require__(80)(content, {});
	if(content.locals) module.exports = content.locals;
	// Hot Module Replacement
	if(false) {
		// When the styles change, update the <style> tags
		if(!content.locals) {
			module.hot.accept("!!./../node_modules/css-loader/index.js!./../node_modules/less-loader/index.js!./campaign-partner-badge.less", function() {
				var newContent = require("!!./../node_modules/css-loader/index.js!./../node_modules/less-loader/index.js!./campaign-partner-badge.less");
				if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];
				update(newContent);
			});
		}
		// When the module is disposed, remove the <style> tags
		module.hot.dispose(function() { update(); });
	}

/***/ },

/***/ 1414:
/***/ function(module, exports, __webpack_require__) {

	exports = module.exports = __webpack_require__(79)();
	// imports
	
	
	// module
	exports.push([module.id, "/* Antenna Font Family Variations */\n/* Benton Font Family Variations */\n/** Perk Store mobile header text **/\n/** Only mobile campaign/contributions **/\n/* We can define top-left-dimple or left-top-dimple etc as necessary */\n.campaignPartnerBadge {\n  display: box;\n  display: -webkit-flex;\n  display: -moz-flex;\n  display: -ms-flexbox;\n  display: -ms-flex;\n  display: flex;\n  box-align: center;\n  -ms-flex-align: center;\n  -webkit-align-items: center;\n  -moz-align-items: center;\n  -ms-align-items: center;\n  align-items: center;\n}\n.campaignPartnerBadge-image img {\n  height: 50px;\n  width: 50px;\n  border-radius: 50%;\n}\n.campaignPartnerBadge-details {\n  margin-left: 15px;\n  color: #6a6a6a;\n  box-flex: 1;\n  -webkit-flex: 1;\n  -moz-flex: 1;\n  -ms-flex: 1;\n  flex: 1;\n  font-family: \"Benton Sans Medium\", \"Helvetica\", \"sans-serif\";\n  font-size: 12px;\n  line-height: 18px;\n  font-weight: normal;\n  letter-spacing: 0;\n}\n.campaignPartnerBadge-details-link {\n  color: #eb1478;\n  font-family: \"Benton Sans\", \"Helvetica\", \"sans-serif\";\n  font-size: 12px;\n  font-weight: normal;\n  line-height: 18px;\n}\n", ""]);
	
	// exports


/***/ },

/***/ 1415:
/***/ function(module, exports) {

	module.exports = "<div class=\"campaignPartnerBadge\">\n  <div class=\"campaignPartnerBadge-image\"><img gogo-test=\"image\" ng-src=\"{{logo()}}\"/></div>\n  <div class=\"campaignPartnerBadge-details\">\n    <div gogo-test=\"name\">{{partner.name}}</div>\n    <a gogo-test=\"link\" class=\"campaignPartnerBadge-details-link\"\n       target=\"_blank\" ng-href=\"{{partner.path}}\" rel=\"noopener\">{{::viewInfoText}}</a>\n  </div>\n</div>\n";

/***/ },

/***/ 1416:
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	
	campaignCollectionBadge.$inject = ["i18n", "campaign"];
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	exports.default = campaignCollectionBadge;
	
	__webpack_require__(1417);
	
	/*@ngInject*/
	function campaignCollectionBadge(i18n, campaign) {
	  return {
	    restrict: 'E',
	    template: __webpack_require__(1419),
	    link: function link(scope) {
	      scope.i18n = i18n;
	      scope.collection = campaign.collection;
	    }
	  };
	}

/***/ },

/***/ 1417:
/***/ function(module, exports, __webpack_require__) {

	// style-loader: Adds some css to the DOM by adding a <style> tag
	
	// load the styles
	var content = __webpack_require__(1418);
	if(typeof content === 'string') content = [[module.id, content, '']];
	// add the styles to the DOM
	var update = __webpack_require__(80)(content, {});
	if(content.locals) module.exports = content.locals;
	// Hot Module Replacement
	if(false) {
		// When the styles change, update the <style> tags
		if(!content.locals) {
			module.hot.accept("!!./../node_modules/css-loader/index.js!./../node_modules/less-loader/index.js!./campaign-collection-badge.less", function() {
				var newContent = require("!!./../node_modules/css-loader/index.js!./../node_modules/less-loader/index.js!./campaign-collection-badge.less");
				if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];
				update(newContent);
			});
		}
		// When the module is disposed, remove the <style> tags
		module.hot.dispose(function() { update(); });
	}

/***/ },

/***/ 1418:
/***/ function(module, exports, __webpack_require__) {

	exports = module.exports = __webpack_require__(79)();
	// imports
	
	
	// module
	exports.push([module.id, "/* Antenna Font Family Variations */\n/* Benton Font Family Variations */\n/** Perk Store mobile header text **/\n/** Only mobile campaign/contributions **/\n/* We can define top-left-dimple or left-top-dimple etc as necessary */\n.raised-sizing {\n  font-family: \"Benton Sans\", \"Helvetica\", \"sans-serif\";\n  font-size: 12px;\n  font-weight: normal;\n  line-height: 18px;\n}\n@media (min-width: 1002px) {\n  .raised-sizing {\n    font-family: \"Benton Sans\", \"Helvetica\", \"sans-serif\";\n    font-size: 16px;\n    font-weight: normal;\n    line-height: 26px;\n    letter-spacing: 0;\n    line-height: 25px;\n  }\n}\n.amount-sizing {\n  font-family: \"Benton Sans\", \"Helvetica\", \"sans-serif\";\n  font-weight: bold;\n  font-size: 14px;\n  line-height: 20px;\n}\n@media (min-width: 1002px) {\n  .amount-sizing {\n    font-family: \"Benton Sans\", \"Helvetica\", \"sans-serif\";\n    font-size: 20px;\n    font-weight: bold;\n    line-height: 26px;\n  }\n}\n@media (min-width: 1002px) {\n  .video-heights-for-2-columns {\n    height: 415px;\n  }\n}\n@media (min-width: 1280px) {\n  .video-heights-for-2-columns {\n    height: 460px !important;\n  }\n}\n.body-section-header-text-sizing {\n  font-family: \"Benton Sans\", \"Helvetica\", \"sans-serif\";\n  font-size: 14px;\n  font-weight: normal;\n  line-height: 20px;\n}\n@media (min-width: 1280px) {\n  .body-section-header-text-sizing {\n    font-family: \"Benton Sans\", \"Helvetica\", \"sans-serif\";\n    font-size: 16px;\n    font-weight: normal;\n    line-height: 26px;\n    letter-spacing: 0;\n  }\n}\n.body-sub-section-header-title {\n  font-family: \"Benton Sans\", \"Helvetica\", \"sans-serif\";\n  font-size: 14px;\n  font-weight: normal;\n  line-height: 20px;\n  color: #a8a8a8;\n  margin-top: 20px;\n  margin-bottom: 20px;\n  padding-top: 5px;\n  padding-bottom: 5px;\n  text-transform: uppercase;\n  border-bottom: 1px solid #dddddd;\n}\n@media (min-width: 1280px) {\n  .body-sub-section-header-title {\n    font-family: \"Benton Sans\", \"Helvetica\", \"sans-serif\";\n    font-size: 16px;\n    font-weight: normal;\n    line-height: 26px;\n    letter-spacing: 0;\n  }\n}\n@media not all and (min-width: 768px) {\n  .body-sub-section-header-title {\n    margin-left: 20px;\n    margin-right: 20px;\n  }\n}\n.campaignCollectionBadge {\n  margin-bottom: 5px;\n}\n@media (min-width: 768px) {\n  .campaignCollectionBadge {\n    margin-bottom: 38px;\n  }\n}\n.campaignCollectionBadge-title {\n  font-family: \"Benton Sans\", \"Helvetica\", \"sans-serif\";\n  font-size: 14px;\n  font-weight: normal;\n  line-height: 20px;\n  color: #a8a8a8;\n  margin-top: 20px;\n  margin-bottom: 20px;\n  padding-top: 5px;\n  padding-bottom: 5px;\n  text-transform: uppercase;\n  border-bottom: 1px solid #dddddd;\n}\n@media (min-width: 1280px) {\n  .campaignCollectionBadge-title {\n    font-family: \"Benton Sans\", \"Helvetica\", \"sans-serif\";\n    font-size: 16px;\n    font-weight: normal;\n    line-height: 26px;\n    letter-spacing: 0;\n  }\n}\n@media not all and (min-width: 768px) {\n  .campaignCollectionBadge-title {\n    margin-left: 20px;\n    margin-right: 20px;\n  }\n}\n.campaignCollectionBadge-content {\n  display: box;\n  display: -webkit-flex;\n  display: -moz-flex;\n  display: -ms-flexbox;\n  display: -ms-flex;\n  display: flex;\n  box-align: center;\n  -ms-flex-align: center;\n  -webkit-align-items: center;\n  -moz-align-items: center;\n  -ms-align-items: center;\n  align-items: center;\n  padding-left: 20px;\n  padding-right: 20px;\n}\n@media (min-width: 768px) {\n  .campaignCollectionBadge-content {\n    padding-left: 0;\n  }\n}\n.campaignCollectionBadge-content svg {\n  fill: #FDDE86;\n  vertical-align: middle;\n  width: 25px;\n  height: 50px;\n}\n@media (min-width: 1002px) {\n  .campaignCollectionBadge-content svg {\n    width: 40px;\n    height: 80px;\n  }\n}\n.campaignCollectionBadge-text {\n  font-family: \"Benton Sans\", \"Helvetica\", \"sans-serif\";\n  font-size: 14px;\n  font-weight: normal;\n  line-height: 20px;\n  color: #eb1478;\n  padding-left: 10px;\n}\n@media (min-width: 1002px) {\n  .campaignCollectionBadge-text {\n    font-family: \"Benton Sans\", \"Helvetica\", \"sans-serif\";\n    font-size: 16px;\n    font-weight: normal;\n    line-height: 26px;\n    letter-spacing: 0;\n    padding-left: 20px;\n  }\n}\n", ""]);
	
	// exports


/***/ },

/***/ 1419:
/***/ function(module, exports) {

	module.exports = "<div ng-if=\"collection\">\n  <div class=\"campaignCollectionBadge\" gogo-test=\"campaign_collection_badge\">\n    <div class=\"campaignCollectionBadge-title\">{{::i18n.t('campaign_page_next.featured_in')}}</div>\n    <div class=\"campaignCollectionBadge-content\">\n      <svg><use xlink:href=\"#badge-collections\"></use></svg>\n      <a class=\"campaignCollectionBadge-text\"\n         gogo-test=\"link\"\n         target=\"_blank\"\n         analytics-on=\"click\"\n         analytics-name=\"campaign_page_collection_badge_click\"\n         analytics-category=\"campaign_page_discovery\"\n         analytics-event=\"collection_badge\"\n         analytics-label=\"{{ collection.title }}\"\n         analytics-collection-id=\"{{ collection.id }}\"\n         ng-href=\"{{collection.path}}\">{{collection.title + \" \" + i18n.t('collections.collection')}}</a>\n    </div>\n  </div>\n</div>\n";

/***/ },

/***/ 1420:
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	
	campaignSponsors.$inject = ["i18n", "campaign"];
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	
	__webpack_require__(1421);
	
	/*@ngInject*/
	function campaignSponsors(i18n, campaign) {
	  return {
	    restrict: 'E',
	    scope: {},
	    template: __webpack_require__(1423),
	    link: function link(scope) {
	      scope.i18n = i18n;
	      var aboveLowSponsorPartners = function aboveLowSponsorPartners() {
	        return campaign.sponsorsWhereLevelGreaterThan(1);
	      };
	      scope.showSingleSponsor = function () {
	        return aboveLowSponsorPartners().length === 1;
	      };
	      scope.showMultipleSponsors = function () {
	        return aboveLowSponsorPartners().length > 1;
	      };
	      scope.sponsors = function () {
	        return aboveLowSponsorPartners().slice(0, 4);
	      };
	      scope.styleForImageIndex = function (index) {
	        return 'z-index:' + (10 - index);
	      };
	    }
	  };
	}
	
	exports.default = campaignSponsors;

/***/ },

/***/ 1421:
/***/ function(module, exports, __webpack_require__) {

	// style-loader: Adds some css to the DOM by adding a <style> tag
	
	// load the styles
	var content = __webpack_require__(1422);
	if(typeof content === 'string') content = [[module.id, content, '']];
	// add the styles to the DOM
	var update = __webpack_require__(80)(content, {});
	if(content.locals) module.exports = content.locals;
	// Hot Module Replacement
	if(false) {
		// When the styles change, update the <style> tags
		if(!content.locals) {
			module.hot.accept("!!./../node_modules/css-loader/index.js!./../node_modules/less-loader/index.js!./campaign-sponsors.less", function() {
				var newContent = require("!!./../node_modules/css-loader/index.js!./../node_modules/less-loader/index.js!./campaign-sponsors.less");
				if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];
				update(newContent);
			});
		}
		// When the module is disposed, remove the <style> tags
		module.hot.dispose(function() { update(); });
	}

/***/ },

/***/ 1422:
/***/ function(module, exports, __webpack_require__) {

	exports = module.exports = __webpack_require__(79)();
	// imports
	
	
	// module
	exports.push([module.id, "/* Antenna Font Family Variations */\n/* Benton Font Family Variations */\n/** Perk Store mobile header text **/\n/** Only mobile campaign/contributions **/\n/* We can define top-left-dimple or left-top-dimple etc as necessary */\n.campaignSponsor-singlePartner {\n  display: box;\n  display: -webkit-flex;\n  display: -moz-flex;\n  display: -ms-flexbox;\n  display: -ms-flex;\n  display: flex;\n  box-align: center;\n  -ms-flex-align: center;\n  -webkit-align-items: center;\n  -moz-align-items: center;\n  -ms-align-items: center;\n  align-items: center;\n}\n.campaignSponsor-avatar {\n  border-radius: 50%;\n  min-width: 50px;\n}\n.campaignSponsor-avatar--stacked {\n  position: relative;\n  margin-left: -10px;\n}\n.campaignSponsor-avatar--stacked:first-child {\n  margin-left: 0;\n}\n@media (max-width: 1279px) {\n  .campaignSponsor-avatar--overflow {\n    display: none;\n  }\n}\n.campaignSponsor-details {\n  margin-left: 10px;\n  display: none;\n}\n@media (min-width: 1280px) {\n  .campaignSponsor-details {\n    display: block;\n  }\n}\n.campaignSponsor-detailsName {\n  font-family: \"Benton Sans Medium\", \"Helvetica\", \"sans-serif\";\n  font-size: 14px;\n  line-height: 20px;\n  color: #6a6a6a;\n  line-height: 18px;\n}\n.campaignSponsor-detailsLink {\n  font-family: \"Benton Sans\", \"Helvetica\", \"sans-serif\";\n  font-size: 14px;\n  font-weight: normal;\n  line-height: 20px;\n  line-height: 18px;\n}\n", ""]);
	
	// exports


/***/ },

/***/ 1423:
/***/ function(module, exports) {

	module.exports = "<div class=\"campaignSponsor\" gogo-test=\"campaign_sponsor_badge\">\n  <div class=\"campaignSponsor-singlePartner\" ng-if=\"showSingleSponsor()\" ng-repeat=\"sponsor in sponsors()\">\n    <img class=\"campaignSponsor-avatar\" cl-image width=\"50\" height=\"50\" crop=\"fill\" public-id=\"sponsor.image_public_id\">\n    <div class=\"campaignSponsor-details\">\n      <div class=\"campaignSponsor-detailsName\">{{sponsor.name}}</div>\n      <a class=\"campaignSponsor-detailsLink\" ng-href=\"{{sponsor.landing_page}}\">{{::i18n.t('about')}}</a>\n    </div>\n  </div>\n  <div ng-if=\"showMultipleSponsors()\">\n    <img ng-repeat=\"sponsor in sponsors() track by $index\"\n         class=\"campaignSponsor-avatar campaignSponsor-avatar--stacked\"\n         ng-class=\"{'campaignSponsor-avatar--overflow': $index > 1}\"\n         style=\"{{styleForImageIndex($index)}}\"\n         cl-image width=\"50\" height=\"50\" crop=\"fill\" public-id=\"sponsor.image_public_id\">\n  </div>\n</div>\n";

/***/ },

/***/ 1424:
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	
	campaignHeaderTrust.$inject = ["campaign"];
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	
	__webpack_require__(1425);
	
	/*@ngInject*/
	function campaignHeaderTrust(campaign) {
	  return {
	    restrict: 'E',
	    scope: {},
	    template: __webpack_require__(1427),
	    link: function link(scope) {
	      var medAndHighSponsors = function medAndHighSponsors() {
	        return campaign.sponsorsWhereLevelGreaterThan(1);
	      };
	      scope.showSponsors = function () {
	        return !_.isEmpty(medAndHighSponsors());
	      };
	    }
	  };
	}
	
	exports.default = campaignHeaderTrust;

/***/ },

/***/ 1425:
/***/ function(module, exports, __webpack_require__) {

	// style-loader: Adds some css to the DOM by adding a <style> tag
	
	// load the styles
	var content = __webpack_require__(1426);
	if(typeof content === 'string') content = [[module.id, content, '']];
	// add the styles to the DOM
	var update = __webpack_require__(80)(content, {});
	if(content.locals) module.exports = content.locals;
	// Hot Module Replacement
	if(false) {
		// When the styles change, update the <style> tags
		if(!content.locals) {
			module.hot.accept("!!./../node_modules/css-loader/index.js!./../node_modules/less-loader/index.js!./campaign-header-trust.less", function() {
				var newContent = require("!!./../node_modules/css-loader/index.js!./../node_modules/less-loader/index.js!./campaign-header-trust.less");
				if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];
				update(newContent);
			});
		}
		// When the module is disposed, remove the <style> tags
		module.hot.dispose(function() { update(); });
	}

/***/ },

/***/ 1426:
/***/ function(module, exports, __webpack_require__) {

	exports = module.exports = __webpack_require__(79)();
	// imports
	
	
	// module
	exports.push([module.id, "/* Antenna Font Family Variations */\n/* Benton Font Family Variations */\n/** Perk Store mobile header text **/\n/** Only mobile campaign/contributions **/\n/* We can define top-left-dimple or left-top-dimple etc as necessary */\n.campaignHeader-combinedTrust {\n  display: box;\n  display: -webkit-flex;\n  display: -moz-flex;\n  display: -ms-flexbox;\n  display: -ms-flex;\n  display: flex;\n  box-orient: horizontal;\n  -ms-flex-wrap: none;\n  -webkit-flex-flow: row nowrap;\n  -moz-flex-flow: row nowrap;\n  -ms-flex-flow: row nowrap;\n  flex-flow: row nowrap;\n  box-pack: start;\n  -ms-flex-pack: start;\n  -webkit-justify-content: flex-start;\n  -moz-justify-content: flex-start;\n  -ms-justify-content: flex-start;\n  justify-content: flex-start;\n  box-align: center;\n  -ms-flex-align: center;\n  -webkit-align-items: center;\n  -moz-align-items: center;\n  -ms-align-items: center;\n  align-items: center;\n  -ms-flex-line-pack: center;\n  -webkit-align-content: center;\n  -moz-align-content: center;\n  -ms-align-content: center;\n  align-content: center;\n}\n.campaignHeaderBasics-sponsor {\n  display: none;\n}\n@media (min-width: 1002px) {\n  .campaignHeaderBasics-sponsor {\n    display: block;\n  }\n}\n.campaignHeader-combinedTrustAdd {\n  font-family: \"Benton Sans Medium\", \"Helvetica\", \"sans-serif\";\n  font-size: 14px;\n  line-height: 20px;\n  margin-left: 20px;\n  margin-right: 20px;\n  color: #6a6a6a;\n}\n.campaignTrust-details {\n  white-space: nowrap;\n}\n", ""]);
	
	// exports


/***/ },

/***/ 1427:
/***/ function(module, exports) {

	module.exports = "<div class=\"campaignHeader-combinedTrust\">\n  <campaign-trust class=\"campaignHeaderBasics-trust\"></campaign-trust>\n  <span ng-if=\"showSponsors()\" class=\"campaignHeaderBasics-sponsor campaignHeader-combinedTrustAdd\">+</span>\n  <campaign-sponsors ng-if=\"showSponsors()\" class=\"campaignHeaderBasics-sponsor\"></campaign-sponsors>\n</div>\n";

/***/ },

/***/ 1428:
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	exports.default = campaignBody;
	
	__webpack_require__(1429);
	
	function campaignBody(campaign, campaignAnalyticsService, split) {
	  var THUMBNAIL_EXPERIMENT_NAME = 'campaign_page_thumbnails';
	
	  return {
	    restrict: 'E',
	    scope: {},
	    template: __webpack_require__(1431),
	    link: function link(scope) {
	      scope.campaignHasOverview = !!campaign.overview;
	      scope.inCampaignThumbnailExperiment = false;
	
	      //send event on page load
	      campaignAnalyticsService.sendOnCampaignLoadEvent({ gaEventCategory: 'campaign_page_discovery',
	        gaEventAction: 'campaign_load' }, { thetaName: 'campaign_page_show',
	        inCollection: !!campaign.collection,
	        videoType: campaign.main_video_info.type });
	
	      if (campaign.gallery_available) {
	        checkThumbnailGallerySplitVariant();
	      }
	
	      function checkThumbnailGallerySplitVariant() {
	        var stopWatching = scope.$watch(function () {
	          return split.checkVariantState(THUMBNAIL_EXPERIMENT_NAME);
	        }, function (variantName) {
	          if (variantName !== '$loading') {
	            stopWatching(); // stop the watch cycle after a real result is returned from split
	            scope.inCampaignThumbnailExperiment = variantName === 'experiment';
	          }
	        });
	      }
	    }
	  };
	} /*@ngInject*/

/***/ },

/***/ 1429:
/***/ function(module, exports, __webpack_require__) {

	// style-loader: Adds some css to the DOM by adding a <style> tag
	
	// load the styles
	var content = __webpack_require__(1430);
	if(typeof content === 'string') content = [[module.id, content, '']];
	// add the styles to the DOM
	var update = __webpack_require__(80)(content, {});
	if(content.locals) module.exports = content.locals;
	// Hot Module Replacement
	if(false) {
		// When the styles change, update the <style> tags
		if(!content.locals) {
			module.hot.accept("!!./../node_modules/css-loader/index.js!./../node_modules/less-loader/index.js!./campaign-body.less", function() {
				var newContent = require("!!./../node_modules/css-loader/index.js!./../node_modules/less-loader/index.js!./campaign-body.less");
				if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];
				update(newContent);
			});
		}
		// When the module is disposed, remove the <style> tags
		module.hot.dispose(function() { update(); });
	}

/***/ },

/***/ 1430:
/***/ function(module, exports, __webpack_require__) {

	exports = module.exports = __webpack_require__(79)();
	// imports
	
	
	// module
	exports.push([module.id, "/* Antenna Font Family Variations */\n/* Benton Font Family Variations */\n/** Perk Store mobile header text **/\n/** Only mobile campaign/contributions **/\n/* We can define top-left-dimple or left-top-dimple etc as necessary */\ncampaign-navigation,\ncampaign-accordion {\n  display: block;\n  padding-top: 20px;\n  padding-bottom: 20px;\n}\ncampaign-story-link {\n  padding: 20px;\n}\ncampaign-overview {\n  padding-bottom: 20px;\n}\n.campaignBody-leadSection {\n  min-height: 50vh;\n  display: block;\n  position: relative;\n  float: left;\n  width: 75%;\n  min-height: 1px;\n  padding-left: 6px;\n  padding-right: 6px;\n}\n@media (min-width: 768px) {\n  .campaignBody-leadSection {\n    position: relative;\n    min-height: 1px;\n    padding-left: 10px;\n    padding-right: 10px;\n    float: left;\n    width: 58.33333333%;\n  }\n}\n@media (min-width: 1002px) {\n  .campaignBody-leadSection {\n    position: relative;\n    min-height: 1px;\n    padding-left: 15px;\n    padding-right: 15px;\n    float: left;\n    width: 58.33333333%;\n  }\n}\n@media (min-width: 1280px) {\n  .campaignBody-leadSection {\n    position: relative;\n    min-height: 1px;\n    padding-left: 20px;\n    padding-right: 20px;\n    float: left;\n    width: 58.33333333%;\n  }\n}\n.campaignBody-finalSection {\n  display: block;\n  position: relative;\n  float: left;\n  width: 25%;\n  min-height: 1px;\n  padding-left: 6px;\n  padding-right: 6px;\n}\n@media (min-width: 768px) {\n  .campaignBody-finalSection {\n    position: relative;\n    min-height: 1px;\n    padding-left: 10px;\n    padding-right: 10px;\n    float: left;\n    width: 41.66666667%;\n  }\n}\n@media (min-width: 1002px) {\n  .campaignBody-finalSection {\n    position: relative;\n    min-height: 1px;\n    padding-left: 15px;\n    padding-right: 15px;\n    float: left;\n    width: 33.33333333%;\n  }\n}\n@media (min-width: 1280px) {\n  .campaignBody-finalSection {\n    position: relative;\n    min-height: 1px;\n    padding-left: 20px;\n    padding-right: 20px;\n    float: left;\n    width: 29.16666667%;\n  }\n}\n.campaignBody campaign-next-perk:not(:first-child) {\n  display: block;\n  margin-top: 20px;\n}\n.campaignBody-vertical {\n  display: block;\n}\n@media (min-width: 768px) {\n  .campaignBody-vertical {\n    display: none;\n  }\n}\n.campaignBody-horizontal {\n  display: none;\n}\n@media (min-width: 768px) {\n  .campaignBody-horizontal {\n    display: block;\n    margin-bottom: 20px;\n  }\n}\n", ""]);
	
	// exports


/***/ },

/***/ 1431:
/***/ function(module, exports) {

	module.exports = "<div class=\"campaignBody\"\n     analytics-on=\"scrollby\"\n     analytics-name=\"campaign/body.scroll\"\n     analytics-category=\"campaign_page_scroll\"\n     analytics-event=\"body\"\n     scrollby-offset=\"3%\"\n     scrollby-continuous>\n  <div class=\"campaignBody-horizontal\">\n    <div class=\"row\">\n      <div class=\"campaignBody-leadSection\">\n        <campaign-overview ng-if=\"campaignHasOverview\"></campaign-overview>\n        <campaign-navigation in-campaign-thumbnail-experiment=\"inCampaignThumbnailExperiment\"></campaign-navigation>\n        <div ui-view></div>\n      </div>\n      <div class=\"campaignBody-finalSection\">\n        <campaign-collection-badge></campaign-collection-badge>\n        <campaign-perks></campaign-perks>\n      </div>\n    </div>\n  </div>\n  <div class=\"campaignBody-vertical\">\n    <campaign-collection-badge></campaign-collection-badge>\n    <campaign-overview ng-if=\"campaignHasOverview\"></campaign-overview>\n    <campaign-story-link></campaign-story-link>\n    <campaign-perks id=\"vertical_perks_section\"></campaign-perks>\n    <campaign-accordion in-campaign-thumbnail-experiment=\"inCampaignThumbnailExperiment\"></campaign-accordion>\n  </div>\n  <report-this-campaign></report-this-campaign>\n</div>\n";

/***/ },

/***/ 1432:
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	
	campaignNextPerk.$inject = ["campaign", "i18n", "browser", "gon", "campaignAnalyticsService", "split", "$filter", "perkPrefs", "$modal"];
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	exports.default = campaignNextPerk;
	
	__webpack_require__(1433);
	
	/*@ngInject*/
	
	function campaignNextPerk(campaign, i18n, browser, gon, campaignAnalyticsService, split, $filter, perkPrefs, $modal) {
	  return {
	    template: __webpack_require__(1435),
	    scope: {
	      perk: '=',
	      showItems: '@'
	    },
	    link: function link($scope) {
	      $scope.expanded = false;
	      $scope.i18n = i18n;
	      $scope.campaign = campaign;
	      $scope.showPerkItems = $scope.showItems === 'true';
	      $scope.visibleState = function (test) {
	        var perk = $scope.perk;
	        if (campaign.isEnded()) {
	          return 'unavailable' == test;
	        } else if (perk.sold_out) {
	          return 'unavailable' == test || 'sold_out' == test;
	        } else if (perk.secret) {
	          return 'secret' == test;
	        } else if (perk.featured) {
	          return 'featured' == test;
	        }
	      };
	      $scope.discountPercent = $scope.perk.retail_amount && percentDifference($scope.perk.retail_amount, $scope.perk.amount);
	
	      $scope.estimatedDeliveryMonthYear = function () {
	        var month = i18n.t('date.month_names')[$filter('date')($scope.perk.estimated_delivery_date, 'M')];
	        var year = $filter('date')($scope.perk.estimated_delivery_date, 'yyyy');
	        return i18n.t('campaign_page_next.estimated_month_year', {
	          month: month,
	          year: year
	        });
	      };
	
	      $scope.perksClaimed = function () {
	        var numClaimed = $scope.perk.number_claimed || 0;
	        if ($scope.perk.number_available) {
	          return i18n.t('x_out_of_y_claimed', {
	            x: numClaimed,
	            y: $scope.perk.number_available,
	            count: numClaimed
	          });
	        } else {
	          return i18n.t('x_claimed', {
	            number_claimed: numClaimed,
	            count: numClaimed
	          });
	        }
	      };
	
	      function handlePerkCardSelection() {
	        if (!$scope.perk.sold_out && !campaign.funding_invalid_yet_live) {
	          // track secret perk clicks from the campaign page (goes into contribution flow)
	          campaignAnalyticsService.sendPerkEvent({ gaEventCategory: 'campaign_page_contribute',
	            gaEventAction: 'perk_card' }, { thetaName: "campaign/perk.click",
	            perkId: $scope.perk.id,
	            isFeatured: $scope.perk.featured,
	            isSecret: $scope.perk.secret,
	            hasShipping: $scope.perk.shipping_address_required });
	          if ($scope.showPerkItems) {
	            openPerkPrefencesModal();
	          } else {
	            navigateToPayment();
	          }
	        }
	      }
	
	      function openPerkPrefencesModal() {
	        perkPrefs.configure(perkPrefs.contexts.campaignPage);
	        var preferenceModalScope = $scope.$new();
	        preferenceModalScope.perkPrefs = perkPrefs;
	        perkPrefs.items = [];
	        $modal({
	          scope: preferenceModalScope,
	          template: __webpack_require__(1436)
	        });
	        perkPrefs.getItemsForPerk($scope.perk.id);
	      }
	
	      function navigateToPayment() {
	        browser.redirectTo(gon.urls.campaign_contribution_path + '?perk_id=' + $scope.perk.id);
	      }
	
	      $scope.clickPerkBody = function () {
	        if (browser.isMobile()) {
	          $scope.expanded = !$scope.expanded;
	          campaignAnalyticsService.sendPerkEvent({ gaEventCategory: 'campaign_page_contribute',
	            gaEventAction: 'perk_card_expand_mobile' }, { thetaName: "campaign/perk.click",
	            perkId: $scope.perk.id,
	            isFeatured: $scope.perk.featured,
	            isSecret: $scope.perk.secret,
	            hasShipping: $scope.perk.shipping_address_required });
	        } else {
	          handlePerkCardSelection();
	        }
	      };
	
	      $scope.clickPerkCta = function () {
	        handlePerkCardSelection();
	      };
	
	      function percentDifference(originalAmount, newAmount) {
	        return Math.floor((originalAmount - newAmount) / originalAmount * 100);
	      }
	    }
	  };
	}

/***/ },

/***/ 1433:
/***/ function(module, exports, __webpack_require__) {

	// style-loader: Adds some css to the DOM by adding a <style> tag
	
	// load the styles
	var content = __webpack_require__(1434);
	if(typeof content === 'string') content = [[module.id, content, '']];
	// add the styles to the DOM
	var update = __webpack_require__(80)(content, {});
	if(content.locals) module.exports = content.locals;
	// Hot Module Replacement
	if(false) {
		// When the styles change, update the <style> tags
		if(!content.locals) {
			module.hot.accept("!!./../node_modules/css-loader/index.js!./../node_modules/less-loader/index.js!./campaign-next-perk.less", function() {
				var newContent = require("!!./../node_modules/css-loader/index.js!./../node_modules/less-loader/index.js!./campaign-next-perk.less");
				if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];
				update(newContent);
			});
		}
		// When the module is disposed, remove the <style> tags
		module.hot.dispose(function() { update(); });
	}

/***/ },

/***/ 1434:
/***/ function(module, exports, __webpack_require__) {

	exports = module.exports = __webpack_require__(79)();
	// imports
	
	
	// module
	exports.push([module.id, "/* Antenna Font Family Variations */\n/* Benton Font Family Variations */\n/** Perk Store mobile header text **/\n/** Only mobile campaign/contributions **/\n/* We can define top-left-dimple or left-top-dimple etc as necessary */\n.campaignNextPerk {\n  display: block;\n  box-shadow: 0 0 0 1px #dddddd;\n  position: relative;\n}\n.campaignNextPerk--unavailable {\n  opacity: 0.5;\n  pointer-events: none;\n}\n.campaignNextPerk-featured,\n.campaignNextPerk-soldout,\n.campaignNextPerk-secret {\n  color: #ffffff;\n  position: absolute;\n  font-family: \"Benton Sans Medium\", \"Helvetica\", \"sans-serif\";\n  letter-spacing: 1px;\n  line-height: 25px;\n  text-align: center;\n  text-transform: uppercase;\n  width: 100%;\n}\n.campaignNextPerk-soldout,\n.campaignNextPerk-secret {\n  background-color: #a8a8a8;\n}\n.campaignNextPerk-featured {\n  background-color: #eb1478;\n}\n.campaignNextPerk-image {\n  width: 100%;\n}\n.campaignNextPerk-body {\n  padding: 30px 20px 20px;\n}\n.campaignNextPerk-amountWithCurrency > * {\n  display: inline-block;\n}\n.campaignNextPerk-amount {\n  font-family: \"Benton Sans\", \"Helvetica\", \"sans-serif\";\n  font-size: 24px;\n  line-height: 34px;\n  font-weight: bold;\n}\n.campaignNextPerk-amountMeta {\n  font-family: \"Benton Sans\", \"Helvetica\", \"sans-serif\";\n  font-size: 12px;\n  font-weight: normal;\n  line-height: 18px;\n  color: #6a6a6a;\n}\n.campaignNextPerk-discount {\n  color: #eb1478;\n}\n.campaignNextPerk-retailAmount {\n  text-decoration: line-through;\n}\n.campaignNextPerk-label {\n  font-family: \"Benton Sans Medium\", \"Helvetica\", \"sans-serif\";\n  font-size: 16px;\n  line-height: 26px;\n  font-weight: normal;\n  letter-spacing: 0;\n}\n@media (min-width: 1002px) {\n  .campaignNextPerk-label {\n    line-height: 22px;\n    font-family: \"Benton Sans Medium\", \"Helvetica\", \"sans-serif\";\n    font-size: 18px;\n    line-height: 28px;\n    font-weight: normal;\n    letter-spacing: 0;\n  }\n}\n.campaignNextPerk-description {\n  font-family: \"Benton Sans\", \"Helvetica\", \"sans-serif\";\n  font-size: 12px;\n  font-weight: normal;\n  line-height: 18px;\n}\n@media (min-width: 1002px) {\n  .campaignNextPerk-description {\n    font-family: \"Benton Sans\", \"Helvetica\", \"sans-serif\";\n    font-size: 14px;\n    font-weight: normal;\n    line-height: 20px;\n  }\n}\n.campaignNextPerk-description--taxDeductable {\n  margin-top: 10px;\n}\n.campaignNextPerk-description + .campaignNextPerk-countries,\n.campaignNextPerk-description + .campaignNextPerk-availability {\n  margin-top: 10px;\n}\n.campaignNextPerk-countries,\n.campaignNextPerk-availability {\n  color: #a8a8a8;\n  font-family: \"Benton Sans Medium\", \"Helvetica\", \"sans-serif\";\n  font-size: 12px;\n  line-height: 18px;\n  font-weight: normal;\n  letter-spacing: 0;\n}\n.campaignNextPerk-delivery {\n  width: 100%;\n  border: none;\n  background-color: #fafafa !important;\n  color: #6a6a6a;\n  border-radius: 0;\n  /*override*/\n}\n.campaignNextPerk-cta {\n  width: 100%;\n}\n@media not all and (min-width: 768px) {\n  .campaignNextPerk {\n    margin-left: 20px;\n    margin-right: 20px;\n  }\n  .campaignNextPerk .campaignNextPerk-cta {\n    display: none;\n  }\n  .campaignNextPerk-descriptionWithMeta {\n    max-height: 8ex;\n    overflow: hidden;\n    position: relative;\n  }\n  .campaignNextPerk-descriptionWithMetaOverlay {\n    position: absolute;\n    left: 0;\n    right: 0;\n    top: 0;\n    bottom: 0;\n    background: linear-gradient(180deg, rgba(255, 255, 255, 0), #ffffff);\n  }\n  .campaignNextPerk--expanded .campaignNextPerk-descriptionWithMeta {\n    max-height: 100ex;\n  }\n  .campaignNextPerk--expanded .campaignNextPerk-descriptionWithMetaOverlay {\n    display: none;\n  }\n  .campaignNextPerk--expanded .campaignNextPerk-cta {\n    display: block;\n  }\n  .campaignNextPerk--expanded .campaignNextPerk-delivery {\n    display: none;\n  }\n}\n@media (min-width: 768px) {\n  .campaignNextPerk-cta {\n    display: none;\n  }\n  .campaignNextPerk:hover {\n    border-color: #6a6a6a;\n    cursor: pointer;\n  }\n  .campaignNextPerk:hover .campaignNextPerk-cta {\n    box-shadow: 0 -5px 20px #ffffff;\n    border-radius: 0;\n    position: absolute;\n    bottom: 0;\n    left: 0;\n    display: block;\n  }\n}\n", ""]);
	
	// exports


/***/ },

/***/ 1435:
/***/ function(module, exports) {

	module.exports = "<div class=\"campaignNextPerk\" ng-class=\"{'campaignNextPerk--unavailable': visibleState('unavailable'), 'campaignNextPerk--expanded': expanded }\">\n  <div class=\"campaignNextPerk-featured\" ng-if=\"visibleState('featured')\" gogo-test=\"perk-featured\">\n    {{::i18n.t('featured')}}\n  </div>\n\n  <div class=\"campaignNextPerk-soldout\" ng-if=\"visibleState('sold_out')\" gogo-test=\"perk-soldout\">\n   {{::i18n.t('sold_out')}}\n  </div>\n\n  <div class=\"campaignNextPerk-secret\" ng-if=\"visibleState('secret')\">\n   {{::i18n.t('secret_perk.secret_perk')}}\n  </div>\n\n  <img ng-if=\"perk.perk_image_public_id\" class=\"campaignNextPerk-image\"\n       cl-image width=\"304\" height=\"230\" crop=\"fill\"\n       public-id=\"perk.perk_image_public_id\" alt=\"{{i18n.t('upload_an_image')}}\"/>\n\n  <div class=\"campaignNextPerk-body\" ng-click=\"clickPerkBody()\" gogo-test=\"card\">\n    <div class=\"campaignNextPerk-amountWithCurrency\">\n      <div class=\"campaignNextPerk-amount\" gogo-test=\"perk-amount\">\n        {{campaign.currency.symbol}}{{perk.amount}}\n      </div>\n      <div class=\"campaignNextPerk-amountMeta\" gogo-test=\"perk-currency\">{{campaign.currency.iso_code}}</div>\n      <div class=\"campaignNextPerk-amountMeta\" gogo-test=\"perk-shipping-fee\" ng-if=\"perk.isShippingLabelDisplayed()\">+ {{i18n.t('contribution_flow.shipping')}}</div>\n    </div>\n\n    <div class=\"campaignNextPerk-discount\" ng-if=\"discountPercent\" gogo-test=\"perk-discount\">\n      <span class=\"campaignNextPerk-retailAmount\">\n        {{perk.retail_amount| currency:currency.symbol:0}}\n      </span>\n      ({{i18n.t('campaign_page_next.percent_off', {percentage: discountPercent})}})\n    </div>\n\n    <div class=\"campaignNextPerk-label\" gogo-test=\"perk-label\">{{perk.label}}</div>\n    <div class=\"campaignNextPerk-descriptionWithMeta\">\n      <div class=\"campaignNextPerk-descriptionWithMetaOverlay\"></div>\n      <div class=\"campaignNextPerk-description\" gogo-test=\"perk-description\">{{perk.description}}</div>\n      <div ng-if=\"perk.use_non_tax_deductible_amount && perk.non_tax_deductible_amount\" class=\"campaignNextPerk-description campaignNextPerk-description--taxDeductable\" gogo-test=\"perk-taxDeductable\">\n        {{i18n.t('amount_over_x_is_tax_deductible', {non_tax_deductible_amount: perk.non_tax_deductible_amount})}}\n      </div>\n      <div ng-if=\"showPerkItems && perk.perk_item_links && perk.perk_item_links.length > 0\">\n        <campaign-next-perk-items perk-item-links=\"perk.perk_item_links\"></campaign-next-perk-items>\n      </div>\n      <div class=\"campaignNextPerk-availability\" ng-bind=\"perksClaimed()\" gogo-test=\"perk-availability\"></div>\n      <ships-to-countries gogo-test=\"perk-ships\" ng-if=\"perk.hasShippingObject()\"\n                          label-text=\"{{::i18n.t('contribution_flow.line_items.ships_to')}}\"\n                          option-perk=\"::perk\"\n                          class=\"campaignNextPerk-countries\"></ships-to-countries>\n    </div>\n  </div>\n  <div class=\"campaignNextPerk-delivery i-cta-1\" gogo-test=\"perk-shipping\" ng-click=\"clickPerkCta()\" ng-if=\"perk.shipping_now\">\n    {{::i18n.t('perk_store.shipping_now')}}\n  </div>\n  <div class=\"campaignNextPerk-delivery i-cta-1\" ng-bind=\"estimatedDeliveryMonthYear()\" gogo-test=\"perk-shipping\" ng-click=\"clickPerkCta()\" ng-if=\"!perk.shipping_now && perk.estimated_delivery_date\"></div>\n  <div class=\"campaignNextPerk-cta i-cta-1\" gogo-test=\"cta\" ng-click=\"clickPerkCta()\">\n    <span ng-if=\"perk.shipping_now\">\n      {{::i18n.t('pre_order_page.buy_now')}}\n    </span>\n    <span ng-if=\"!perk.shipping_now\">\n      {{::i18n.t('contribution_flow.get_this_perk')}}\n    </span>\n  </div>\n</div>\n";

/***/ },

/***/ 1436:
/***/ function(module, exports) {

	module.exports = "<div class=\"modal i-modal\">\n  <div class=\"modal-dialog\">\n    <div class=\"modal-content perkPreferencesModal\">\n      <div ng-if=\"perkPrefs.items\">\n        {{perkPrefs.items}}\n      </div>\n    </div>\n  </div>\n</div>\n";

/***/ },

/***/ 1437:
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	
	campaignNextPerkItems.$inject = ["i18n", "$sce"];
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	exports.default = campaignNextPerkItems;
	
	__webpack_require__(1438);
	
	/*@ngInject*/
	
	function campaignNextPerkItems(i18n, $sce) {
	  return {
	    template: __webpack_require__(1440),
	    scope: {
	      perkItemLinks: '='
	    },
	    link: function link(scope) {
	      var magicNumberCutOff = 5;
	
	      var numberOfVisibleItems = function numberOfVisibleItems() {
	        if (scope.perkItemLinks.length > magicNumberCutOff) {
	          return magicNumberCutOff - 1;
	        }
	        return scope.perkItemLinks.length;
	      };
	
	      var perkItemLinksToHover = function perkItemLinksToHover() {
	        return scope.perkItemLinks.slice(numberOfVisibleItems());
	      };
	
	      scope.title = i18n.t('campaign_page_next.perks.items_included');
	      scope.perkItemLinksToDisplay = function () {
	        return scope.perkItemLinks.slice(0, numberOfVisibleItems());
	      };
	      scope.perkItemLinksToHover = perkItemLinksToHover;
	      scope.showAndMoreText = function () {
	        return perkItemLinksToHover().length > 0;
	      };
	      scope.andMoreText = function () {
	        var html = i18n.t('campaign_page_next.perks.and_so_many_more_items', { number: perkItemLinksToHover().length });
	        return $sce.trustAsHtml(html);
	      };
	    }
	  };
	}

/***/ },

/***/ 1438:
/***/ function(module, exports, __webpack_require__) {

	// style-loader: Adds some css to the DOM by adding a <style> tag
	
	// load the styles
	var content = __webpack_require__(1439);
	if(typeof content === 'string') content = [[module.id, content, '']];
	// add the styles to the DOM
	var update = __webpack_require__(80)(content, {});
	if(content.locals) module.exports = content.locals;
	// Hot Module Replacement
	if(false) {
		// When the styles change, update the <style> tags
		if(!content.locals) {
			module.hot.accept("!!./../node_modules/css-loader/index.js!./../node_modules/less-loader/index.js!./campaign-next-perk-items.less", function() {
				var newContent = require("!!./../node_modules/css-loader/index.js!./../node_modules/less-loader/index.js!./campaign-next-perk-items.less");
				if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];
				update(newContent);
			});
		}
		// When the module is disposed, remove the <style> tags
		module.hot.dispose(function() { update(); });
	}

/***/ },

/***/ 1439:
/***/ function(module, exports, __webpack_require__) {

	exports = module.exports = __webpack_require__(79)();
	// imports
	
	
	// module
	exports.push([module.id, "/* Antenna Font Family Variations */\n/* Benton Font Family Variations */\n/** Perk Store mobile header text **/\n/** Only mobile campaign/contributions **/\n/* We can define top-left-dimple or left-top-dimple etc as necessary */\n.raised-sizing {\n  font-family: \"Benton Sans\", \"Helvetica\", \"sans-serif\";\n  font-size: 12px;\n  font-weight: normal;\n  line-height: 18px;\n}\n@media (min-width: 1002px) {\n  .raised-sizing {\n    font-family: \"Benton Sans\", \"Helvetica\", \"sans-serif\";\n    font-size: 16px;\n    font-weight: normal;\n    line-height: 26px;\n    letter-spacing: 0;\n    line-height: 25px;\n  }\n}\n.amount-sizing {\n  font-family: \"Benton Sans\", \"Helvetica\", \"sans-serif\";\n  font-weight: bold;\n  font-size: 14px;\n  line-height: 20px;\n}\n@media (min-width: 1002px) {\n  .amount-sizing {\n    font-family: \"Benton Sans\", \"Helvetica\", \"sans-serif\";\n    font-size: 20px;\n    font-weight: bold;\n    line-height: 26px;\n  }\n}\n@media (min-width: 1002px) {\n  .video-heights-for-2-columns {\n    height: 415px;\n  }\n}\n@media (min-width: 1280px) {\n  .video-heights-for-2-columns {\n    height: 460px !important;\n  }\n}\n.campaignNextPerkItems {\n  margin-top: 20px;\n  margin-bottom: 20px;\n}\n.campaignNextPerkItems li {\n  list-style: disc inside;\n}\n", ""]);
	
	// exports


/***/ },

/***/ 1440:
/***/ function(module, exports) {

	module.exports = "<div class=\"campaignNextPerkItems\">\n  {{title}}:\n  <ul>\n    <li class=\"campaignNextPerkItem-name\" ng-repeat=\"itemLink in perkItemLinksToDisplay()\">\n      {{itemLink.perk_item.name}}\n    </li>\n    <li ng-if=\"showAndMoreText()\">\n      <div placement=\"top\" igg-popover html=\"{{andMoreText()}}\"><div ng-repeat=\"itemLink in perkItemLinksToHover()\">{{itemLink.perk_item.name}}</div></div>\n    </li>\n  </ul>\n</div>\n";

/***/ },

/***/ 1441:
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	
	campaignOldPerk.$inject = ["campaign", "campaignAnalyticsService"];
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	exports.default = campaignOldPerk;
	
	__webpack_require__(1442);
	
	/*@ngInject*/
	
	function campaignOldPerk(campaign, campaignAnalyticsService) {
	  return {
	    template: __webpack_require__(1444),
	    scope: {
	      perk: '=',
	      contributionPath: '='
	    },
	    link: function link(scope) {
	      scope.campaign = campaign;
	      scope.perkStyling = {
	        'campaignOldPerk-highlightHover': !campaign.all_funding_expired,
	        'campaignOldPerk-expired': campaign.all_funding_expired
	      };
	
	      scope.onClick = function () {
	        sendPerkEvent();
	      };
	
	      function sendPerkEvent() {
	        campaignAnalyticsService.sendPerkEvent({
	          gaEventCategory: 'campaign_page_contribute',
	          gaEventAction: 'perk_card'
	        }, {
	          thetaName: "campaign/perk.click",
	          perkId: scope.perk.id,
	          isFeatured: scope.perk.featured,
	          isSecret: scope.perk.secret,
	          hasShipping: scope.perk.shipping_address_required
	        });
	      }
	    }
	  };
	}

/***/ },

/***/ 1442:
/***/ function(module, exports, __webpack_require__) {

	// style-loader: Adds some css to the DOM by adding a <style> tag
	
	// load the styles
	var content = __webpack_require__(1443);
	if(typeof content === 'string') content = [[module.id, content, '']];
	// add the styles to the DOM
	var update = __webpack_require__(80)(content, {});
	if(content.locals) module.exports = content.locals;
	// Hot Module Replacement
	if(false) {
		// When the styles change, update the <style> tags
		if(!content.locals) {
			module.hot.accept("!!./../node_modules/css-loader/index.js!./../node_modules/less-loader/index.js!./campaign-old-perk.less", function() {
				var newContent = require("!!./../node_modules/css-loader/index.js!./../node_modules/less-loader/index.js!./campaign-old-perk.less");
				if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];
				update(newContent);
			});
		}
		// When the module is disposed, remove the <style> tags
		module.hot.dispose(function() { update(); });
	}

/***/ },

/***/ 1443:
/***/ function(module, exports, __webpack_require__) {

	exports = module.exports = __webpack_require__(79)();
	// imports
	
	
	// module
	exports.push([module.id, "/* Antenna Font Family Variations */\n/* Benton Font Family Variations */\n/** Perk Store mobile header text **/\n/** Only mobile campaign/contributions **/\n/* We can define top-left-dimple or left-top-dimple etc as necessary */\n.campaignOldPerk {\n  padding-bottom: 15px;\n}\n.campaignOldPerk-highlightHover.active .perkItem,\n.campaignOldPerk-highlightHover:hover .perkItem {\n  cursor: pointer;\n  background-color: #fafafa;\n}\n.campaignOldPerk-expired .perkItem {\n  background-color: #fafafa;\n}\n", ""]);
	
	// exports


/***/ },

/***/ 1444:
/***/ function(module, exports) {

	module.exports = "<div class=\"campaignOldPerk perkItem-campaignPerkContainer\">\n  <perk ng-click=\"onClick()\"\n        perk=\"::perk\"\n        ng-class=\"perkStyling\"\n        cta-link=\"{{contributionPath + perk.id}}\"\n        shipping-now-campaign=\"campaign.is_shipping_now_campaign\"\n        preorder-perk-campaign=\"campaign.is_pre_order_campaign\"\n        invalid-yet-live-campaign=\"campaign.funding_invalid_yet_live\"\n        indemand-campaign=\"campaign.isInDemand()\"\n        all-funding-expired=\"campaign.all_funding_expired\"\n        tech-design-restyled-campaign=\"campaign.isTechDesignRestyled()\">\n    <perk-title></perk-title>\n    <perk-description></perk-description>\n    <ships-to-countries ng-if=\"perk.hasShippingObject()\"\n                        label-text=\"{{::i18n.t('contribution_flow.line_items.ships_to')}}\"\n                        option-perk=\"::perk\"\n                        desktop-and-more=\"HOVER\"\n                        mobile-and-more=\"CLICK\"\n                        class=\"perkItem-shipsTo\"></ships-to-countries>\n  </perk>\n</div>\n";

/***/ },

/***/ 1445:
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	
	campaignNavigation.$inject = ["i18n", "campaign", "campaignAnalyticsService", "campaignLayoutService", "$filter"];
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	exports.default = campaignNavigation;
	
	__webpack_require__(1446);
	
	/*@ngInject*/
	function campaignNavigation(i18n, campaign, campaignAnalyticsService, campaignLayoutService, $filter) {
	  return {
	    restrict: 'E',
	    scope: {
	      inCampaignThumbnailExperiment: '='
	    },
	    template: __webpack_require__(1448),
	    link: function link(scope) {
	      scope.i18n = i18n;
	      scope.campaign = campaign;
	      scope.inPreview = campaignLayoutService.isPreviewLayout;
	      scope.backersCount = campaign.contributions_count;
	      scope.commentsCount = campaign.comments_count;
	      scope.updatesCount = campaign.updates_count;
	
	      scope.campaign_type = campaignAnalyticsService.campaignType();
	      scope.campaign_category = campaignAnalyticsService.defaultAnalyticsAttrs().projectCategory;
	
	      scope.textForState = function (state) {
	        var stateText = i18n.t('campaign_page_next.navigation.' + state);
	        if (state === 'backers' && campaign.contributions_count > 0) {
	          stateText = stateText + ' (' + formatInteger(campaign.contributions_count) + ')';
	        }
	        if (state === 'comments' && campaign.comments_count > 0) {
	          stateText = stateText + ' (' + formatInteger(campaign.comments_count) + ')';
	        }
	        if (state === 'updates' && campaign.updates_count > 0) {
	          stateText = stateText + ' (' + formatInteger(campaign.updates_count) + ')';
	        }
	        return stateText;
	      };
	
	      function formatInteger(integer) {
	        return $filter('number')(integer, 0);
	      }
	    }
	  };
	}

/***/ },

/***/ 1446:
/***/ function(module, exports, __webpack_require__) {

	// style-loader: Adds some css to the DOM by adding a <style> tag
	
	// load the styles
	var content = __webpack_require__(1447);
	if(typeof content === 'string') content = [[module.id, content, '']];
	// add the styles to the DOM
	var update = __webpack_require__(80)(content, {});
	if(content.locals) module.exports = content.locals;
	// Hot Module Replacement
	if(false) {
		// When the styles change, update the <style> tags
		if(!content.locals) {
			module.hot.accept("!!./../node_modules/css-loader/index.js!./../node_modules/less-loader/index.js!./campaign-navigation.less", function() {
				var newContent = require("!!./../node_modules/css-loader/index.js!./../node_modules/less-loader/index.js!./campaign-navigation.less");
				if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];
				update(newContent);
			});
		}
		// When the module is disposed, remove the <style> tags
		module.hot.dispose(function() { update(); });
	}

/***/ },

/***/ 1447:
/***/ function(module, exports, __webpack_require__) {

	exports = module.exports = __webpack_require__(79)();
	// imports
	
	
	// module
	exports.push([module.id, "/* Antenna Font Family Variations */\n/* Benton Font Family Variations */\n/** Perk Store mobile header text **/\n/** Only mobile campaign/contributions **/\n/* We can define top-left-dimple or left-top-dimple etc as necessary */\n.raised-sizing {\n  font-family: \"Benton Sans\", \"Helvetica\", \"sans-serif\";\n  font-size: 12px;\n  font-weight: normal;\n  line-height: 18px;\n}\n@media (min-width: 1002px) {\n  .raised-sizing {\n    font-family: \"Benton Sans\", \"Helvetica\", \"sans-serif\";\n    font-size: 16px;\n    font-weight: normal;\n    line-height: 26px;\n    letter-spacing: 0;\n    line-height: 25px;\n  }\n}\n.amount-sizing {\n  font-family: \"Benton Sans\", \"Helvetica\", \"sans-serif\";\n  font-weight: bold;\n  font-size: 14px;\n  line-height: 20px;\n}\n@media (min-width: 1002px) {\n  .amount-sizing {\n    font-family: \"Benton Sans\", \"Helvetica\", \"sans-serif\";\n    font-size: 20px;\n    font-weight: bold;\n    line-height: 26px;\n  }\n}\n@media (min-width: 1002px) {\n  .video-heights-for-2-columns {\n    height: 415px;\n  }\n}\n@media (min-width: 1280px) {\n  .video-heights-for-2-columns {\n    height: 460px !important;\n  }\n}\n.body-section-header-text-sizing {\n  font-family: \"Benton Sans\", \"Helvetica\", \"sans-serif\";\n  font-size: 14px;\n  font-weight: normal;\n  line-height: 20px;\n}\n@media (min-width: 1280px) {\n  .body-section-header-text-sizing {\n    font-family: \"Benton Sans\", \"Helvetica\", \"sans-serif\";\n    font-size: 16px;\n    font-weight: normal;\n    line-height: 26px;\n    letter-spacing: 0;\n  }\n}\n.body-sub-section-header-title {\n  font-family: \"Benton Sans\", \"Helvetica\", \"sans-serif\";\n  font-size: 14px;\n  font-weight: normal;\n  line-height: 20px;\n  color: #a8a8a8;\n  margin-top: 20px;\n  margin-bottom: 20px;\n  padding-top: 5px;\n  padding-bottom: 5px;\n  text-transform: uppercase;\n  border-bottom: 1px solid #dddddd;\n}\n@media (min-width: 1280px) {\n  .body-sub-section-header-title {\n    font-family: \"Benton Sans\", \"Helvetica\", \"sans-serif\";\n    font-size: 16px;\n    font-weight: normal;\n    line-height: 26px;\n    letter-spacing: 0;\n  }\n}\n@media not all and (min-width: 768px) {\n  .body-sub-section-header-title {\n    margin-left: 20px;\n    margin-right: 20px;\n  }\n}\n.campaignNavigation-items {\n  border-bottom: 1px solid #dddddd;\n}\n.campaignNavigation-items li {\n  display: inline-block;\n  text-transform: uppercase;\n  padding-top: 5px;\n  padding-bottom: 5px;\n  font-family: \"Benton Sans\", \"Helvetica\", \"sans-serif\";\n  font-size: 14px;\n  font-weight: normal;\n  line-height: 20px;\n}\n@media (min-width: 1280px) {\n  .campaignNavigation-items li {\n    font-family: \"Benton Sans\", \"Helvetica\", \"sans-serif\";\n    font-size: 16px;\n    font-weight: normal;\n    line-height: 26px;\n    letter-spacing: 0;\n  }\n}\n.campaignNavigation-items li:not(:first-child) {\n  padding-left: 10px;\n}\n.campaignNavigation-item {\n  color: #a8a8a8;\n}\n.campaignNavigation-item:focus,\n.campaignNavigation-item:hover,\n.campaignNavigation-item--active {\n  color: #eb1478;\n  text-decoration: none;\n}\n.campaignNavigation-item--active {\n  font-weight: bold;\n}\n.campaignNavigation-item--disabled {\n  pointer-events: none;\n}\n", ""]);
	
	// exports


/***/ },

/***/ 1448:
/***/ function(module, exports) {

	module.exports = "<div class=\"campaignNavigation\">\n  <ul class=\"campaignNavigation-items\">\n    <li>\n      <a class=\"campaignNavigation-item\"\n         gogo-test=\"navigation-story\"\n         ui-sref=\"main\"\n         ui-sref-active=\"campaignNavigation-item--active\"\n         analytics-on=\"click\"\n         analytics-name=\"campaign/story.link\"\n         analytics-category=\"campaign_page_tabs\"\n         analytics-event=\"story\"\n         analytics-label=\"{{campaign_type}}_{{campaign_category}}\">\n        {{::textForState('story')}}\n      </a>\n    </li>\n    <li>\n      <a class=\"campaignNavigation-item\"\n         ng-class=\"{'campaignNavigation-item--disabled': inPreview()}\"\n         gogo-test=\"navigation-updates\"\n         ui-sref=\"updates\"\n         ui-sref-active=\"campaignNavigation-item--active\"\n         analytics-on=\"click\"\n         analytics-name=\"campaign/updates.link\"\n         analytics-category=\"campaign_page_tabs\"\n         analytics-event=\"updates\"\n         analytics-label=\"{{campaign_type}}_{{campaign_category}}\">\n        {{::textForState('updates')}}\n      </a>\n    </li>\n    <li>\n      <a class=\"campaignNavigation-item\"\n         ng-class=\"{'campaignNavigation-item--disabled': inPreview()}\"\n         gogo-test=\"navigation-comments\"\n         ui-sref=\"comments\"\n         ui-sref-active=\"campaignNavigation-item--active\"\n         analytics-on=\"click\"\n         analytics-name=\"campaign/comments.link\"\n         analytics-category=\"campaign_page_tabs\"\n         analytics-event=\"comments\"\n         analytics-label=\"{{campaign_type}}_{{campaign_category}}\">\n        {{::textForState('comments')}}\n      </a>\n    </li>\n    <li>\n      <a class=\"campaignNavigation-item\"\n         ng-class=\"{'campaignNavigation-item--disabled': inPreview()}\"\n         gogo-test=\"navigation-backers\"\n         ui-sref=\"backers\"\n         ui-sref-active=\"campaignNavigation-item--active\"\n         analytics-on=\"click\"\n         analytics-name=\"campaign/backers.link\"\n         analytics-category=\"campaign_page_tabs\"\n         analytics-event=\"backers\"\n         analytics-label=\"{{campaign_type}}_{{campaign_category}}\">\n        {{::textForState('backers')}}\n      </a>\n    </li>\n    <li ng-if=\"campaign.gallery_available && !inCampaignThumbnailExperiment\">\n      <a class=\"campaignNavigation-item\"\n         gogo-test=\"navigation-gallery\"\n         ui-sref=\"gallery\"\n         ui-sref-active=\"campaignNavigation-item--active\"\n         analytics-on=\"click\"\n         analytics-name=\"campaign/gallery.link\"\n         analytics-category=\"campaign_page_tabs\"\n         analytics-event=\"gallery\"\n         analytics-label=\"{{campaign_type}}_{{campaign_category}}\">\n        {{::textForState('gallery')}}\n      </a>\n    </li>\n  </ul>\n</div>\n";

/***/ },

/***/ 1449:
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	
	campaignAccordion.$inject = ["i18n", "$state", "$rootScope", "$timeout", "campaign", "$filter", "campaignLayoutService"];
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	exports.default = campaignAccordion;
	
	__webpack_require__(1450);
	
	/*@ngInject*/
	function campaignAccordion(i18n, $state, $rootScope, $timeout, campaign, $filter, campaignLayoutService) {
	  return {
	    restrict: 'E',
	    scope: {
	      inCampaignThumbnailExperiment: '='
	    },
	    template: __webpack_require__(1452),
	    link: function link(scope) {
	      scope.i18n = i18n;
	
	      scope.states = ['updates', 'comments', 'backers', 'gallery'];
	
	      scope.textForState = function (state) {
	        var stateText = i18n.t('campaign_page_next.navigation.' + state);
	        if (state === 'backers' && campaign.contributions_count > 0) {
	          stateText = stateText + ' (' + formatInteger(campaign.contributions_count) + ')';
	        }
	        if (state === 'comments' && campaign.comments_count > 0) {
	          stateText = stateText + ' (' + formatInteger(campaign.comments_count) + ')';
	        }
	        if (state === 'updates' && campaign.updates_count > 0) {
	          stateText = stateText + ' (' + formatInteger(campaign.updates_count) + ')';
	        }
	        return stateText;
	      };
	
	      scope.isStateActive = function (state) {
	        return $state.includes(state);
	      };
	
	      scope.navigateTo = function (state) {
	        $timeout(function () {
	          if ($state.includes(state)) {
	            $state.go('main');
	          } else {
	            $state.go(state);
	          }
	        });
	      };
	
	      scope.showState = function (state) {
	        if (state === 'gallery') {
	          return campaign.gallery_available && !scope.inCampaignThumbnailExperiment;
	        } else {
	          return true;
	        }
	      };
	
	      scope.inPreview = campaignLayoutService.isPreviewLayout;
	
	      function formatInteger(integer) {
	        return $filter('number')(integer, 0);
	      }
	    }
	  };
	}

/***/ },

/***/ 1450:
/***/ function(module, exports, __webpack_require__) {

	// style-loader: Adds some css to the DOM by adding a <style> tag
	
	// load the styles
	var content = __webpack_require__(1451);
	if(typeof content === 'string') content = [[module.id, content, '']];
	// add the styles to the DOM
	var update = __webpack_require__(80)(content, {});
	if(content.locals) module.exports = content.locals;
	// Hot Module Replacement
	if(false) {
		// When the styles change, update the <style> tags
		if(!content.locals) {
			module.hot.accept("!!./../node_modules/css-loader/index.js!./../node_modules/less-loader/index.js!./campaign-accordion.less", function() {
				var newContent = require("!!./../node_modules/css-loader/index.js!./../node_modules/less-loader/index.js!./campaign-accordion.less");
				if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];
				update(newContent);
			});
		}
		// When the module is disposed, remove the <style> tags
		module.hot.dispose(function() { update(); });
	}

/***/ },

/***/ 1451:
/***/ function(module, exports, __webpack_require__) {

	exports = module.exports = __webpack_require__(79)();
	// imports
	
	
	// module
	exports.push([module.id, "/* Antenna Font Family Variations */\n/* Benton Font Family Variations */\n/** Perk Store mobile header text **/\n/** Only mobile campaign/contributions **/\n/* We can define top-left-dimple or left-top-dimple etc as necessary */\n.campaignAccordion li {\n  transition: all 0.3s;\n  min-height: 5px;\n}\n.campaignAccordion li.active {\n  min-height: 10em;\n}\n.campaignAccordion li:last-child .campaignAccordion-item {\n  border-bottom: 1px solid #dddddd;\n}\n.campaignAccordion-item {\n  display: box;\n  display: -webkit-flex;\n  display: -moz-flex;\n  display: -ms-flexbox;\n  display: -ms-flex;\n  display: flex;\n  box-pack: justify;\n  -ms-flex-pack: justify;\n  -webkit-justify-content: space-between;\n  -moz-justify-content: space-between;\n  -ms-justify-content: space-between;\n  justify-content: space-between;\n  box-align: center;\n  -ms-flex-align: center;\n  -webkit-align-items: center;\n  -moz-align-items: center;\n  -ms-align-items: center;\n  align-items: center;\n  border-top: 1px solid #dddddd;\n  padding: 5px 20px;\n  text-decoration: none;\n}\n.campaignAccordion-item:focus,\n.campaignAccordion-item:active,\n.campaignAccordion-item:hover {\n  text-decoration: none;\n}\n.campaignAccordion-itemLabel {\n  font-family: \"Benton Sans Medium\", \"Helvetica\", \"sans-serif\";\n  font-size: 16px;\n  line-height: 26px;\n  font-weight: normal;\n  letter-spacing: 0;\n  color: #a8a8a8;\n  text-transform: uppercase;\n}\n.campaignAccordion-item svg-icon {\n  transform: rotate(0deg);\n  transition: all 0.3s;\n}\n.campaignAccordion-item svg {\n  width: 15px;\n  height: 15px;\n  fill: #a8a8a8;\n}\n.campaignAccordion-item--active {\n  border-bottom: 1px solid #dddddd;\n}\n.campaignAccordion-item--active svg-icon {\n  transform: rotate(180deg);\n}\n.campaignAccordion-item--disabled {\n  pointer-events: none;\n}\n.campaignAccordion-itemContent {\n  margin: 10px 20px;\n}\n", ""]);
	
	// exports


/***/ },

/***/ 1452:
/***/ function(module, exports) {

	module.exports = "<div class=\"campaignAccordion\">\n  <ul>\n    <li ng-repeat=\"state in states\" ng-if=\"showState(state)\" ng-class=\"{active: isStateActive(state)}\">\n      <a ng-click=\"navigateTo(state)\"\n         class=\"campaignAccordion-item\"\n         ng-class=\"{'campaignAccordion-item--active': isStateActive(state), 'campaignAccordion-item--disabled': inPreview()}\"\n         gogo-test=\"accordion-{{state}}\">\n        <div class=\"campaignAccordion-itemLabel\">\n          {{textForState(state)}}\n        </div>\n        <svg-icon icon=\"down-caret\"></svg-icon>\n      </a>\n      <div class=\"campaignAccordion-itemContent\" ui-view ng-if=\"isStateActive(state)\"></div>\n    </li>\n  </ul>\n</div>\n";

/***/ },

/***/ 1453:
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	
	campaignDescription.$inject = ["$http", "campaign", "$sce"];
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	exports.default = campaignDescription;
	
	__webpack_require__(1454);
	
	var _privateApi = __webpack_require__(186);
	
	/*@ngInject*/
	function campaignDescription($http, campaign, $sce) {
	  return {
	    restrict: 'E',
	    scope: {},
	    template: '<div class="campaignDescription ugcContent" ng-bind-html="description_html"></div>',
	    link: function link(scope) {
	      scope.description_html = '';
	      var resetMaxWidth = function resetMaxWidth(html) {
	        return html.replace(/max-width:.*?px;?/g, '');
	      };
	
	      $http.get((0, _privateApi.descriptionPrivateApiCampaignPath)({ id: campaign.id })).then(function (response) {
	        if (_.get(response, 'data.response')) {
	          scope.description_html = $sce.trustAsHtml(resetMaxWidth(response.data.response.description_html));
	        }
	      });
	    }
	  };
	}

/***/ },

/***/ 1454:
/***/ function(module, exports, __webpack_require__) {

	// style-loader: Adds some css to the DOM by adding a <style> tag
	
	// load the styles
	var content = __webpack_require__(1455);
	if(typeof content === 'string') content = [[module.id, content, '']];
	// add the styles to the DOM
	var update = __webpack_require__(80)(content, {});
	if(content.locals) module.exports = content.locals;
	// Hot Module Replacement
	if(false) {
		// When the styles change, update the <style> tags
		if(!content.locals) {
			module.hot.accept("!!./../node_modules/css-loader/index.js!./../node_modules/less-loader/index.js!./campaign-description.less", function() {
				var newContent = require("!!./../node_modules/css-loader/index.js!./../node_modules/less-loader/index.js!./campaign-description.less");
				if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];
				update(newContent);
			});
		}
		// When the module is disposed, remove the <style> tags
		module.hot.dispose(function() { update(); });
	}

/***/ },

/***/ 1455:
/***/ function(module, exports, __webpack_require__) {

	exports = module.exports = __webpack_require__(79)();
	// imports
	
	
	// module
	exports.push([module.id, "/* Antenna Font Family Variations */\n/* Benton Font Family Variations */\n/** Perk Store mobile header text **/\n/** Only mobile campaign/contributions **/\n/* We can define top-left-dimple or left-top-dimple etc as necessary */\n.campaignDescription iframe {\n  width: 100%;\n  height: 225px;\n}\n@media (min-width: 1002px) {\n  .campaignDescription {\n    margin-left: auto;\n    margin-right: auto;\n    margin-top: 15px;\n    max-width: 620px;\n  }\n  .campaignDescription iframe {\n    width: 620px;\n    height: 415px;\n  }\n}\n.campaignDescription img {\n  max-width: 100% !important;\n}\n.campaignDescription iframe {\n  max-width: 100% !important;\n  border: 0;\n}\n", ""]);
	
	// exports


/***/ },

/***/ 1456:
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	
	campaignSponsorBadge.$inject = ["i18n"];
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	
	__webpack_require__(1457);
	
	/*@ngInject*/
	function campaignSponsorBadge(i18n) {
	  return {
	    restrict: 'E',
	    scope: {
	      sponsor: '='
	    },
	    template: __webpack_require__(1459),
	    link: function link(scope) {
	      scope.viewInfoText = i18n.t('campaign_page_next.trust.view_info');
	    }
	  };
	}
	
	exports.default = campaignSponsorBadge;

/***/ },

/***/ 1457:
/***/ function(module, exports, __webpack_require__) {

	// style-loader: Adds some css to the DOM by adding a <style> tag
	
	// load the styles
	var content = __webpack_require__(1458);
	if(typeof content === 'string') content = [[module.id, content, '']];
	// add the styles to the DOM
	var update = __webpack_require__(80)(content, {});
	if(content.locals) module.exports = content.locals;
	// Hot Module Replacement
	if(false) {
		// When the styles change, update the <style> tags
		if(!content.locals) {
			module.hot.accept("!!./../node_modules/css-loader/index.js!./../node_modules/less-loader/index.js!./campaign-sponsor-badge.less", function() {
				var newContent = require("!!./../node_modules/css-loader/index.js!./../node_modules/less-loader/index.js!./campaign-sponsor-badge.less");
				if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];
				update(newContent);
			});
		}
		// When the module is disposed, remove the <style> tags
		module.hot.dispose(function() { update(); });
	}

/***/ },

/***/ 1458:
/***/ function(module, exports, __webpack_require__) {

	exports = module.exports = __webpack_require__(79)();
	// imports
	
	
	// module
	exports.push([module.id, "/* Antenna Font Family Variations */\n/* Benton Font Family Variations */\n/** Perk Store mobile header text **/\n/** Only mobile campaign/contributions **/\n/* We can define top-left-dimple or left-top-dimple etc as necessary */\n.campaignSponsorBadge {\n  display: box;\n  display: -webkit-flex;\n  display: -moz-flex;\n  display: -ms-flexbox;\n  display: -ms-flex;\n  display: flex;\n  box-align: center;\n  -ms-flex-align: center;\n  -webkit-align-items: center;\n  -moz-align-items: center;\n  -ms-align-items: center;\n  align-items: center;\n  margin-bottom: 20px;\n}\n.campaignSponsorBadge-avatar {\n  border-radius: 50%;\n  min-width: 50px;\n  height: 50px;\n}\n.campaignSponsorBadge-details {\n  margin-left: 15px;\n  color: #6a6a6a;\n  box-flex: 1;\n  -webkit-flex: 1;\n  -moz-flex: 1;\n  -ms-flex: 1;\n  flex: 1;\n  font-family: \"Benton Sans Medium\", \"Helvetica\", \"sans-serif\";\n  font-size: 12px;\n  line-height: 18px;\n  font-weight: normal;\n  letter-spacing: 0;\n}\n.campaignSponsorBadge-details-link {\n  color: #eb1478;\n  font-family: \"Benton Sans\", \"Helvetica\", \"sans-serif\";\n  font-size: 12px;\n  font-weight: normal;\n  line-height: 18px;\n}\n", ""]);
	
	// exports


/***/ },

/***/ 1459:
/***/ function(module, exports) {

	module.exports = "<div class=\"campaignSponsorBadge\" gogo-test=\"sponsor_badge_trust_passport\">\n  <img class=\"campaignSponsorBadge-avatar\" cl-image width=\"50\" height=\"50\" crop=\"fill\" public-id=\"sponsor.image_public_id\">\n  <div class=\"campaignSponsorBadge-details\">\n    <div gogo-test=\"sponsor_badge_name\">{{sponsor.name}}</div>\n    <a class=\"campaignSponsorBadge-details-link\" ng-href=\"{{sponsor.landing_page}}\">{{::viewInfoText}}</a>\n  </div>\n</div>\n";

/***/ },

/***/ 1460:
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	
	campaignSupportedBy.$inject = ["campaign", "i18n"];
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	
	/*@ngInject*/
	function campaignSupportedBy(campaign, i18n) {
	  return {
	    restrict: 'E',
	    scope: {},
	    template: __webpack_require__(1461),
	    link: function link(scope) {
	      var hasPartner = function hasPartner() {
	        return campaign.partner_connected && campaign.partner.visible;
	      };
	      var hasSponsor = function hasSponsor() {
	        return campaign.project_sponsors.length > 0;
	      };
	
	      scope.supportedByTitle = i18n.t('campaign_page_next.trust.supported_by');
	      scope.showSupportedBy = function () {
	        return hasPartner() || hasSponsor();
	      };
	      scope.sponsors = function () {
	        return campaign.sponsorsWhereLevelGreaterThan(0);
	      };
	      scope.partners = function () {
	        return hasPartner() ? [campaign.partner] : [];
	      };
	    }
	  };
	}
	
	exports.default = campaignSupportedBy;

/***/ },

/***/ 1461:
/***/ function(module, exports) {

	module.exports = "<div ng-if=\"showSupportedBy()\" class=\"campaignTrustInfo-section campaignTrustInfo-section-partner\">\n  <div class=\"campaignTrustInfo-sectionTitle\">{{::supportedByTitle}}</div>\n  <div class=\"campaignTrustInfo-sectionContent\">\n    <campaign-sponsor-badge ng-repeat=\"sponsor in sponsors()\" sponsor=\"sponsor\"></campaign-sponsor-badge>\n    <campaign-partner-badge ng-repeat=\"partner in partners()\" partner=\"partner\"></campaign-partner-badge>\n  </div>\n</div>\n";

/***/ },

/***/ 1462:
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	exports.default = share;
	
	var _shareItemDirective = __webpack_require__(1463);
	
	var _shareItemDirective2 = _interopRequireDefault(_shareItemDirective);
	
	var _shareFacebookDirective = __webpack_require__(1467);
	
	var _shareFacebookDirective2 = _interopRequireDefault(_shareFacebookDirective);
	
	var _shareTwitterDirective = __webpack_require__(1469);
	
	var _shareTwitterDirective2 = _interopRequireDefault(_shareTwitterDirective);
	
	var _shareCopyLinkDirective = __webpack_require__(1471);
	
	var _shareCopyLinkDirective2 = _interopRequireDefault(_shareCopyLinkDirective);
	
	function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
	
	function share(angular) {
	  angular.module('indiegogo.components.share', ['utils']).directive('shareItem', _shareItemDirective2.default).directive('shareFacebook', _shareFacebookDirective2.default).directive('shareTwitter', _shareTwitterDirective2.default).directive('shareCopyLink', _shareCopyLinkDirective2.default);
	}

/***/ },

/***/ 1463:
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	exports.default = shareItem;
	
	__webpack_require__(1464);
	
	function shareItem() {
	  return {
	    restrict: 'E',
	    scope: {
	      icon: "@icon",
	      hoverLabel: '@hoverLabel'
	    },
	    template: __webpack_require__(1466)
	  };
	}

/***/ },

/***/ 1464:
/***/ function(module, exports, __webpack_require__) {

	// style-loader: Adds some css to the DOM by adding a <style> tag
	
	// load the styles
	var content = __webpack_require__(1465);
	if(typeof content === 'string') content = [[module.id, content, '']];
	// add the styles to the DOM
	var update = __webpack_require__(80)(content, {});
	if(content.locals) module.exports = content.locals;
	// Hot Module Replacement
	if(false) {
		// When the styles change, update the <style> tags
		if(!content.locals) {
			module.hot.accept("!!./../../../node_modules/css-loader/index.js!./../../../node_modules/less-loader/index.js!./_share_item.less", function() {
				var newContent = require("!!./../../../node_modules/css-loader/index.js!./../../../node_modules/less-loader/index.js!./_share_item.less");
				if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];
				update(newContent);
			});
		}
		// When the module is disposed, remove the <style> tags
		module.hot.dispose(function() { update(); });
	}

/***/ },

/***/ 1465:
/***/ function(module, exports, __webpack_require__) {

	exports = module.exports = __webpack_require__(79)();
	// imports
	
	
	// module
	exports.push([module.id, "/* Antenna Font Family Variations */\n/* Benton Font Family Variations */\n/** Perk Store mobile header text **/\n/** Only mobile campaign/contributions **/\n/* We can define top-left-dimple or left-top-dimple etc as necessary */\n.share {\n  white-space: nowrap;\n  overflow: hidden;\n}\n.share-component {\n  display: inline-block;\n}\n.share-component:hover {\n  cursor: pointer;\n  text-decoration: none;\n}\n.share-component:hover .share-hoverLabel {\n  visibility: visible;\n  text-align: center;\n}\n.share-component:hover .share-icon {\n  background-color: #a8a8a8;\n}\n.share-component:hover .share-icon svg {\n  fill: white;\n}\n.share-icon {\n  display: box;\n  display: -webkit-flex;\n  display: -moz-flex;\n  display: -ms-flexbox;\n  display: -ms-flex;\n  display: flex;\n  box-align: center;\n  -ms-flex-align: center;\n  -webkit-align-items: center;\n  -moz-align-items: center;\n  -ms-align-items: center;\n  align-items: center;\n  box-pack: center;\n  -ms-flex-pack: center;\n  -webkit-justify-content: center;\n  -moz-justify-content: center;\n  -ms-justify-content: center;\n  justify-content: center;\n  background-color: white;\n  transition: all 0.3s;\n  border: 2px solid #a8a8a8;\n  border-radius: 50%;\n  width: 40px;\n  height: 40px;\n}\n.share-icon svg {\n  fill: #a8a8a8;\n  width: 22px;\n  height: 22px;\n}\n.share-hoverLabel {\n  font-family: \"Benton Sans\", \"Helvetica\", \"sans-serif\";\n  font-size: 12px;\n  font-weight: bold;\n  line-height: 18px;\n  color: #a8a8a8;\n  visibility: hidden;\n}\n", ""]);
	
	// exports


/***/ },

/***/ 1466:
/***/ function(module, exports) {

	module.exports = "<a class=\"share-component\">\n  <div class=\"share-icon\">\n    <svg><use xlink:href=\"{{icon}}\"></use></svg>\n  </div>\n  <div ng-if='hoverLabel !== undefined' class=\"share-hoverLabel\">{{hoverLabel}}</div>\n</a>\n";

/***/ },

/***/ 1467:
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	exports.default = shareFacebook;
	function shareFacebook(fb, i18n, gon) {
	  return {
	    restrict: 'E',
	    scope: {
	      url: '@url',
	      iggref: '@iggref'
	    },
	    template: __webpack_require__(1468),
	    link: function link(scope) {
	      var currentUserId = function currentUserId() {
	        return gon.current_user ? gon.current_user.id : null;
	      };
	      scope.i18n = i18n;
	      scope.shareFacebook = function () {
	        var shareOptions = { iggref: scope.iggref };
	        if (currentUserId()) {
	          shareOptions.account_id = currentUserId();
	        }
	        fb.share(scope.url, shareOptions);
	      };
	    }
	  };
	}

/***/ },

/***/ 1468:
/***/ function(module, exports) {

	module.exports = "<share-item ng-click=\"shareFacebook()\" icon=\"#icon-icon-facebook\" hover-label=\"{{i18n.t('share')}}\" ></share-item>\n";

/***/ },

/***/ 1469:
/***/ function(module, exports, __webpack_require__) {

	"use strict";
	
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	exports.default = shareTwitter;
	function shareTwitter(twitter) {
	  return {
	    restrict: 'E',
	    scope: {
	      url: "@url",
	      text: "@text",
	      from: "@from"
	    },
	    template: __webpack_require__(1470),
	    link: function link(scope) {
	      scope.shareTwitter = function () {
	        twitter.shareTwitter(scope.url, scope.text, scope.from);
	      };
	    }
	  };
	}

/***/ },

/***/ 1470:
/***/ function(module, exports) {

	module.exports = "<share-item ng-click=\"shareTwitter()\" icon=\"#icon-icon-twitter\" hover-label=\"Tweet\" ></share-item>\n";

/***/ },

/***/ 1471:
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	exports.default = shareCopyLink;
	function shareCopyLink(i18n) {
	  return {
	    restrict: 'E',
	    template: __webpack_require__(1472),
	    link: function link(scope) {
	      scope.i18n = i18n;
	    }
	  };
	}

/***/ },

/***/ 1472:
/***/ function(module, exports) {

	module.exports = "<share-item icon=\"#icon-icon-link\" hover-label=\"{{i18n.t('link')}}\" ></share-item>\n";

/***/ },

/***/ 1473:
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	
	exports.default = function (angular) {
	  angular.module('indiegogo.components.perkPrefs', ['utils']).factory('perkPrefs', _perkPrefService2.default);
	};
	
	var _perkPrefService = __webpack_require__(1474);
	
	var _perkPrefService2 = _interopRequireDefault(_perkPrefService);
	
	function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

/***/ },

/***/ 1474:
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	exports.default = perkPrefs;
	
	var _privateApi = __webpack_require__(186);
	
	function perkPrefs($http) {
	  var items = [];
	
	  function configure(context) {
	    this.context = context;
	  }
	
	  function getItemsForPerk(perkId) {
	    var _this = this;
	
	    return $http.get((0, _privateApi.privateApiPerkItemsPath)({ perkId: perkId })).then(function (response) {
	      _this.items = response.data;
	    });
	  }
	
	  return {
	    contexts: {
	      campaignPage: 'campaignPage',
	      payFlow: 'payFlow'
	    },
	    context: null,
	    configure: configure,
	    getItemsForPerk: getItemsForPerk,
	    items: items
	  };
	} /* @ngInject */

/***/ },

/***/ 1475:
/***/ function(module, exports) {

	/*!
	Waypoints - 3.1.1
	Copyright © 2011-2015 Caleb Troughton
	Licensed under the MIT license.
	https://github.com/imakewebthings/waypoints/blog/master/licenses.txt
	*/
	(function() {
	  'use strict'
	
	  var keyCounter = 0
	  var allWaypoints = {}
	
	  /* http://imakewebthings.com/waypoints/api/waypoint */
	  function Waypoint(options) {
	    if (!options) {
	      throw new Error('No options passed to Waypoint constructor')
	    }
	    if (!options.element) {
	      throw new Error('No element option passed to Waypoint constructor')
	    }
	    if (!options.handler) {
	      throw new Error('No handler option passed to Waypoint constructor')
	    }
	
	    this.key = 'waypoint-' + keyCounter
	    this.options = Waypoint.Adapter.extend({}, Waypoint.defaults, options)
	    this.element = this.options.element
	    this.adapter = new Waypoint.Adapter(this.element)
	    this.callback = options.handler
	    this.axis = this.options.horizontal ? 'horizontal' : 'vertical'
	    this.enabled = this.options.enabled
	    this.triggerPoint = null
	    this.group = Waypoint.Group.findOrCreate({
	      name: this.options.group,
	      axis: this.axis
	    })
	    this.context = Waypoint.Context.findOrCreateByElement(this.options.context)
	
	    if (Waypoint.offsetAliases[this.options.offset]) {
	      this.options.offset = Waypoint.offsetAliases[this.options.offset]
	    }
	    this.group.add(this)
	    this.context.add(this)
	    allWaypoints[this.key] = this
	    keyCounter += 1
	  }
	
	  /* Private */
	  Waypoint.prototype.queueTrigger = function(direction) {
	    this.group.queueTrigger(this, direction)
	  }
	
	  /* Private */
	  Waypoint.prototype.trigger = function(args) {
	    if (!this.enabled) {
	      return
	    }
	    if (this.callback) {
	      this.callback.apply(this, args)
	    }
	  }
	
	  /* Public */
	  /* http://imakewebthings.com/waypoints/api/destroy */
	  Waypoint.prototype.destroy = function() {
	    this.context.remove(this)
	    this.group.remove(this)
	    delete allWaypoints[this.key]
	  }
	
	  /* Public */
	  /* http://imakewebthings.com/waypoints/api/disable */
	  Waypoint.prototype.disable = function() {
	    this.enabled = false
	    return this
	  }
	
	  /* Public */
	  /* http://imakewebthings.com/waypoints/api/enable */
	  Waypoint.prototype.enable = function() {
	    this.context.refresh()
	    this.enabled = true
	    return this
	  }
	
	  /* Public */
	  /* http://imakewebthings.com/waypoints/api/next */
	  Waypoint.prototype.next = function() {
	    return this.group.next(this)
	  }
	
	  /* Public */
	  /* http://imakewebthings.com/waypoints/api/previous */
	  Waypoint.prototype.previous = function() {
	    return this.group.previous(this)
	  }
	
	  /* Private */
	  Waypoint.invokeAll = function(method) {
	    var allWaypointsArray = []
	    for (var waypointKey in allWaypoints) {
	      allWaypointsArray.push(allWaypoints[waypointKey])
	    }
	    for (var i = 0, end = allWaypointsArray.length; i < end; i++) {
	      allWaypointsArray[i][method]()
	    }
	  }
	
	  /* Public */
	  /* http://imakewebthings.com/waypoints/api/destroy-all */
	  Waypoint.destroyAll = function() {
	    Waypoint.invokeAll('destroy')
	  }
	
	  /* Public */
	  /* http://imakewebthings.com/waypoints/api/disable-all */
	  Waypoint.disableAll = function() {
	    Waypoint.invokeAll('disable')
	  }
	
	  /* Public */
	  /* http://imakewebthings.com/waypoints/api/enable-all */
	  Waypoint.enableAll = function() {
	    Waypoint.invokeAll('enable')
	  }
	
	  /* Public */
	  /* http://imakewebthings.com/waypoints/api/refresh-all */
	  Waypoint.refreshAll = function() {
	    Waypoint.Context.refreshAll()
	  }
	
	  /* Public */
	  /* http://imakewebthings.com/waypoints/api/viewport-height */
	  Waypoint.viewportHeight = function() {
	    return window.innerHeight || document.documentElement.clientHeight
	  }
	
	  /* Public */
	  /* http://imakewebthings.com/waypoints/api/viewport-width */
	  Waypoint.viewportWidth = function() {
	    return document.documentElement.clientWidth
	  }
	
	  Waypoint.adapters = []
	
	  Waypoint.defaults = {
	    context: window,
	    continuous: true,
	    enabled: true,
	    group: 'default',
	    horizontal: false,
	    offset: 0
	  }
	
	  Waypoint.offsetAliases = {
	    'bottom-in-view': function() {
	      return this.context.innerHeight() - this.adapter.outerHeight()
	    },
	    'right-in-view': function() {
	      return this.context.innerWidth() - this.adapter.outerWidth()
	    }
	  }
	
	  window.Waypoint = Waypoint
	}())
	;(function() {
	  'use strict'
	
	  function requestAnimationFrameShim(callback) {
	    window.setTimeout(callback, 1000 / 60)
	  }
	
	  var keyCounter = 0
	  var contexts = {}
	  var Waypoint = window.Waypoint
	  var oldWindowLoad = window.onload
	
	  /* http://imakewebthings.com/waypoints/api/context */
	  function Context(element) {
	    this.element = element
	    this.Adapter = Waypoint.Adapter
	    this.adapter = new this.Adapter(element)
	    this.key = 'waypoint-context-' + keyCounter
	    this.didScroll = false
	    this.didResize = false
	    this.oldScroll = {
	      x: this.adapter.scrollLeft(),
	      y: this.adapter.scrollTop()
	    }
	    this.waypoints = {
	      vertical: {},
	      horizontal: {}
	    }
	
	    element.waypointContextKey = this.key
	    contexts[element.waypointContextKey] = this
	    keyCounter += 1
	
	    this.createThrottledScrollHandler()
	    this.createThrottledResizeHandler()
	  }
	
	  /* Private */
	  Context.prototype.add = function(waypoint) {
	    var axis = waypoint.options.horizontal ? 'horizontal' : 'vertical'
	    this.waypoints[axis][waypoint.key] = waypoint
	    this.refresh()
	  }
	
	  /* Private */
	  Context.prototype.checkEmpty = function() {
	    var horizontalEmpty = this.Adapter.isEmptyObject(this.waypoints.horizontal)
	    var verticalEmpty = this.Adapter.isEmptyObject(this.waypoints.vertical)
	    if (horizontalEmpty && verticalEmpty) {
	      this.adapter.off('.waypoints')
	      delete contexts[this.key]
	    }
	  }
	
	  /* Private */
	  Context.prototype.createThrottledResizeHandler = function() {
	    var self = this
	
	    function resizeHandler() {
	      self.handleResize()
	      self.didResize = false
	    }
	
	    this.adapter.on('resize.waypoints', function() {
	      if (!self.didResize) {
	        self.didResize = true
	        Waypoint.requestAnimationFrame(resizeHandler)
	      }
	    })
	  }
	
	  /* Private */
	  Context.prototype.createThrottledScrollHandler = function() {
	    var self = this
	    function scrollHandler() {
	      self.handleScroll()
	      self.didScroll = false
	    }
	
	    this.adapter.on('scroll.waypoints', function() {
	      if (!self.didScroll || Waypoint.isTouch) {
	        self.didScroll = true
	        Waypoint.requestAnimationFrame(scrollHandler)
	      }
	    })
	  }
	
	  /* Private */
	  Context.prototype.handleResize = function() {
	    Waypoint.Context.refreshAll()
	  }
	
	  /* Private */
	  Context.prototype.handleScroll = function() {
	    var triggeredGroups = {}
	    var axes = {
	      horizontal: {
	        newScroll: this.adapter.scrollLeft(),
	        oldScroll: this.oldScroll.x,
	        forward: 'right',
	        backward: 'left'
	      },
	      vertical: {
	        newScroll: this.adapter.scrollTop(),
	        oldScroll: this.oldScroll.y,
	        forward: 'down',
	        backward: 'up'
	      }
	    }
	
	    for (var axisKey in axes) {
	      var axis = axes[axisKey]
	      var isForward = axis.newScroll > axis.oldScroll
	      var direction = isForward ? axis.forward : axis.backward
	
	      for (var waypointKey in this.waypoints[axisKey]) {
	        var waypoint = this.waypoints[axisKey][waypointKey]
	        var wasBeforeTriggerPoint = axis.oldScroll < waypoint.triggerPoint
	        var nowAfterTriggerPoint = axis.newScroll >= waypoint.triggerPoint
	        var crossedForward = wasBeforeTriggerPoint && nowAfterTriggerPoint
	        var crossedBackward = !wasBeforeTriggerPoint && !nowAfterTriggerPoint
	        if (crossedForward || crossedBackward) {
	          waypoint.queueTrigger(direction)
	          triggeredGroups[waypoint.group.id] = waypoint.group
	        }
	      }
	    }
	
	    for (var groupKey in triggeredGroups) {
	      triggeredGroups[groupKey].flushTriggers()
	    }
	
	    this.oldScroll = {
	      x: axes.horizontal.newScroll,
	      y: axes.vertical.newScroll
	    }
	  }
	
	  /* Private */
	  Context.prototype.innerHeight = function() {
	    /*eslint-disable eqeqeq */
	    if (this.element == this.element.window) {
	      return Waypoint.viewportHeight()
	    }
	    /*eslint-enable eqeqeq */
	    return this.adapter.innerHeight()
	  }
	
	  /* Private */
	  Context.prototype.remove = function(waypoint) {
	    delete this.waypoints[waypoint.axis][waypoint.key]
	    this.checkEmpty()
	  }
	
	  /* Private */
	  Context.prototype.innerWidth = function() {
	    /*eslint-disable eqeqeq */
	    if (this.element == this.element.window) {
	      return Waypoint.viewportWidth()
	    }
	    /*eslint-enable eqeqeq */
	    return this.adapter.innerWidth()
	  }
	
	  /* Public */
	  /* http://imakewebthings.com/waypoints/api/context-destroy */
	  Context.prototype.destroy = function() {
	    var allWaypoints = []
	    for (var axis in this.waypoints) {
	      for (var waypointKey in this.waypoints[axis]) {
	        allWaypoints.push(this.waypoints[axis][waypointKey])
	      }
	    }
	    for (var i = 0, end = allWaypoints.length; i < end; i++) {
	      allWaypoints[i].destroy()
	    }
	  }
	
	  /* Public */
	  /* http://imakewebthings.com/waypoints/api/context-refresh */
	  Context.prototype.refresh = function() {
	    /*eslint-disable eqeqeq */
	    var isWindow = this.element == this.element.window
	    /*eslint-enable eqeqeq */
	    var contextOffset = this.adapter.offset()
	    var triggeredGroups = {}
	    var axes
	
	    this.handleScroll()
	    axes = {
	      horizontal: {
	        contextOffset: isWindow ? 0 : contextOffset.left,
	        contextScroll: isWindow ? 0 : this.oldScroll.x,
	        contextDimension: this.innerWidth(),
	        oldScroll: this.oldScroll.x,
	        forward: 'right',
	        backward: 'left',
	        offsetProp: 'left'
	      },
	      vertical: {
	        contextOffset: isWindow ? 0 : contextOffset.top,
	        contextScroll: isWindow ? 0 : this.oldScroll.y,
	        contextDimension: this.innerHeight(),
	        oldScroll: this.oldScroll.y,
	        forward: 'down',
	        backward: 'up',
	        offsetProp: 'top'
	      }
	    }
	
	    for (var axisKey in axes) {
	      var axis = axes[axisKey]
	      for (var waypointKey in this.waypoints[axisKey]) {
	        var waypoint = this.waypoints[axisKey][waypointKey]
	        var adjustment = waypoint.options.offset
	        var oldTriggerPoint = waypoint.triggerPoint
	        var elementOffset = 0
	        var freshWaypoint = oldTriggerPoint == null
	        var contextModifier, wasBeforeScroll, nowAfterScroll
	        var triggeredBackward, triggeredForward
	
	        if (waypoint.element !== waypoint.element.window) {
	          elementOffset = waypoint.adapter.offset()[axis.offsetProp]
	        }
	
	        if (typeof adjustment === 'function') {
	          adjustment = adjustment.apply(waypoint)
	        }
	        else if (typeof adjustment === 'string') {
	          adjustment = parseFloat(adjustment)
	          if (waypoint.options.offset.indexOf('%') > - 1) {
	            adjustment = Math.ceil(axis.contextDimension * adjustment / 100)
	          }
	        }
	
	        contextModifier = axis.contextScroll - axis.contextOffset
	        waypoint.triggerPoint = elementOffset + contextModifier - adjustment
	        wasBeforeScroll = oldTriggerPoint < axis.oldScroll
	        nowAfterScroll = waypoint.triggerPoint >= axis.oldScroll
	        triggeredBackward = wasBeforeScroll && nowAfterScroll
	        triggeredForward = !wasBeforeScroll && !nowAfterScroll
	
	        if (!freshWaypoint && triggeredBackward) {
	          waypoint.queueTrigger(axis.backward)
	          triggeredGroups[waypoint.group.id] = waypoint.group
	        }
	        else if (!freshWaypoint && triggeredForward) {
	          waypoint.queueTrigger(axis.forward)
	          triggeredGroups[waypoint.group.id] = waypoint.group
	        }
	        else if (freshWaypoint && axis.oldScroll >= waypoint.triggerPoint) {
	          waypoint.queueTrigger(axis.forward)
	          triggeredGroups[waypoint.group.id] = waypoint.group
	        }
	      }
	    }
	
	    for (var groupKey in triggeredGroups) {
	      triggeredGroups[groupKey].flushTriggers()
	    }
	
	    return this
	  }
	
	  /* Private */
	  Context.findOrCreateByElement = function(element) {
	    return Context.findByElement(element) || new Context(element)
	  }
	
	  /* Private */
	  Context.refreshAll = function() {
	    for (var contextId in contexts) {
	      contexts[contextId].refresh()
	    }
	  }
	
	  /* Public */
	  /* http://imakewebthings.com/waypoints/api/context-find-by-element */
	  Context.findByElement = function(element) {
	    return contexts[element.waypointContextKey]
	  }
	
	  window.onload = function() {
	    if (oldWindowLoad) {
	      oldWindowLoad()
	    }
	    Context.refreshAll()
	  }
	
	  Waypoint.requestAnimationFrame = function(callback) {
	    var requestFn = window.requestAnimationFrame ||
	      window.mozRequestAnimationFrame ||
	      window.webkitRequestAnimationFrame ||
	      requestAnimationFrameShim
	    requestFn.call(window, callback)
	  }
	  Waypoint.Context = Context
	}())
	;(function() {
	  'use strict'
	
	  function byTriggerPoint(a, b) {
	    return a.triggerPoint - b.triggerPoint
	  }
	
	  function byReverseTriggerPoint(a, b) {
	    return b.triggerPoint - a.triggerPoint
	  }
	
	  var groups = {
	    vertical: {},
	    horizontal: {}
	  }
	  var Waypoint = window.Waypoint
	
	  /* http://imakewebthings.com/waypoints/api/group */
	  function Group(options) {
	    this.name = options.name
	    this.axis = options.axis
	    this.id = this.name + '-' + this.axis
	    this.waypoints = []
	    this.clearTriggerQueues()
	    groups[this.axis][this.name] = this
	  }
	
	  /* Private */
	  Group.prototype.add = function(waypoint) {
	    this.waypoints.push(waypoint)
	  }
	
	  /* Private */
	  Group.prototype.clearTriggerQueues = function() {
	    this.triggerQueues = {
	      up: [],
	      down: [],
	      left: [],
	      right: []
	    }
	  }
	
	  /* Private */
	  Group.prototype.flushTriggers = function() {
	    for (var direction in this.triggerQueues) {
	      var waypoints = this.triggerQueues[direction]
	      var reverse = direction === 'up' || direction === 'left'
	      waypoints.sort(reverse ? byReverseTriggerPoint : byTriggerPoint)
	      for (var i = 0, end = waypoints.length; i < end; i += 1) {
	        var waypoint = waypoints[i]
	        if (waypoint.options.continuous || i === waypoints.length - 1) {
	          waypoint.trigger([direction])
	        }
	      }
	    }
	    this.clearTriggerQueues()
	  }
	
	  /* Private */
	  Group.prototype.next = function(waypoint) {
	    this.waypoints.sort(byTriggerPoint)
	    var index = Waypoint.Adapter.inArray(waypoint, this.waypoints)
	    var isLast = index === this.waypoints.length - 1
	    return isLast ? null : this.waypoints[index + 1]
	  }
	
	  /* Private */
	  Group.prototype.previous = function(waypoint) {
	    this.waypoints.sort(byTriggerPoint)
	    var index = Waypoint.Adapter.inArray(waypoint, this.waypoints)
	    return index ? this.waypoints[index - 1] : null
	  }
	
	  /* Private */
	  Group.prototype.queueTrigger = function(waypoint, direction) {
	    this.triggerQueues[direction].push(waypoint)
	  }
	
	  /* Private */
	  Group.prototype.remove = function(waypoint) {
	    var index = Waypoint.Adapter.inArray(waypoint, this.waypoints)
	    if (index > -1) {
	      this.waypoints.splice(index, 1)
	    }
	  }
	
	  /* Public */
	  /* http://imakewebthings.com/waypoints/api/first */
	  Group.prototype.first = function() {
	    return this.waypoints[0]
	  }
	
	  /* Public */
	  /* http://imakewebthings.com/waypoints/api/last */
	  Group.prototype.last = function() {
	    return this.waypoints[this.waypoints.length - 1]
	  }
	
	  /* Private */
	  Group.findOrCreate = function(options) {
	    return groups[options.axis][options.name] || new Group(options)
	  }
	
	  Waypoint.Group = Group
	}())
	;(function() {
	  'use strict'
	
	  var $ = window.jQuery
	  var Waypoint = window.Waypoint
	
	  function JQueryAdapter(element) {
	    this.$element = $(element)
	  }
	
	  $.each([
	    'innerHeight',
	    'innerWidth',
	    'off',
	    'offset',
	    'on',
	    'outerHeight',
	    'outerWidth',
	    'scrollLeft',
	    'scrollTop'
	  ], function(i, method) {
	    JQueryAdapter.prototype[method] = function() {
	      var args = Array.prototype.slice.call(arguments)
	      return this.$element[method].apply(this.$element, args)
	    }
	  })
	
	  $.each([
	    'extend',
	    'inArray',
	    'isEmptyObject'
	  ], function(i, method) {
	    JQueryAdapter[method] = $[method]
	  })
	
	  Waypoint.adapters.push({
	    name: 'jquery',
	    Adapter: JQueryAdapter
	  })
	  Waypoint.Adapter = JQueryAdapter
	}())
	;(function() {
	  'use strict'
	
	  var Waypoint = window.Waypoint
	
	  function createExtension(framework) {
	    return function() {
	      var waypoints = []
	      var overrides = arguments[0]
	
	      if (framework.isFunction(arguments[0])) {
	        overrides = framework.extend({}, arguments[1])
	        overrides.handler = arguments[0]
	      }
	
	      this.each(function() {
	        var options = framework.extend({}, overrides, {
	          element: this
	        })
	        if (typeof options.context === 'string') {
	          options.context = framework(this).closest(options.context)[0]
	        }
	        waypoints.push(new Waypoint(options))
	      })
	
	      return waypoints
	    }
	  }
	
	  if (window.jQuery) {
	    window.jQuery.fn.waypoint = createExtension(window.jQuery)
	  }
	  if (window.Zepto) {
	    window.Zepto.fn.waypoint = createExtension(window.Zepto)
	  }
	}())
	;

/***/ }

});
//# sourceMappingURL=campaign-page-next.js.map
