<commit_before>$(function () {


  /////////////////
  // Initial setup.
  /////////////////

  //======================
  // Create app namespace:
  //======================
  var app = {};

  // Default objects:
  app.purchases = [];
  app.perfumesCollection;


  //==============================
  // Get the data to be displayed:
  //==============================

  $.getJSON('data/perfumes.json', function(data) {
    // Make acquired data available to templates:
    app.perfumesCollection = app.perfumeGenres.scope.perfumesCollection = data;
    // Render first template:
    app.perfumeGenres.render();
  });



  /////////////////////////////////
  // Initalize the app's templates:
  /////////////////////////////////


  //==============================================
  // Define the templates.
  // This creates templates from all DOM ids which 
  // correspond to Somajs Templates in the DOM,
  // thus enabling calling them later by name
  // without having to define them individually.
  //============================================== 
  app.perfumeGenres = soma.template.create(document.getElementById('perfumeGenres'));
  app.perfumesGenreTitle = soma.template.create(document.getElementById('perfumesGenreTitle'));
  app.available_perfumes = soma.template.create(document.getElementById('available_perfumes'));
  app.detailNavbar = soma.template.create(document.getElementById('detailNavbar'));
  app.perfumeDetail = soma.template.create(document.getElementById('perfumeDetail'));
  app.backToPerfume = soma.template.create(document.getElementById('backToPerfume'));
  app.cart = soma.template.create(document.getElementById('cart'));
  app.confirmation = soma.template.create(document.getElementById('confirmation'));

  //=================================
  // Define a template helper.
  // Capitalize first letter of word:
  //=================================
  soma.template.helpers({
    capitalize : function ( str ) {
      if (!str) return;
      return str.charAt(0).toUpperCase() + str.slice(1);
    }
  });


  //================================================================
  // Set up genres for inital page load. This will be used to
  // filter perfumes based on which genre the user selects.
  // Define a method to get the genre of perfume (ladies, men, kids).
  // This filters the genre from the total perfumes object.
  // Then renders the template on the next screen with that genre.
  //================================================================
  app.perfumeGenres.scope.genres = ['ladies', 'men', 'kids'];
  
  app.perfumeGenres.scope.getGenre = function(item) {
    var title = app.perfumesGenreTitle.scope.title = item.target.getAttribute('data-title');
    var perfumeGenre = item.target.getAttribute('data-genre');
    //===================================
    // Update the title of the next view:
    //===================================
    app.perfumesGenreTitle.render();
    //=============================================
    // Filter the data based on the user selection:
    //=============================================
    var whichPerfumes = app.perfumesCollection.filter(function(item) {
      return item.genre === perfumeGenre;
    })
    app.available_perfumes.scope.selectedGenre = whichPerfumes;
    //===============================================
    // Update the next template for the chosen genre:
    //===============================================
    app.available_perfumes.render();
    app.available_perfumes.scope.children = $('#available_perfumes').children();
  };


  //================================================
  // Get the chosen perfume and render its template:
  //================================================
  app.available_perfumes.scope.getChosenPerfume = function(e) {
    var item = e.target.nodeName === 'LI' ? e.target : $(e.target).closest('li')[0];
    var sku = item.getAttribute('data-sku');
    var chosenPerfume = app.available_perfumes.scope.selectedGenre.filter(function(perfume) {
       return perfume.sku === sku;
    });

    //=========================
    // Update the navbar title:
    //=========================
    app.detailNavbar.scope.chosenPerfume = chosenPerfume[0];
    app.detailNavbar.scope.chosenPerfume.genreTitle = app.perfumesGenreTitle.scope.title;
    app.detailNavbar.render();

    //========================
    // Update the detail view:
    //========================
    app.perfumeDetail.scope.chosenPerfume = chosenPerfume[0];
    app.perfumeDetail.render();
  };


  //===========================================
  // Calculate how many items have been chosen.
  // This is used in the shopping cart:
  //===========================================
  app.cart.scope.purchases = app.purchases;
  app.cart.scope.disabled = true;
  app.cart.scope.getTotalItems = function() {
    if (!app.cart.scope.purchases.length) return 0;
    else return app.cart.scope.purchases.length;
  };


  //==========================
  // Render Confirmation view:
  //==========================
  app.confirmation.scope.getTotalCost = app.cart.scope.getTotalCost = function() {
    var total = 0;
    app.cart.scope.purchases.forEach(function(item) {
      total += Number(item.wholesale_price);
    });
    return total.toFixed(2);
  };    




  ///////////////////////////
  // Setup User Interactions:
  ///////////////////////////

  //======================
  // Add to Shopping Cart:
  //======================
  $('#addToCart').on('singletap', function() {
    $.UIGoToArticle('#cart');
    // Update cart with added perfume data:
    app.perfumeDetail.scope.chosenPerfume.genreTitle = app.perfumesGenreTitle.scope.title;
    // Render cart template:
    app.cart.scope.purchases.push(app.perfumeDetail.scope.chosenPerfume);
    app.cart.scope.disabled = false;
    app.cart.render();
    // Update 'Back Button' text template:
    app.backToPerfume.scope.perfumeName = app.perfumeDetail.scope.chosenPerfume.product_title;
    app.backToPerfume.render();
  });

  //====================
  // View Shopping Cart:
  //====================
  $('#shoppingCart').on('singletap', function() {
    // If shopping cart is empty, do nothing:
    if (!app.cart.scope.purchases.length) return;
    // Otherwise, go to cart view:
    $.UIGoToArticle('#cart');
  });

  //=============
  // Place Order:
  //=============
  $('#placeOrder').on('singletap', function() {
    // Go to order confirmation view:
    $.UIGoToArticle('#confirmation');
    // Create a uuid for the order:
    $('#confirmationNum').text($.Uuid());
    // Update the confirmation view template:
    app.confirmation.scope.purchases = app.cart.scope.purchases;
    app.confirmation.render();
  });

  //==============
  // Cancel Order:
  //==============
  $('#cancelOrder').on('singletap', function() {
    // Return to the main view:
    $.UIGoBackToArticle('#main');
    // Reset the shopping cart:
    app.cart.scope.purchases = [];
    app.cart.render();
  });  
});<commit_msg>Added popup for empty shopping cart.<commit_after>$(function () {


  /////////////////
  // Initial setup.
  /////////////////

  //======================
  // Create app namespace:
  //======================
  var app = {};

  // Default objects:
  app.purchases = [];
  app.perfumesCollection;


  //=================================
  // Define a template helper.
  // Capitalize first letter of word:
  //=================================
  soma.template.helpers({
    capitalize : function ( str ) {
      if (!str) return;
      return str.charAt(0).toUpperCase() + str.slice(1);
    }
  });



  /////////////////////////////////
  // Initalize the app's templates:
  /////////////////////////////////


  //==============================================
  // Define the templates.
  // This creates templates from all DOM ids which 
  // correspond to Somajs Templates in the DOM,
  // thus enabling calling them later by name
  // without having to define them individually.
  //============================================== 
  app.perfumeGenres = soma.template.create($('#perfumeGenres')[0]);
  app.perfumesGenreTitle = soma.template.create($('#perfumesGenreTitle')[0]);
  app.available_perfumes = soma.template.create($('#available_perfumes')[0]);
  app.detailNavbar = soma.template.create($('#detailNavbar')[0]);
  app.perfumeDetail = soma.template.create($('#perfumeDetail')[0]);
  app.backToPerfume = soma.template.create($('#backToPerfume')[0]);
  app.cart = soma.template.create($('#cart')[0]);
  app.confirmation = soma.template.create($('#confirmation')[0]);



  //==============================
  // Get the data to be displayed:
  //==============================

  $.getJSON('data/perfumes.json', function(data) {
    // Make acquired data available to templates:
    app.perfumesCollection = app.perfumeGenres.scope.perfumesCollection = data;
    // Render first template:
    app.perfumeGenres.render();
  });


  //================================================================
  // Set up genres for inital page load. This will be used to
  // filter perfumes based on which genre the user selects.
  // Define a method to get the genre of perfume (ladies, men, kids).
  // This filters the genre from the total perfumes object.
  // Then renders the template on the next screen with that genre.
  //================================================================
  app.perfumeGenres.scope.genres = ['ladies', 'men', 'kids'];
  
  app.perfumeGenres.scope.getGenre = function(item) {
    var title = app.perfumesGenreTitle.scope.title = item.target.getAttribute('data-title');
    var perfumeGenre = item.target.getAttribute('data-genre');
    //===================================
    // Update the title of the next view:
    //===================================
    app.perfumesGenreTitle.render();
    //=============================================
    // Filter the data based on the user selection:
    //=============================================
    var whichPerfumes = app.perfumesCollection.filter(function(item) {
      return item.genre === perfumeGenre;
    })
    app.available_perfumes.scope.selectedGenre = whichPerfumes;
    //===============================================
    // Update the next template for the chosen genre:
    //===============================================
    app.available_perfumes.render();
    app.available_perfumes.scope.children = $('#available_perfumes').children();
  };


  //================================================
  // Get the chosen perfume and render its template:
  //================================================
  app.available_perfumes.scope.getChosenPerfume = function(e) {
    var item = e.target.nodeName === 'LI' ? e.target : $(e.target).closest('li')[0];
    var sku = item.getAttribute('data-sku');
    var chosenPerfume = app.available_perfumes.scope.selectedGenre.filter(function(perfume) {
       return perfume.sku === sku;
    });

    //=========================
    // Update the navbar title:
    //=========================
    app.detailNavbar.scope.chosenPerfume = chosenPerfume[0];
    app.detailNavbar.scope.chosenPerfume.genreTitle = app.perfumesGenreTitle.scope.title;
    app.detailNavbar.render();

    //========================
    // Update the detail view:
    //========================
    app.perfumeDetail.scope.chosenPerfume = chosenPerfume[0];
    app.perfumeDetail.render();
  };


  //===========================================
  // Calculate how many items have been chosen.
  // This is used in the shopping cart:
  //===========================================
  app.cart.scope.purchases = app.purchases;
  app.cart.scope.disabled = true;
  app.cart.scope.getTotalItems = function() {
    if (!app.cart.scope.purchases.length) return 0;
    else return app.cart.scope.purchases.length;
  };


  //==========================
  // Render Confirmation view:
  //==========================
  app.confirmation.scope.getTotalCost = app.cart.scope.getTotalCost = function() {
    var total = 0;
    app.cart.scope.purchases.forEach(function(item) {
      total += Number(item.wholesale_price);
    });
    return total.toFixed(2);
  };    




  ///////////////////////////
  // Setup User Interactions:
  ///////////////////////////

  //======================
  // Add to Shopping Cart:
  //======================
  $('#addToCart').on('singletap', function() {
    $.UIGoToArticle('#cart');
    // Update cart with added perfume data:
    app.perfumeDetail.scope.chosenPerfume.genreTitle = app.perfumesGenreTitle.scope.title;
    // Render cart template:
    app.cart.scope.purchases.push(app.perfumeDetail.scope.chosenPerfume);
    app.cart.scope.disabled = false;
    app.cart.render();
    // Update 'Back Button' text template:
    app.backToPerfume.scope.perfumeName = app.perfumeDetail.scope.chosenPerfume.product_title;
    app.backToPerfume.render();
  });


  //====================
  // View Shopping Cart:
  //====================

  // Popup for when cart is empty:
  app.cartIsEmpty = function() {
    $.UIPopup({
      id: "warning",
      title: 'Empty Cart!', 
      cancelButton: 'Close', 
      message: 'The shopping cart is empty. Add some items using the "+" button on the lower left.'
    });
  };

  $('#shoppingCart').on('singletap', function() {
    // If shopping cart is empty, show popup message:
    if (!app.cart.scope.purchases.length) {
      app.cartIsEmpty();
      return;
    }
    // Otherwise, go to cart view:
    $.UIGoToArticle('#cart');
  });

  //=============
  // Place Order:
  //=============
  $('#placeOrder').on('singletap', function() {
    // Go to order confirmation view:
    $.UIGoToArticle('#confirmation');
    // Create a uuid for the order:
    $('#confirmationNum').text($.Uuid());
    // Update the confirmation view template:
    app.confirmation.scope.purchases = app.cart.scope.purchases;
    app.confirmation.render();
  });

  //==============
  // Cancel Order:
  //==============
  $('#cancelOrder').on('singletap', function() {
    // Return to the main view:
    $.UIGoBackToArticle('#main');
    // Reset the shopping cart:
    app.cart.scope.purchases = [];
    app.cart.render();
  });  
});
{'fraction_non_alphanumeric': 0.29783190201323384, 'fraction_numerical': 0.0016894270026749261, 'mean_word_length': 3.322178278065105, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7261980', 'n_tokens_mistral': 4018, 'n_tokens_neox': 3814, 'n_words': 801}