<commit_before>/**
 * @overview ccm component for router
 * @author Manfred Kaul <manfred.kaul@h-brs.de> 2017
 * @license The MIT License (MIT)
 * @version latest (1.0.0)
 * TODO: docu comments -> API
 * TODO: unit tests
 * TODO: builder component
 * TODO: multilingualism
 */

{

  const component  = {

    /**
     * unique component name
     * @type {string}
     */
    name: 'router',

    /**
     * recommended used framework version
     * @type {string}
     */
    ccm: 'https://akless.github.io/ccm/version/ccm-11.5.0.min.js',
    // ccm: '//akless.github.io/ccm/ccm.js',

    /**
     * default instance configuration
     * @type {object}
     */
    config: {
      // menu item format = [ button label, title label, filename ]
      // is also the location hash format (anchor)
      menu: [ [ 'Orga', 'OG', 'orga' ], [ 'LE01', '01', 'le01' ] ],

      separation_char: ',', // default is comma separated format

      content: [ 'ccm.instance', 'https://akless.github.io/ccm-components/content/versions/ccm.content-2.0.0.min.js' ],

      feedback: [ 'ccm.instance', '//kaul.inf.h-brs.de/data/ccm/feedback/versions/ccm.feedback-1.0.0.js', { position: 'right', from_above: '50%', data: { key: 'se1_ws17', store: [ 'ccm.store', { store: 'feedback', url: 'https://ccm.inf.h-brs.de' } ] } } ],

      server: 'https://kaul.inf.h-brs.de/data/2017/se1/',

      html: {
        main: {
          inner: [
            { tag: 'h1', class: 'center', inner: 'Einführung in Software Engineering' },
            { id: 'menu' },
            { id: 'content' },
            { id: 'feedback' }
          ]
        }
      },
      css: [ 'ccm.load',  '//kaul.inf.h-brs.de/data/ccm/router/resources/default.css' ],
      // css: [ 'ccm.load',  'https://mkaul.github.io/ccm-components/router/resources/default.css' ],
      // user:   [ 'ccm.instance', 'https://akless.github.io/ccm-components/user/versions/ccm.user-2.0.0.min.js' ],
      // logger: [ 'ccm.instance', 'https://akless.github.io/ccm-components/log/versions/ccm.log-1.0.0.min.js', [ 'ccm.get', 'https://akless.github.io/ccm-components/log/resources/log_configs.min.js', 'greedy' ] ],
      // onfinish: function( instance, results ){ console.log( results ); }
    },

    /**
     * for creating instances of this component
     * @constructor
     */
    Instance: function () {

      /**
       * own reference for inner functions
       * @type {Instance}
       */
      const self = this;

      /**
       * shortcut to help functions
       * @type {Object}
       */
      let $;

      /**
       * init is called once after all dependencies are solved and is then deleted
       * @param {function} callback - called after all synchronous and asynchronous operations are complete
       */
      this.init = callback => {

        //  Is content given via LightDOM (inner HTML of Custom Element)?
        //  Then use it with higher priority
        if ( self.inner && self.inner.innerHTML.trim() ){
          // interpreter for LightDOM
          self.text = self.inner.innerHTML;
          self.menu = JSON.parse( self.text );
        }
        callback();
      };

      /**
       * is called once after the initialization and is then deleted
       * @param {function} callback - called after all synchronous and asynchronous operations are complete
       */
      this.ready = callback => {

        // set shortcut to help functions
        $ = self.ccm.helper;

        callback();
      };

      /**
       * starts the instance
       * @param {function} [callback] - called after all synchronous and asynchronous operations are complete
       */
      this.start = callback => {

        // has logger instance? => log 'render' event
        if ( self.logger ) self.logger.log( 'render' );

        // prepare main HTML structure
        const main_elem = $.html( self.html.main );

        // select inner containers
        const menu = main_elem.querySelector('#menu');
        const content = main_elem.querySelector('#content');
        const feedback = main_elem.querySelector('#feedback');

        // set content of own website area
        $.setContent( self.element, main_elem );

        self.menu.map( menu_item => {
          const label = menu_item[ 0 ];
          const title = menu_item[ 1 ];
          const btn = $.html({tag:'button', inner: label, class: 'btn btn-primary'});
          menu.appendChild(btn);
          btn.addEventListener('click', function () {
            document.title = title;
            location.hash = menu_item.join(self.separation_char);
          })
        });

        // backup old event handler
        const old_window_onhashchange = window.onhashchange;

        // assign new event handler
        window.onhashchange = (e) => {
          let address_vector;
          // anchors without comma are local only (inner page)
          if (location.hash.length > 0 && location.hash.indexOf(self.separation_char) >= 0) {
            // parse address_vector from comma separated format of anchor
            address_vector = location.hash.replace('#','').split(self.separation_char);
            start( address_vector );
          } else {
            old_window_onhashchange(e);
          }
        };

        // when initially opening this web page, is there a location.hash (anchor)?
        if (location.hash.length > 0 && location.hash.indexOf(self.separation_char) >= 0) {
          // already selected by location.hash
          window.onhashchange();
        }

        function start( address_vector ) {
          const filename = address_vector[2];
          const oldChild = content.firstChild;
          const newChild = document.createElement('div');
          if (oldChild) content.replaceChild(newChild,oldChild); else content.appendChild(newChild);
          self.ccm.start( 'content-2-0-0', { semester: "172", fach: "se", root: newChild, inner: [ 'ccm.load', self.server + filename + '.html' ] });
        }

        self.feedback.start( ( instance ) => {
          feedback.appendChild( instance.root );
          if ( callback ) callback();
        });

      };

    }

  };

  function p(){window.ccm[v].component(component)}const f="ccm."+component.name+(component.version?"-"+component.version.join("."):"")+".js";if(window.ccm&&null===window.ccm.files[f])window.ccm.files[f]=component;else{const n=window.ccm&&window.ccm.components[component.name];n&&n.ccm&&(component.ccm=n.ccm),"string"===typeof component.ccm&&(component.ccm={url:component.ccm});var v=component.ccm.url.split("/").pop().split("-");if(v.length>1?(v=v[1].split("."),v.pop(),"min"===v[v.length-1]&&v.pop(),v=v.join(".")):v="latest",window.ccm&&window.ccm[v])p();else{const e=document.createElement("script");document.head.appendChild(e),component.ccm.integrity&&e.setAttribute("integrity",component.ccm.integrity),component.ccm.crossorigin&&e.setAttribute("crossorigin",component.ccm.crossorigin),e.onload=function(){p(),document.head.removeChild(e)},e.src=component.ccm.url}}
}<commit_msg>move magic numbers into config<commit_after>/**
 * @overview ccm component for router
 * @author Manfred Kaul <manfred.kaul@h-brs.de> 2017
 * @license The MIT License (MIT)
 * @version latest (1.0.0)
 * TODO: docu comments -> API
 * TODO: unit tests
 * TODO: builder component
 * TODO: multilingualism
 */

{

  const component  = {

    /**
     * unique component name
     * @type {string}
     */
    name: 'router',

    /**
     * recommended used framework version
     * @type {string}
     */
    ccm: 'https://akless.github.io/ccm/version/ccm-11.5.0.min.js',
    // ccm: '//akless.github.io/ccm/ccm.js',

    /**
     * default instance configuration
     * @type {object}
     */
    config: {
      server: 'https://kaul.inf.h-brs.de/data/2017/se1/',

      // additional config parameters tobe merged into loader config
      keys: { semester: "172", fach: "se" },

      // menu item format = [ button label, title label, filename ]
      // is also the location hash format (anchor)
      menu: [ [ 'Orga', 'OG', 'orga' ], [ 'LE01', '01', 'le01' ] ],

      // default is comma separated format for location.hash (anchor)
      separation_char: ',',

      // dependencies
      content: [ 'ccm.instance', 'https://akless.github.io/ccm-components/content/versions/ccm.content-2.0.0.min.js' ],

      feedback: [ 'ccm.instance', '//kaul.inf.h-brs.de/data/ccm/feedback/versions/ccm.feedback-1.0.0.js', { position: 'right', from_above: '50%', data: { key: 'se1_ws17', store: [ 'ccm.store', { store: 'feedback', url: 'https://ccm.inf.h-brs.de' } ] } } ],

      html: {
        main: {
          inner: [
            { tag: 'h1', class: 'center', inner: 'Einführung in Software Engineering' },
            { id: 'menu' },
            { id: 'content' },
            { id: 'feedback' }
          ]
        }
      },
      css: [ 'ccm.load',  '//kaul.inf.h-brs.de/data/ccm/router/resources/default.css' ],
      // css: [ 'ccm.load',  'https://mkaul.github.io/ccm-components/router/resources/default.css' ],
      // user:   [ 'ccm.instance', 'https://akless.github.io/ccm-components/user/versions/ccm.user-2.0.0.min.js' ],
      // logger: [ 'ccm.instance', 'https://akless.github.io/ccm-components/log/versions/ccm.log-1.0.0.min.js', [ 'ccm.get', 'https://akless.github.io/ccm-components/log/resources/log_configs.min.js', 'greedy' ] ],
      // onfinish: function( instance, results ){ console.log( results ); }
    },

    /**
     * for creating instances of this component
     * @constructor
     */
    Instance: function () {

      /**
       * own reference for inner functions
       * @type {Instance}
       */
      const self = this;

      /**
       * shortcut to help functions
       * @type {Object}
       */
      let $;

      /**
       * init is called once after all dependencies are solved and is then deleted
       * @param {function} callback - called after all synchronous and asynchronous operations are complete
       */
      this.init = callback => {

        //  Is content given via LightDOM (inner HTML of Custom Element)?
        //  Then use it with higher priority
        if ( self.inner && self.inner.innerHTML.trim() ){
          // interpreter for LightDOM
          self.text = self.inner.innerHTML;
          self.menu = JSON.parse( '[' + self.text + ']' );
        }
        callback();
      };

      /**
       * is called once after the initialization and is then deleted
       * @param {function} callback - called after all synchronous and asynchronous operations are complete
       */
      this.ready = callback => {

        // set shortcut to help functions
        $ = self.ccm.helper;

        callback();
      };

      /**
       * starts the instance
       * @param {function} [callback] - called after all synchronous and asynchronous operations are complete
       */
      this.start = callback => {

        // has logger instance? => log 'render' event
        if ( self.logger ) self.logger.log( 'render' );

        // prepare main HTML structure
        const main_elem = $.html( self.html.main );

        // select inner containers
        const menu = main_elem.querySelector('#menu');
        const content = main_elem.querySelector('#content');
        const feedback = main_elem.querySelector('#feedback');

        // set content of own website area
        $.setContent( self.element, main_elem );

        self.menu.map( menu_item => {
          const label = menu_item[ 0 ];
          const title = menu_item[ 1 ];
          const btn = $.html({tag:'button', inner: label, class: 'btn btn-primary'});
          menu.appendChild(btn);
          btn.addEventListener('click', function () {
            document.title = title;
            location.hash = menu_item.join(self.separation_char);
          })
        });

        // backup old event handler
        const old_window_onhashchange = window.onhashchange;

        // assign new event handler
        window.onhashchange = (e) => {
          let address_vector;
          // anchors without comma are local only (inner page)
          if ( location.hash.length > 0 && location.hash.indexOf( self.separation_char ) >= 0 ) {
            // parse address_vector from comma separated format of anchor
            address_vector = location.hash.slice(1).split( self.separation_char );
            start( address_vector );
          } else {
            if ( old_window_onhashchange ) old_window_onhashchange(e);
          }
        };

        // when initially opening this web page, is there a location.hash (anchor)?
        if ( location.hash.length > 0 && location.hash.indexOf( self.separation_char ) >= 0 ) {
          // already selected by location.hash
          window.onhashchange();
        }

        function start( address_vector ) {
          const filename = address_vector[2];
          const oldChild = content.firstChild;
          const newChild = document.createElement('div');
          if (oldChild) content.replaceChild(newChild,oldChild); else content.appendChild(newChild);
          const config =  $.integrate({ root: newChild, inner: [ 'ccm.load', self.server + filename + '.html' ] } , self.keys );
          self.ccm.start( 'content-2-0-0', config );
        }

        self.feedback.start( ( instance ) => {
          feedback.appendChild( instance.root );
          if ( callback ) callback();
        });

      };

    }

  };

  function p(){window.ccm[v].component(component)}const f="ccm."+component.name+(component.version?"-"+component.version.join("."):"")+".js";if(window.ccm&&null===window.ccm.files[f])window.ccm.files[f]=component;else{const n=window.ccm&&window.ccm.components[component.name];n&&n.ccm&&(component.ccm=n.ccm),"string"===typeof component.ccm&&(component.ccm={url:component.ccm});var v=component.ccm.url.split("/").pop().split("-");if(v.length>1?(v=v[1].split("."),v.pop(),"min"===v[v.length-1]&&v.pop(),v=v.join(".")):v="latest",window.ccm&&window.ccm[v])p();else{const e=document.createElement("script");document.head.appendChild(e),component.ccm.integrity&&e.setAttribute("integrity",component.ccm.integrity),component.ccm.crossorigin&&e.setAttribute("crossorigin",component.ccm.crossorigin),e.onload=function(){p(),document.head.removeChild(e)},e.src=component.ccm.url}}
}<|endoftext|>


<commit_before>
/* TODO: This is only part of the original template JS */

/* -------------------- Check Browser --------------------- */

function browser() {

  //var isOpera = !!(window.opera && window.opera.version);  // Opera 8.0+
  //var isFirefox = testCSS('MozBoxSizing');                 // FF 0.8+
  var isSafari = Object.prototype.toString.call(window.HTMLElement).indexOf('Constructor') > 0;
      // At least Safari 3+: "[object HTMLElementConstructor]"
  var isChrome = !isSafari && testCSS('WebkitTransform');  // Chrome 1+
  //var isIE = /*@cc_on!@*/false || testCSS('msTransform');  // At least IE6

  function testCSS(prop) {
      return prop in document.documentElement.style;
  }

  if (isSafari || isChrome) {

    return true;

  } else {

    return false;

  }

}

/* -------------------- Search --------------------- */

jQuery(document).ready(function($){

  $('.search > :input').on('keyup',function(){

    $(this).attr('class', 'activeSearch');

    var count;
    var timeToEnd = 1000;

    $(':input').keydown(function(){

      clearTimeout(count);

      count = setTimeout(endCount, timeToEnd);

    });

  });

  function endCount(){

    $('.search > :input').attr('class','search-form');

  }

});

/* -------------------- Buttons 3D Style --------------------- */

jQuery(document).ready(function($){

  $(':button').each(function(){

    if($(this).hasClass('btn-tabula')) {

      $(this).wrap('
');

      var inner = $(this).html();

      if(browser()) {

        $(this).html('' + inner + '');

      }

    }

  });

  $('a').each(function(){

    if($(this).hasClass('btnOverlay')) {

      $(this).wrap('
');

      var inner = $(this).html();

      if(browser()) {

        $(this).html('' + inner + '');

      }

    }

  });

});

/* ------------------ Back To Top ------------------- */
jQuery(document).ready(function($){

  jQuery('#under-footer-back-to-top a').click(function(){
    jQuery('html, body').animate({scrollTop:0}, 300);
    return false;
  });

});

/* ------------------ Tooltips ----------------- */

jQuery(document).ready(function($) {

    $('.tooltips').tooltip({
      selector: "a[rel=tooltip]"
    })

});

/* -------------------- Isotope --------------------- */
/* dcabo: This was called on ready() in the original template, but images overlapped
          when using Turbolinks (only in Firefox, maybe). See discussion at
          https://github.com/rails/turbolinks/issues/159
/* dcabo: Nah, undo, didn't fix it but broke the search page for some reason. Will
          try something else. */

jQuery(document).ready(function () {

  $('#wall').imagesLoaded(function() {

    var $container = $('#wall');
      $select = $('#filters select');

    // initialize Isotope
    $container.isotope({
    // options...
    resizable: false, // disable normal resizing
    // set columnWidth to a percentage of container width
      masonry: { columnWidth: $container.width() / 12 }
    });

    // update columnWidth on window resize
    $(window).smartresize(function(){

      $container.isotope({
      // update columnWidth to a percentage of container width
        masonry: { columnWidth: $container.width() / 12 }
      });
    });

    $container.isotope({
      itemSelector : '.item'
    });

    $select.change(function() {

      var filters = $(this).val();

        $container.isotope({
          filter: filters
        });

      });

      var $optionSets = $('#filters .option-set'),
        $optionLinks = $optionSets.find('a');

        $optionLinks.click(function(){

        var $this = $(this);
        // don't proceed if already selected
        if ( $this.hasClass('selected') ) {
            return false;
        }
      var $optionSet = $this.parents('.option-set');
      $optionSet.find('.selected').removeClass('selected');
      $this.addClass('selected');

      // make option object dynamically, i.e. { filter: '.my-filter-class' }
      var options = {},
        key = $optionSet.attr('data-option-key'),
        value = $this.attr('data-option-value');
      // parse 'false' as false boolean
      value = value === 'false' ? false : value;
      options[ key ] = value;
      if ( key === 'layoutMode' && typeof changeLayoutMode === 'function' ) {
        // changes in layout modes need extra logic
        changeLayoutMode( $this, options )
      } else {
        // otherwise, apply new options
        $container.isotope( options );
      }

      return false;

      });

  });

});

/* -------------------- Width Functions --------------------- */

jQuery(document).ready(function($){

  widthFunctions();

});

$(window).bind("resize", widthFunctions);

function widthFunctions(e) {

  var winHeight = $(window).height();
  var winWidth = $(window).width();

  if (winWidth < 980 && winWidth > 767) {

    if($("#wall").width()) {

      if($(".item").hasClass("span3")) {

        $(".item").removeClass("span3");
        $(".item").addClass("span4");

      }

    }

    if($(".lr-page").hasClass("span4 offset4")) {

      $(".lr-page").removeClass("span4 offset4");
      $(".lr-page").addClass("span6 offset3");

      $("#page-title").removeClass("span4 offset4");
      $("#page-title").addClass("span6 offset3");
    }

  } else {

    if($("#wall").width()) {

      if($(".item").hasClass("span4")) {

        $(".item").removeClass("span4");
        $(".item").addClass("span3");

      }

    }

    if($(".lr-page").hasClass("span6 offset3")) {

      $(".lr-page").removeClass("span6 offset3");
      $(".lr-page").addClass("span4 offset4");

      $("#page-title").removeClass("span6 offset3");
      $("#page-title").addClass("span4 offset4");
    }

  }

}<commit_msg>Try to fix Annotorious-jQuery conflict #95<commit_after>
/* TODO: This is only part of the original template JS */

/* -------------------- Check Browser --------------------- */

function browser() {

  //var isOpera = !!(window.opera && window.opera.version);  // Opera 8.0+
  //var isFirefox = testCSS('MozBoxSizing');                 // FF 0.8+
  var isSafari = Object.prototype.toString.call(window.HTMLElement).indexOf('Constructor') > 0;
      // At least Safari 3+: "[object HTMLElementConstructor]"
  var isChrome = !isSafari && testCSS('WebkitTransform');  // Chrome 1+
  //var isIE = /*@cc_on!@*/false || testCSS('msTransform');  // At least IE6

  function testCSS(prop) {
      return prop in document.documentElement.style;
  }

  if (isSafari || isChrome) {

    return true;

  } else {

    return false;

  }

}

/* -------------------- Search --------------------- */

jQuery(document).ready(function($){

  $('.search > :input').on('keyup',function(){

    $(this).attr('class', 'activeSearch');

    var count;
    var timeToEnd = 1000;

    $(':input').keydown(function(){

      clearTimeout(count);

      count = setTimeout(endCount, timeToEnd);

    });

  });

  function endCount(){

    $('.search > :input').attr('class','search-form');

  }

});

/* -------------------- Buttons 3D Style --------------------- */

jQuery(document).ready(function($){

  $(':button').each(function(){

    if($(this).hasClass('btn-tabula')) {

      $(this).wrap('
');

      var inner = $(this).html();

      if(browser()) {

        $(this).html('' + inner + '');

      }

    }

  });

  $('a').each(function(){

    if($(this).hasClass('btnOverlay')) {

      $(this).wrap('
');

      var inner = $(this).html();

      if(browser()) {

        $(this).html('' + inner + '');

      }

    }

  });

});

/* ------------------ Back To Top ------------------- */
jQuery(document).ready(function($){

  jQuery('#under-footer-back-to-top a').click(function(){
    jQuery('html, body').animate({scrollTop:0}, 300);
    return false;
  });

});

/* ------------------ Tooltips ----------------- */

jQuery(document).ready(function($) {

    $('.tooltips').tooltip({
      selector: "a[rel=tooltip]"
    })

});

/* -------------------- Isotope --------------------- */
/* dcabo: This was called on ready() in the original template, but images overlapped
          when using Turbolinks (only in Firefox, maybe). See discussion at
          https://github.com/rails/turbolinks/issues/159
/* dcabo: Nah, undo, didn't fix it but broke the search page for some reason. Will
          try something else. */

jQuery(document).ready(function () {

  $('#wall').imagesLoaded(function() {

    var $container = $('#wall');
      $select = $('#filters select');

    // initialize Isotope
    $container.isotope({
    // options...
    resizable: false, // disable normal resizing
    // set columnWidth to a percentage of container width
      masonry: { columnWidth: $container.width() / 12 }
    });

    // update columnWidth on window resize
    $(window).smartresize(function(){

      $container.isotope({
      // update columnWidth to a percentage of container width
        masonry: { columnWidth: $container.width() / 12 }
      });
    });

    $container.isotope({
      itemSelector : '.item'
    });

    $select.change(function() {

      var filters = $(this).val();

        $container.isotope({
          filter: filters
        });

      });

      var $optionSets = $('#filters .option-set'),
        $optionLinks = $optionSets.find('a');

        $optionLinks.click(function(){

        var $this = $(this);
        // don't proceed if already selected
        if ( $this.hasClass('selected') ) {
            return false;
        }
      var $optionSet = $this.parents('.option-set');
      $optionSet.find('.selected').removeClass('selected');
      $this.addClass('selected');

      // make option object dynamically, i.e. { filter: '.my-filter-class' }
      var options = {},
        key = $optionSet.attr('data-option-key'),
        value = $this.attr('data-option-value');
      // parse 'false' as false boolean
      value = value === 'false' ? false : value;
      options[ key ] = value;
      if ( key === 'layoutMode' && typeof changeLayoutMode === 'function' ) {
        // changes in layout modes need extra logic
        changeLayoutMode( $this, options )
      } else {
        // otherwise, apply new options
        $container.isotope( options );
      }

      return false;

      });

  });

});

/* -------------------- Width Functions --------------------- */

jQuery(document).ready(function($){

  widthFunctions();

});

$(window).bind("resize", widthFunctions);

function widthFunctions(e) {
  $=jQuery; /* Strange interactions with Annotorious going on */

  var winHeight = $(window).height();
  var winWidth = $(window).width();

  if (winWidth < 980 && winWidth > 767) {

    if($("#wall").width()) {

      if($(".item").hasClass("span3")) {

        $(".item").removeClass("span3");
        $(".item").addClass("span4");

      }

    }

    if($(".lr-page").hasClass("span4 offset4")) {

      $(".lr-page").removeClass("span4 offset4");
      $(".lr-page").addClass("span6 offset3");

      $("#page-title").removeClass("span4 offset4");
      $("#page-title").addClass("span6 offset3");
    }

  } else {

    if($("#wall").width()) {

      if($(".item").hasClass("span4")) {

        $(".item").removeClass("span4");
        $(".item").addClass("span3");

      }

    }

    if($(".lr-page").hasClass("span6 offset3")) {

      $(".lr-page").removeClass("span6 offset3");
      $(".lr-page").addClass("span4 offset4");

      $("#page-title").removeClass("span6 offset3");
      $("#page-title").addClass("span4 offset4");
    }

  }

}<|endoftext|>


<commit_before>// ==========================================================================
// Project:   SproutCore - JavaScript Application Framework
// Copyright: ©2006-2011 Strobe Inc. and contributors.
//            Portions ©2008-2010 Apple Inc. All rights reserved.
// License:   Licensed under MIT license (see license.js)
// ==========================================================================

/**
  The Locale defined information about a specific locale, including date and
  number formatting conventions, and localization strings.  You can define
  various locales by adding them to the SC.locales hash, keyed by language
  and/or country code.

  On page load, the default locale will be chosen based on the current
  languages and saved at SC.Locale.current.  This locale is used for
  localization, etc.

  h2. Creating a new locale

  You can create a locale by simply extending the SC.Locale class and adding
  it to the locales hash:

  {{{
    SC.Locale.locales['en'] = SC.Locale.extend({ .. config .. }) ;
  }}}

  Alternatively, you could choose to base your locale on another locale by
  extending that locale:

  {{{
    SC.Locale.locales['en-US'] = SC.Locale.locales['en'].extend({ ... }) ;
  }}}

  Note that if you do not define your own strings property, then your locale
  will inherit any strings added to the parent locale.  Otherwise you must
  implement your own strings instead.

  @extends SC.Object
  @since SproutCore 1.0
*/
SC.Locale = SC.Object.extend({

  init: function() {
    // make sure we know the name of our own locale.
    if (!this.language) SC.Locale._assignLocales();

    // Make sure we have strings that were set using the new API.  To do this
    // we check to a bool that is set by one of the string helpers.  This
    // indicates that the new API was used. If the new API was not used, we
    // check to see if the old API was used (which places strings on the
    // String class).
    if (!this.hasStrings) {
      var langs = this._deprecatedLanguageCodes || [] ;
      langs.push(this.language);
      var idx = langs.length ;
      var strings = null ;
      while(!strings && --idx >= 0) {
        strings = String[langs[idx]];
      }
      if (strings) {
        this.hasStrings = YES;
        this.strings = strings ;
      }
    }
  },

  /** Set to YES when strings have been added to this locale. */
  hasStrings: NO,

  /** The strings hash for this locale. */
  strings: {},

  toString: function() {
    if (!this.language) SC.Locale._assignLocales() ;
    return "SC.Locale["+this.language+"]"+SC.guidFor(this) ;
  },

  /**
    Returns the localized version of the string or the string if no match
    was found.

    @param {String} string
    @param {String} optional default string to return instead
    @returns {String}
  */
  locWithDefault: function(string, def) {
    var ret = this.strings[string];

    // strings may be blank, so test with typeOf.
    if (SC.typeOf(ret) === SC.T_STRING) return ret;
    else if (SC.typeOf(def) === SC.T_STRING) return def;
    return string;
  }

}) ;

SC.Locale.mixin(/** @scope SC.Locale */ {

  /**
    If YES, localization will favor the detected language instead of the
    preferred one.
  */
  useAutodetectedLanguage: NO,

  /**
    This property is set by the build tools to the current build language.
  */
  preferredLanguage: null,

  /**
    Invoked at the start of SproutCore's document onready handler to setup
    the currentLocale.  This will use the language properties you have set on
    the locale to make a decision.
  */
  createCurrentLocale: function() {

    // get values from String if defined for compatibility with < 1.0 build
    // tools.
    var autodetect = (String.useAutodetectedLanguage !== undefined) ? String.useAutodetectedLanguage : this.useAutodetectedLanguage;
    var preferred = (String.preferredLanguage !== undefined) ? String.preferredLanguage : this.preferredLanguage ;

    // determine the language
    var lang = ((autodetect) ? SC.browser.language : null) || preferred || SC.browser.language || 'en';
    lang = SC.Locale.normalizeLanguage(lang) ;

    // get the locale class.  If a class cannot be found, fall back to generic
    // language then to english.
    var klass = this.localeClassFor(lang) ;

    // if the detected language does not match the current language (or there
    // is none) then set it up.
    if (lang != this.currentLanguage) {
      this.currentLanguage = lang ; // save language
      this.currentLocale = klass.create(); // setup locale
    }
    return this.currentLocale ;
  },

  /**
    Finds the locale class for the names language code or creates on based on
    its most likely parent.
  */
  localeClassFor: function(lang) {
    lang = SC.Locale.normalizeLanguage(lang) ;
    var parent, klass = this.locales[lang];

    // if locale class was not found and there is a broader-based locale
    // present, create a new locale based on that.
    if (!klass && ((parent = lang.split('-')[0]) !== lang) && (klass = this.locales[parent])) {
      klass = this.locales[lang] = klass.extend() ;
    }

    // otherwise, try to create a new locale based on english.
    if (!klass) klass = this.locales[lang] = this.locales.en.extend();

    return klass;
  },

  /**
    Shorthand method to define the settings for a particular locale.
    The settings you pass here will be applied directly to the locale you
    designate.

    If you are already holding a reference to a locale definition, you can
    also use this method to operate on the receiver.

    If the locale you name does not exist yet, this method will create the
    locale for you, based on the most closely related locale or english.  For
    example, if you name the locale 'fr-CA', you will be creating a locale for
    French as it is used in Canada.  This will be based on the general French
    locale (fr), since that is more generic.  On the other hand, if you create
    a locale for manadarin (cn), it will be based on generic english (en)
    since there is no broader language code to match against.

    @param {String} localeName
    @param {Hash} options
    @returns {SC.Locale} the defined locale
  */
  define: function(localeName, options) {
    var locale ;
    if (options===undefined && (SC.typeOf(localeName) !== SC.T_STRING)) {
      locale = this; options = localeName ;
    } else locale = SC.Locale.localeClassFor(localeName) ;
    SC.mixin(locale.prototype, options) ;
    return locale ;
  },

  /**
    Gets the current options for the receiver locale.  This is useful for
    inspecting registered locales that have not been instantiated.

    @returns {Hash} options + instance methods
  */
  options: function() { return this.prototype; },

  /**
    Adds the passed hash of strings to the locale's strings table.  Note that
    if the receiver locale inherits its strings from its parent, then the
    strings table will be cloned first.

    @returns {Object} receiver
  */
  addStrings: function(stringsHash) {
    // make sure the target strings hash exists and belongs to the locale
    var strings = this.prototype.strings ;
    if (strings) {
      if (!this.prototype.hasOwnProperty('strings')) {
        this.prototype.strings = SC.clone(strings) ;
      }
    } else strings = this.prototype.strings = {} ;

    // add strings hash
    if (stringsHash)  this.prototype.strings = SC.mixin(strings, stringsHash) ;
    this.prototype.hasStrings = YES ;
    return this;
  },

  _map: { english: 'en', french: 'fr', german: 'de', japanese: 'ja', jp: 'ja', spanish: 'es' },

  /**
    Normalizes the passed language into a two-character language code.
    This method allows you to specify common languages in their full english
    name (i.e. English, French, etc). and it will be treated like their two
    letter code equivalent.

    @param {String} languageCode
    @returns {String} normalized code
  */
  normalizeLanguage: function(languageCode) {
    if (!languageCode) return 'en' ;
    return SC.Locale._map[languageCode.toLowerCase()] || languageCode ;
  },

  // this method is called once during init to walk the installed locales
  // and make sure they know their own names.
  _assignLocales: function() {
    for(var key in this.locales) this.locales[key].prototype.language = key;
  },

  toString: function() {
    if (!this.prototype.language) SC.Locale._assignLocales() ;
    return "SC.Locale["+this.prototype.language+"]" ;
  },

  // make sure important properties are copied to new class.
  extend: function() {
    var ret= SC.Object.extend.apply(this, arguments) ;
    ret.addStrings= SC.Locale.addStrings;
    ret.define = SC.Locale.define ;
    ret.options = SC.Locale.options ;
    ret.toString = SC.Locale.toString ;
    return ret ;
  }

}) ;

/**
  This locales hash contains all of the locales defined by SproutCore and
  by your own application.  See the SC.Locale class definition for the
  various properties you can set on your own locales.

  @property {Hash}
*/
SC.Locale.locales = {
  en: SC.Locale.extend({ _deprecatedLanguageCodes: ['English'] }),
  fr: SC.Locale.extend({ _deprecatedLanguageCodes: ['French'] }),
  de: SC.Locale.extend({ _deprecatedLanguageCodes: ['German'] }),
  ja: SC.Locale.extend({ _deprecatedLanguageCodes: ['Japanese', 'jp'] }),
  es: SC.Locale.extend({ _deprecatedLanguageCodes: ['Spanish'] })
} ;

SC.Locale.locales['en-NP'] = SC.Locale.locales['en'].extend({
  locWithDefault: function(string, def) {
    var ret = this.strings[string];

    // strings may be blank, so test with typeOf.
    if (SC.typeOf(ret) === SC.T_STRING) return ret;
    else if (SC.typeOf(def) === SC.T_STRING) return def;
    return string;
  }

}) ;

/**
  This special helper will store the strings you pass in the locale matching
  the language code.  If a locale is not defined from the language code you
  specify, then one will be created for you with the english locale as the
  parent.

  @param {String} languageCode
  @param {Hash} strings
  @returns {Object} receiver
*/
SC.stringsFor = function(languageCode, strings) {
  // get the locale, creating one if needed.
  var locale = SC.Locale.localeClassFor(languageCode);
  locale.addStrings(strings) ;
  return this ;
} ;

<commit_msg>lower case<commit_after>// ==========================================================================
// Project:   SproutCore - JavaScript Application Framework
// Copyright: ©2006-2011 Strobe Inc. and contributors.
//            Portions ©2008-2010 Apple Inc. All rights reserved.
// License:   Licensed under MIT license (see license.js)
// ==========================================================================

/**
  The Locale defined information about a specific locale, including date and
  number formatting conventions, and localization strings.  You can define
  various locales by adding them to the SC.locales hash, keyed by language
  and/or country code.

  On page load, the default locale will be chosen based on the current
  languages and saved at SC.Locale.current.  This locale is used for
  localization, etc.

  h2. Creating a new locale

  You can create a locale by simply extending the SC.Locale class and adding
  it to the locales hash:

  {{{
    SC.Locale.locales['en'] = SC.Locale.extend({ .. config .. }) ;
  }}}

  Alternatively, you could choose to base your locale on another locale by
  extending that locale:

  {{{
    SC.Locale.locales['en-US'] = SC.Locale.locales['en'].extend({ ... }) ;
  }}}

  Note that if you do not define your own strings property, then your locale
  will inherit any strings added to the parent locale.  Otherwise you must
  implement your own strings instead.

  @extends SC.Object
  @since SproutCore 1.0
*/
SC.Locale = SC.Object.extend({

  init: function() {
    // make sure we know the name of our own locale.
    if (!this.language) SC.Locale._assignLocales();

    // Make sure we have strings that were set using the new API.  To do this
    // we check to a bool that is set by one of the string helpers.  This
    // indicates that the new API was used. If the new API was not used, we
    // check to see if the old API was used (which places strings on the
    // String class).
    if (!this.hasStrings) {
      var langs = this._deprecatedLanguageCodes || [] ;
      langs.push(this.language);
      var idx = langs.length ;
      var strings = null ;
      while(!strings && --idx >= 0) {
        strings = String[langs[idx]];
      }
      if (strings) {
        this.hasStrings = YES;
        this.strings = strings ;
      }
    }
  },

  /** Set to YES when strings have been added to this locale. */
  hasStrings: NO,

  /** The strings hash for this locale. */
  strings: {},

  toString: function() {
    if (!this.language) SC.Locale._assignLocales() ;
    return "SC.Locale["+this.language+"]"+SC.guidFor(this) ;
  },

  /**
    Returns the localized version of the string or the string if no match
    was found.

    @param {String} string
    @param {String} optional default string to return instead
    @returns {String}
  */
  locWithDefault: function(string, def) {
    var ret = this.strings[string];

    // strings may be blank, so test with typeOf.
    if (SC.typeOf(ret) === SC.T_STRING) return ret;
    else if (SC.typeOf(def) === SC.T_STRING) return def;
    return string;
  }

}) ;

SC.Locale.mixin(/** @scope SC.Locale */ {

  /**
    If YES, localization will favor the detected language instead of the
    preferred one.
  */
  useAutodetectedLanguage: NO,

  /**
    This property is set by the build tools to the current build language.
  */
  preferredLanguage: null,

  /**
    Invoked at the start of SproutCore's document onready handler to setup
    the currentLocale.  This will use the language properties you have set on
    the locale to make a decision.
  */
  createCurrentLocale: function() {

    // get values from String if defined for compatibility with < 1.0 build
    // tools.
    var autodetect = (String.useAutodetectedLanguage !== undefined) ? String.useAutodetectedLanguage : this.useAutodetectedLanguage;
    var preferred = (String.preferredLanguage !== undefined) ? String.preferredLanguage : this.preferredLanguage ;

    // determine the language
    var lang = ((autodetect) ? SC.browser.language : null) || preferred || SC.browser.language || 'en';
    lang = SC.Locale.normalizeLanguage(lang) ;

    // get the locale class.  If a class cannot be found, fall back to generic
    // language then to english.
    var klass = this.localeClassFor(lang) ;

    // if the detected language does not match the current language (or there
    // is none) then set it up.
    if (lang != this.currentLanguage) {
      this.currentLanguage = lang ; // save language
      this.currentLocale = klass.create(); // setup locale
    }
    return this.currentLocale ;
  },

  /**
    Finds the locale class for the names language code or creates on based on
    its most likely parent.
  */
  localeClassFor: function(lang) {
    lang = SC.Locale.normalizeLanguage(lang) ;
    var parent, klass = this.locales[lang];

    // if locale class was not found and there is a broader-based locale
    // present, create a new locale based on that.
    if (!klass && ((parent = lang.split('-')[0]) !== lang) && (klass = this.locales[parent])) {
      klass = this.locales[lang] = klass.extend() ;
    }

    // otherwise, try to create a new locale based on english.
    if (!klass) klass = this.locales[lang] = this.locales.en.extend();

    return klass;
  },

  /**
    Shorthand method to define the settings for a particular locale.
    The settings you pass here will be applied directly to the locale you
    designate.

    If you are already holding a reference to a locale definition, you can
    also use this method to operate on the receiver.

    If the locale you name does not exist yet, this method will create the
    locale for you, based on the most closely related locale or english.  For
    example, if you name the locale 'fr-CA', you will be creating a locale for
    French as it is used in Canada.  This will be based on the general French
    locale (fr), since that is more generic.  On the other hand, if you create
    a locale for manadarin (cn), it will be based on generic english (en)
    since there is no broader language code to match against.

    @param {String} localeName
    @param {Hash} options
    @returns {SC.Locale} the defined locale
  */
  define: function(localeName, options) {
    var locale ;
    if (options===undefined && (SC.typeOf(localeName) !== SC.T_STRING)) {
      locale = this; options = localeName ;
    } else locale = SC.Locale.localeClassFor(localeName) ;
    SC.mixin(locale.prototype, options) ;
    return locale ;
  },

  /**
    Gets the current options for the receiver locale.  This is useful for
    inspecting registered locales that have not been instantiated.

    @returns {Hash} options + instance methods
  */
  options: function() { return this.prototype; },

  /**
    Adds the passed hash of strings to the locale's strings table.  Note that
    if the receiver locale inherits its strings from its parent, then the
    strings table will be cloned first.

    @returns {Object} receiver
  */
  addStrings: function(stringsHash) {
    // make sure the target strings hash exists and belongs to the locale
    var strings = this.prototype.strings ;
    if (strings) {
      if (!this.prototype.hasOwnProperty('strings')) {
        this.prototype.strings = SC.clone(strings) ;
      }
    } else strings = this.prototype.strings = {} ;

    // add strings hash
    if (stringsHash)  this.prototype.strings = SC.mixin(strings, stringsHash) ;
    this.prototype.hasStrings = YES ;
    return this;
  },

  _map: { english: 'en', french: 'fr', german: 'de', japanese: 'ja', jp: 'ja', spanish: 'es' },

  /**
    Normalizes the passed language into a two-character language code.
    This method allows you to specify common languages in their full english
    name (i.e. English, French, etc). and it will be treated like their two
    letter code equivalent.

    @param {String} languageCode
    @returns {String} normalized code
  */
  normalizeLanguage: function(languageCode) {
    if (!languageCode) return 'en' ;
    return SC.Locale._map[languageCode.toLowerCase()] || languageCode ;
  },

  // this method is called once during init to walk the installed locales
  // and make sure they know their own names.
  _assignLocales: function() {
    for(var key in this.locales) this.locales[key].prototype.language = key;
  },

  toString: function() {
    if (!this.prototype.language) SC.Locale._assignLocales() ;
    return "SC.Locale["+this.prototype.language+"]" ;
  },

  // make sure important properties are copied to new class.
  extend: function() {
    var ret= SC.Object.extend.apply(this, arguments) ;
    ret.addStrings= SC.Locale.addStrings;
    ret.define = SC.Locale.define ;
    ret.options = SC.Locale.options ;
    ret.toString = SC.Locale.toString ;
    return ret ;
  }

}) ;

/**
  This locales hash contains all of the locales defined by SproutCore and
  by your own application.  See the SC.Locale class definition for the
  various properties you can set on your own locales.

  @property {Hash}
*/
SC.Locale.locales = {
  en: SC.Locale.extend({ _deprecatedLanguageCodes: ['English'] }),
  fr: SC.Locale.extend({ _deprecatedLanguageCodes: ['French'] }),
  de: SC.Locale.extend({ _deprecatedLanguageCodes: ['German'] }),
  ja: SC.Locale.extend({ _deprecatedLanguageCodes: ['Japanese', 'jp'] }),
  es: SC.Locale.extend({ _deprecatedLanguageCodes: ['Spanish'] })
} ;

SC.Locale.locales['en-np'] = SC.Locale.locales['en'].extend({
  locWithDefault: function(string, def) {
    var ret = this.strings[string];

    // strings may be blank, so test with typeOf.
    if (SC.typeOf(ret) === SC.T_STRING) return ret;
    else if (SC.typeOf(def) === SC.T_STRING) return def;
    return string;
  }

}) ;

/**
  This special helper will store the strings you pass in the locale matching
  the language code.  If a locale is not defined from the language code you
  specify, then one will be created for you with the english locale as the
  parent.

  @param {String} languageCode
  @param {Hash} strings
  @returns {Object} receiver
*/
SC.stringsFor = function(languageCode, strings) {
  // get the locale, creating one if needed.
  var locale = SC.Locale.localeClassFor(languageCode);
  locale.addStrings(strings) ;
  return this ;
} ;

<|endoftext|>


<commit_before>define(["dist/resolver"], function(Resolver) {

  describe("Resolver Suite", function() {
    describe("When Resolver is configured with `packages`", function() {
      var resolver;
      beforeEach(function() {
        resolver = new Resolver({
          "packages": [
            "pacakge1", {
              "name": "package2"
            }, {
              "location": "good/tests",
              "main": "index",
              "name": "assets"
            }, {
              "location": "good/tests",
              "name": "lib"
            }
          ]
        });
      });

      describe("When processing package 'pacakge1'", function() {
        var moduleMeta;
        beforeEach(function() {
          moduleMeta = resolver.resolve("pacakge1");
        });

        it("then package is 'pacakge1/main.js'", function() {
          expect(moduleMeta.file.toUrl()).to.equal("pacakge1/main.js");
        });
      });

      describe("And processing package 'package2'", function() {
        var moduleMeta;
        beforeEach(function() {
          moduleMeta = resolver.resolve("package2");
        });

        it("then package is 'package2/main.js'", function() {
          expect(moduleMeta.file.toUrl()).to.equal("package2/main.js");
        });
      });

      describe("And processing package 'lib'", function() {
        var moduleMeta;
        beforeEach(function() {
          moduleMeta = resolver.resolve("lib");
        });

        it("then package is 'good/tests/lib/main.js'", function() {
          expect(moduleMeta.file.toUrl()).to.equal("good/tests/lib/main.js");
        });
      });

      describe("And processing package `assets`", function() {
        it("then resolving package `assets` is `good/tests/assets/index.js`", function() {
          var moduleMeta = resolver.resolve("assets");
          expect(moduleMeta.file.toUrl()).to.equal("good/tests/assets/index.js");
        });

        it("then resolving `assets/library/mod` is 'good/tests/assets/library/mod.js'", function() {
          var moduleMeta = resolver.resolve("assets/library/mod");
          expect(moduleMeta.file.toUrl()).to.equal("good/tests/assets/library/mod.js");
        });

        it("then resolving `assets/library/template.html` is 'good/tests/assets/library/template.html'", function() {
          var moduleMeta = resolver.resolve("assets/library/template.html");
          expect(moduleMeta.file.toUrl()).to.equal("good/tests/assets/library/template.html");
        });
      });
    });

    describe("When Resolver is configured with `shim`", function() {
      var resolver;
      beforeEach(function() {
        resolver = new Resolver({
          "shim": {
            "machine": {
              "exports": "mch"
            },
            "jimmy": {
              "name": "coffee",
              "deps": ["trucks", "passport"]
            },
            "macho": {
              "exports": "camacho",
              "imports": ["guns", "president"]
            }
          }
        });
      });

      describe("and resolving shim `machine`", function() {
        var moduleMeta;
        beforeEach(function() {
          moduleMeta = resolver.resolve("machine");
        });

        it("then shim is an object", function() {
          expect(moduleMeta.shim).to.be.an("object");
        });

        it("exports is `mch`", function() {
          expect(moduleMeta.shim.name).to.equal("mch");
        });

        it("deps is an array", function() {
          expect(moduleMeta.shim.deps).to.be.an("array");
        });

        it("deps is empty", function() {
          expect(moduleMeta.shim.deps.length).to.equal(0);
        });
      });

      describe("and resolving shim `jimmy`", function() {
        var moduleMeta;
        beforeEach(function() {
          moduleMeta = resolver.resolve("jimmy");
        });

        it("then shim is an object", function() {
          expect(moduleMeta.shim).to.be.an("object");
        });

        it("name is `coffee`", function() {
          expect(moduleMeta.shim.name).to.equal("coffee");
        });

        it("deps is an array", function() {
          expect(moduleMeta.shim.deps).to.be.an("array");
        });

        it("deps to have two entries", function() {
          expect(moduleMeta.shim.deps.length).to.equal(2);
        });

        it("deps[0] is `trucks`", function() {
          expect(moduleMeta.shim.deps[0]).to.equal("trucks");
        });

        it("deps[1] is `passport`", function() {
          expect(moduleMeta.shim.deps[1]).to.equal("passport");
        });
      });

      describe("and resolving shim `macho`", function() {
        var moduleMeta;
        beforeEach(function() {
          moduleMeta = resolver.resolve("macho");
        });

        it("then shim is an object", function() {
          expect(moduleMeta.shim).to.be.an("object");
        });

        it("then shim exports `camacho`", function() {
          expect(moduleMeta.shim.name).to.equal("camacho");
        });

        it("them shim imports `guns`", function() {
          expect(moduleMeta.shim.deps[0]).to.equal("guns");
        });

        it("them shim imports `president`", function() {
          expect(moduleMeta.shim.deps[1]).to.equal("president");
        });
      });

      describe("and resolving with `unknown`", function() {
        var moduleMeta;
        beforeEach(function() {
          moduleMeta = resolver.resolve("unknown");
        });

        it("then shim is undefined", function() {
          expect(moduleMeta.shim).to.undefined();
        });
      });
    });

    describe("When Resolver is configured with `paths`", function() {
      var resolver;
      beforeEach(function() {
        resolver = new Resolver({
          "paths": {
            "machine": "path/to/module/1",
            "kitchen": "../path/to/kitchen/and/sink",
            "tree": "./hugger"
          }
        });
      });

      describe("and resolving with `machine`", function() {
        var moduleMeta;
        beforeEach(function() {
          moduleMeta = resolver.resolve("machine");
        });

        it("then name is `machine`", function() {
          expect(moduleMeta.name).to.equal("machine");
        });

        it("then moduleMeta.file.toUrl() is `path/to/module/1.js`", function() {
          expect(moduleMeta.file.toUrl()).to.equal("path/to/module/1.js");
        });
      });

      describe("and resolving with `kitchen`", function() {
        var moduleMeta;
        beforeEach(function() {
          moduleMeta = resolver.resolve("kitchen");
        });

        it("then name is `kitchen`", function() {
          expect(moduleMeta.name).to.equal("kitchen");
        });

        it("then moduleMeta.file.toUrl() is `../path/to/kitchen/and/sink.js`", function() {
          expect(moduleMeta.file.toUrl()).to.equal("../path/to/kitchen/and/sink.js");
        });
      });

      describe("and resolving with `tree`", function() {
        var moduleMeta;
        beforeEach(function() {
          moduleMeta = resolver.resolve("tree");
        });

        it("then name is `tree`", function() {
          expect(moduleMeta.name).to.equal("tree");
        });

        it("then moduleMeta.file.toUrl() is `./hugger.js`", function() {
          expect(moduleMeta.file.toUrl()).to.equal("./hugger.js");
        });
      });
    });

    describe("When Resolver has plugins", function() {
      var resolver;
      beforeEach(function() {
        resolver = new Resolver();
      });

      describe("and a module name is `path/to/file.css`", function() {
        var moduleMeta;
        beforeEach(function() {
          moduleMeta = resolver.resolve("path/to/file.css");
        });

        it("then module name is `path/to/file.css`", function() {
          expect(moduleMeta.name).to.equal("path/to/file.css");
        });

        it("then first plugin is an empty array", function() {
          expect(moduleMeta.plugins.length).to.equal(0);
        });
      });

      describe("and a module name is `less!css!path/to/file.css`", function() {
        var moduleMeta;
        beforeEach(function() {
          moduleMeta = resolver.resolve("less!css!path/to/file.css");
        });

        it("then module name is `path/to/file.css`", function() {
          expect(moduleMeta.name).to.equal("path/to/file.css");
        });

        it("then first plugin is an array with two items", function() {
          expect(moduleMeta.plugins.length).to.equal(2);
        });

        it("then first plugin is `less`", function() {
          expect(moduleMeta.plugins[0]).to.equal("less");
        });

        it("then second plugin is `css`", function() {
          expect(moduleMeta.plugins[1]).to.equal("css");
        });
      });
    });

    describe("When Resolver is configured with `baseUrl`", function() {
      it("needs tests");
    });

  });
});
<commit_msg>Adding another test case for packages with extension<commit_after>define(["dist/resolver"], function(Resolver) {

  describe("Resolver Suite", function() {
    describe("When Resolver is configured with `packages`", function() {
      var resolver;
      beforeEach(function() {
        resolver = new Resolver({
          "packages": [
            "pacakge1", {
              "name": "package2"
            }, {
              "location": "good/tests",
              "main": "index",
              "name": "assets"
            }, {
              "location": "good/tests",
              "name": "lib"
            }
          ]
        });
      });

      describe("When processing package 'pacakge1'", function() {
        var moduleMeta;
        beforeEach(function() {
          moduleMeta = resolver.resolve("pacakge1");
        });

        it("then package is 'pacakge1/main.js'", function() {
          expect(moduleMeta.file.toUrl()).to.equal("pacakge1/main.js");
        });
      });

      describe("And processing package 'package2'", function() {
        var moduleMeta;
        beforeEach(function() {
          moduleMeta = resolver.resolve("package2");
        });

        it("then package is 'package2/main.js'", function() {
          expect(moduleMeta.file.toUrl()).to.equal("package2/main.js");
        });
      });

      describe("And processing package 'lib'", function() {
        var moduleMeta;
        beforeEach(function() {
          moduleMeta = resolver.resolve("lib");
        });

        it("then package is 'good/tests/lib/main.js'", function() {
          expect(moduleMeta.file.toUrl()).to.equal("good/tests/lib/main.js");
        });
      });

      describe("And processing package `assets`", function() {
        it("then resolving package `assets` is `good/tests/assets/index.js`", function() {
          var moduleMeta = resolver.resolve("assets");
          expect(moduleMeta.file.toUrl()).to.equal("good/tests/assets/index.js");
        });

        it("then resolving `assets/library/mod` is 'good/tests/assets/library/mod.js'", function() {
          var moduleMeta = resolver.resolve("assets/library/mod");
          expect(moduleMeta.file.toUrl()).to.equal("good/tests/assets/library/mod.js");
        });

        it("then resolving `assets/library/mod.js` is 'good/tests/assets/library/mod.js'", function() {
          var moduleMeta = resolver.resolve("assets/library/mod.js");
          expect(moduleMeta.file.toUrl()).to.equal("good/tests/assets/library/mod.js");
        });

        it("then resolving `assets/library/template.html` is 'good/tests/assets/library/template.html'", function() {
          var moduleMeta = resolver.resolve("assets/library/template.html");
          expect(moduleMeta.file.toUrl()).to.equal("good/tests/assets/library/template.html");
        });
      });
    });

    describe("When Resolver is configured with `shim`", function() {
      var resolver;
      beforeEach(function() {
        resolver = new Resolver({
          "shim": {
            "machine": {
              "exports": "mch"
            },
            "jimmy": {
              "name": "coffee",
              "deps": ["trucks", "passport"]
            },
            "macho": {
              "exports": "camacho",
              "imports": ["guns", "president"]
            }
          }
        });
      });

      describe("and resolving shim `machine`", function() {
        var moduleMeta;
        beforeEach(function() {
          moduleMeta = resolver.resolve("machine");
        });

        it("then shim is an object", function() {
          expect(moduleMeta.shim).to.be.an("object");
        });

        it("exports is `mch`", function() {
          expect(moduleMeta.shim.name).to.equal("mch");
        });

        it("deps is an array", function() {
          expect(moduleMeta.shim.deps).to.be.an("array");
        });

        it("deps is empty", function() {
          expect(moduleMeta.shim.deps.length).to.equal(0);
        });
      });

      describe("and resolving shim `jimmy`", function() {
        var moduleMeta;
        beforeEach(function() {
          moduleMeta = resolver.resolve("jimmy");
        });

        it("then shim is an object", function() {
          expect(moduleMeta.shim).to.be.an("object");
        });

        it("name is `coffee`", function() {
          expect(moduleMeta.shim.name).to.equal("coffee");
        });

        it("deps is an array", function() {
          expect(moduleMeta.shim.deps).to.be.an("array");
        });

        it("deps to have two entries", function() {
          expect(moduleMeta.shim.deps.length).to.equal(2);
        });

        it("deps[0] is `trucks`", function() {
          expect(moduleMeta.shim.deps[0]).to.equal("trucks");
        });

        it("deps[1] is `passport`", function() {
          expect(moduleMeta.shim.deps[1]).to.equal("passport");
        });
      });

      describe("and resolving shim `macho`", function() {
        var moduleMeta;
        beforeEach(function() {
          moduleMeta = resolver.resolve("macho");
        });

        it("then shim is an object", function() {
          expect(moduleMeta.shim).to.be.an("object");
        });

        it("then shim exports `camacho`", function() {
          expect(moduleMeta.shim.name).to.equal("camacho");
        });

        it("them shim imports `guns`", function() {
          expect(moduleMeta.shim.deps[0]).to.equal("guns");
        });

        it("them shim imports `president`", function() {
          expect(moduleMeta.shim.deps[1]).to.equal("president");
        });
      });

      describe("and resolving with `unknown`", function() {
        var moduleMeta;
        beforeEach(function() {
          moduleMeta = resolver.resolve("unknown");
        });

        it("then shim is undefined", function() {
          expect(moduleMeta.shim).to.undefined();
        });
      });
    });

    describe("When Resolver is configured with `paths`", function() {
      var resolver;
      beforeEach(function() {
        resolver = new Resolver({
          "paths": {
            "machine": "path/to/module/1",
            "kitchen": "../path/to/kitchen/and/sink",
            "tree": "./hugger"
          }
        });
      });

      describe("and resolving with `machine`", function() {
        var moduleMeta;
        beforeEach(function() {
          moduleMeta = resolver.resolve("machine");
        });

        it("then name is `machine`", function() {
          expect(moduleMeta.name).to.equal("machine");
        });

        it("then moduleMeta.file.toUrl() is `path/to/module/1.js`", function() {
          expect(moduleMeta.file.toUrl()).to.equal("path/to/module/1.js");
        });
      });

      describe("and resolving with `kitchen`", function() {
        var moduleMeta;
        beforeEach(function() {
          moduleMeta = resolver.resolve("kitchen");
        });

        it("then name is `kitchen`", function() {
          expect(moduleMeta.name).to.equal("kitchen");
        });

        it("then moduleMeta.file.toUrl() is `../path/to/kitchen/and/sink.js`", function() {
          expect(moduleMeta.file.toUrl()).to.equal("../path/to/kitchen/and/sink.js");
        });
      });

      describe("and resolving with `tree`", function() {
        var moduleMeta;
        beforeEach(function() {
          moduleMeta = resolver.resolve("tree");
        });

        it("then name is `tree`", function() {
          expect(moduleMeta.name).to.equal("tree");
        });

        it("then moduleMeta.file.toUrl() is `./hugger.js`", function() {
          expect(moduleMeta.file.toUrl()).to.equal("./hugger.js");
        });
      });
    });

    describe("When Resolver has plugins", function() {
      var resolver;
      beforeEach(function() {
        resolver = new Resolver();
      });

      describe("and a module name is `path/to/file.css`", function() {
        var moduleMeta;
        beforeEach(function() {
          moduleMeta = resolver.resolve("path/to/file.css");
        });

        it("then module name is `path/to/file.css`", function() {
          expect(moduleMeta.name).to.equal("path/to/file.css");
        });

        it("then first plugin is an empty array", function() {
          expect(moduleMeta.plugins.length).to.equal(0);
        });
      });

      describe("and a module name is `less!css!path/to/file.css`", function() {
        var moduleMeta;
        beforeEach(function() {
          moduleMeta = resolver.resolve("less!css!path/to/file.css");
        });

        it("then module name is `path/to/file.css`", function() {
          expect(moduleMeta.name).to.equal("path/to/file.css");
        });

        it("then first plugin is an array with two items", function() {
          expect(moduleMeta.plugins.length).to.equal(2);
        });

        it("then first plugin is `less`", function() {
          expect(moduleMeta.plugins[0]).to.equal("less");
        });

        it("then second plugin is `css`", function() {
          expect(moduleMeta.plugins[1]).to.equal("css");
        });
      });
    });

    describe("When Resolver is configured with `baseUrl`", function() {
      it("needs tests");
    });

  });
});
<|endoftext|>


<commit_before>// ==UserScript==
// @name          Steezy Pibb
// @namespace     http://www.geocities.com/ian3n
// @description   Makes Pibb+Fluid one hell of a steez
// @author        Ian Collins
// @homepage      http://www.geocities.com/ian3n
// @include       *pibb.com*
// ==/UserScript==

var ChatRoom = function(client) {

	// private
	var self = {
		client							: client,

		period 							: 1000,
		my_bg_color 				: '#eee',
		important_bg_color 	: '#FFC670',

		aliases_input_cookie : new Cookie('aliases_input_value', null, 1000),

		// tabz : self.client.doc().getElementsByClassName('ChannelTabBar')[0].childNodes[0].getElementsByTagName('li'),
		// tab : function(num) {
		// 	return self.tabz[num]
		// },

		new_messages : [],
		check_for_new_messages : function(){
			if (self.client.message_window()){
				var elems = self.get_new_message_elems()

				if (elems.length < self.new_messages.length)
					self.new_messages = []

				for (var i = self.new_messages.length; i < elems.length; i++)
					if (elems[i]) self.handle_new_message(elems[i])
			}
			window.setTimeout(self.check_for_new_messages, self.period)
		},
		get_new_message_elems : function(){
			var elems = self.client.message_window().getElementsByClassName(self.client.new_class)
			var lame = []

			for (var i=0; i < elems.length; i++)
				if (elems[i] && elems[i].className && elems[i].className.match(self.client.new_class)) lame.push(elems[i])

			return lame
		},
		handle_new_message: function(elem) {
			var message = new Message(elem)

			// if message was written by current user
			if (self.get_aliases().some(function(a){ return message.author.toLowerCase() == a.toLowerCase() })){
				self.mark_all_read()
				message.mark_read(self.client.new_class)
				message.by_current_user = true
				message.elem.style['background-color'] = self.my_bg_color
				return
			}

			// if message has one of the words from the alias input in it
			if (self.get_aliases().some(function(a){ return (a.length > 0) && (message.body.match(new RegExp('\\b(' + a + ')\\b','i'))) })) {
				self.new_message_growl_alert(message)
				message.elem.style['background-color'] = self.important_bg_color
			}

			self.new_messages.push(message)
			self.set_dock_alert(self.new_messages.length)
		},

		new_message_growl_alert : function(message){
			window.fluid.showGrowlNotification({
		    title				: message.author + " said",
		    description	: message.body,
		    priority		: 1,
		    sticky			: true,
				icon				: message.icon
			})
		},
		set_dock_alert : function(to){
			window.fluid.dockBadge = to
		},

		setup_message_window_events: function(){
			if (self.message_window()) self.message_window().addEventListener('click', self.message_window_clicked)
			window.setTimeout(self.setup_message_window_events, self.period)
		},
		message_window_clicked : function(){
			self.client.message_input().focus()
			self.mark_all_read()
		},
		mark_all_read : function() {
			self.new_messages.forEach(function(nm){ nm.mark_read(self.client.new_class) })
			self.new_messages = []
			self.set_dock_alert('')
		},

		insert_aliases_input: function(){
			if (!self.client.doc().getElementById('steezy-input')){
				self.aliases_input = document.createElement("input")
				self.aliases_input.id = "steezy-input"
				self.aliases_input.style.float = "left"

				self.aliases_input.value = self.aliases_input_cookie.get_value()
				self.aliases_input.addEventListener('keyup', (function(cookie){ cookie.set_value(this.value) }).bind(self.aliases_input, self.aliases_input_cookie))

				self.client.footer().appendChild(self.aliases_input)
			}

			window.setTimeout(self.insert_aliases_input, self.period)
		},
		get_aliases: function(){
			if (self.aliases_input)
				return self.aliases_input.value.split(',')
		}
	};

	// public
	var that = {}

	// initialize
	self.check_for_new_messages()
	self.setup_message_window_events()
	self.insert_aliases_input()

	return that
};

///////////////////////////////////////////////////////////////////////////////
// Models

var Message = function(elem){
	this.elem				= elem
	this.body 			= this.elem.childNodes[0].innerHTML
	this.author 		= this.elem.parentNode.parentNode.getElementsByClassName('Metadata')[0].getElementsByTagName('h3')[0].getElementsByClassName('Name')[0].innerHTML
	this.icon				= this.elem.parentNode.parentNode.getElementsByClassName('UserThumb')[0]
	this.by_current_user = false
	this.mark_read 	= function(class_name) {
											this.elem.className = this.elem.className.replace(class_name,'')
											// elem.remove_class(class_name)
										}
	return this
}

///////////////////////////////////////////////////////////////////////////////
// Utility Classes

var Cookie = function(key, value, max_days) {
	this.key = key

	if (max_days) {
		var tmp_date = new Date();
		tmp_date.setTime(tmp_date.getTime() + (max_days * 24 * 60 * 60 * 1000));
		this.expiry = '; expires=' + tmp_date.toGMTString()
	}

	this.set_value = function(val) {
		document.cookie = this.key + '=' + val + (this.expiry || '')
		return this
	}
	this.get_value = function() {
		var the_match = document.cookie.match(this.key + "=([^;]+)")
		if (the_match && the_match.length > 1) return the_match[1]
		else return null
	}
	this.clear = function(){
		return this.set_value('')
	}

	if (value) this.set_value(value)

	return this
}

///////////////////////////////////////////////////////////////////////////////
// Native Extensions

Function.prototype.bind = function(bind, arg) {
	var fun = this
	return function(){ return fun.call(bind, arg) }
}

///////////////////////////////////////////////////////////////////////////////
// Chat client wrapper classes

var Pibb = function(){
	var self = {
		doc  						: function() { return window.frames[0].document },
		message_window 	: function() { return self.doc().getElementsByClassName('EntriesView-Entries')[0] },
		message_input		: function() { return self.doc().getElementsByClassName('gwt-TextBox EntriesView-textbox')[0] },
		footer					: function() { return self.doc().getElementsByClassName('Footer')[0] },
		new_class				: 'NewEntry'
	}

	return self
}

///////////////////////////////////////////////////////////////////////////////
// Initialization

// only create pibb instance for second frame(set) (they all run this script)
if (window.loaded_once){
	var the_pibb = new ChatRoom(new Pibb())
	window.loaded_once = false
}else
	window.loaded_once = true<commit_msg>found first bug<commit_after>// ==UserScript==
// @name          Steezy Pibb
// @namespace     http://www.geocities.com/ian3n
// @description   Makes Pibb+Fluid one hell of a steez
// @author        Ian Collins
// @homepage      http://www.geocities.com/ian3n
// @include       *pibb.com*
// ==/UserScript==

var ChatRoom = function(client) {

	// private
	var self = {
		client							: client,

		period 							: 1000,
		my_bg_color 				: '#eee',
		important_bg_color 	: '#FFC670',

		aliases_input_cookie : new Cookie('aliases_input_value', null, 1000),

		// tabz : self.client.doc().getElementsByClassName('ChannelTabBar')[0].childNodes[0].getElementsByTagName('li'),
		// tab : function(num) {
		// 	return self.tabz[num]
		// },

		new_messages : [],
		check_for_new_messages : function(){
			if (self.client.message_window()){
				var elems = self.get_new_message_elems()

				if (elems.length < self.new_messages.length)
					self.new_messages = []

				for (var i = self.new_messages.length; i < elems.length; i++)
					if (elems[i]) self.handle_new_message(elems[i])
			}
			window.setTimeout(self.check_for_new_messages, self.period)
		},
		get_new_message_elems : function(){
			var elems = self.client.message_window().getElementsByClassName(self.client.new_class)
			var lame = []

			for (var i=0; i < elems.length; i++)
				if (elems[i] && elems[i].className && elems[i].className.match(self.client.new_class)) lame.push(elems[i])

			return lame
		},
		handle_new_message: function(elem) {
			var message = new Message(elem)

			// if message was written by current user
			if (self.get_aliases().some(function(a){ return message.author.toLowerCase() == a.toLowerCase() })){
				self.mark_all_read()
				message.mark_read(self.client.new_class)
				message.by_current_user = true
				message.elem.style['background-color'] = self.my_bg_color
				return
			}

			// if message has one of the words from the alias input in it
			if (self.get_aliases().some(function(a){ return (a.length > 0) && (message.body.match(new RegExp('\\b(' + a + ')\\b','i'))) })) {
				self.new_message_growl_alert(message)
				message.elem.style['background-color'] = self.important_bg_color
			}

			self.new_messages.push(message)
			self.set_dock_alert(self.new_messages.length)
		},

		new_message_growl_alert : function(message){
			window.fluid.showGrowlNotification({
		    title				: message.author + " said",
		    description	: message.body,
		    priority		: 1,
		    sticky			: true,
				icon				: message.icon
			})
		},
		set_dock_alert : function(to){
			window.fluid.dockBadge = to
		},

		setup_message_window_events: function(){
			if (self.client.message_window()) self.client.message_window().addEventListener('click', self.client.message_window_clicked)
			window.setTimeout(self.setup_message_window_events, self.period)
		},
		message_window_clicked : function(){
			self.client.message_input().focus()
			self.mark_all_read()
		},
		mark_all_read : function() {
			self.new_messages.forEach(function(nm){ nm.mark_read(self.client.new_class) })
			self.new_messages = []
			self.set_dock_alert('')
		},

		insert_aliases_input: function(){
			if (!self.client.doc().getElementById('steezy-input')){
				self.aliases_input = document.createElement("input")
				self.aliases_input.id = "steezy-input"
				self.aliases_input.style.float = "left"

				self.aliases_input.value = self.aliases_input_cookie.get_value()
				self.aliases_input.addEventListener('keyup', (function(cookie){ cookie.set_value(this.value) }).bind(self.aliases_input, self.aliases_input_cookie))

				self.client.footer().appendChild(self.aliases_input)
			}

			window.setTimeout(self.insert_aliases_input, self.period)
		},
		get_aliases: function(){
			if (self.aliases_input)
				return self.aliases_input.value.split(',')
		}
	};

	// public
	var that = {}

	// initialize
	self.check_for_new_messages()
	self.setup_message_window_events()
	self.insert_aliases_input()

	return that
};

///////////////////////////////////////////////////////////////////////////////
// Models

var Message = function(elem){
	this.elem				= elem
	this.body 			= this.elem.childNodes[0].innerHTML
	this.author 		= this.elem.parentNode.parentNode.getElementsByClassName('Metadata')[0].getElementsByTagName('h3')[0].getElementsByClassName('Name')[0].innerHTML
	this.icon				= this.elem.parentNode.parentNode.getElementsByClassName('UserThumb')[0]
	this.by_current_user = false
	this.mark_read 	= function(class_name) {
											this.elem.className = this.elem.className.replace(class_name,'')
											// elem.remove_class(class_name)
										}
	return this
}

///////////////////////////////////////////////////////////////////////////////
// Utility Classes

var Cookie = function(key, value, max_days) {
	this.key = key

	if (max_days) {
		var tmp_date = new Date();
		tmp_date.setTime(tmp_date.getTime() + (max_days * 24 * 60 * 60 * 1000));
		this.expiry = '; expires=' + tmp_date.toGMTString()
	}

	this.set_value = function(val) {
		document.cookie = this.key + '=' + val + (this.expiry || '')
		return this
	}
	this.get_value = function() {
		var the_match = document.cookie.match(this.key + "=([^;]+)")
		if (the_match && the_match.length > 1) return the_match[1]
		else return null
	}
	this.clear = function(){
		return this.set_value('')
	}

	if (value) this.set_value(value)

	return this
}

///////////////////////////////////////////////////////////////////////////////
// Native Extensions

Function.prototype.bind = function(bind, arg) {
	var fun = this
	return function(){ return fun.call(bind, arg) }
}

///////////////////////////////////////////////////////////////////////////////
// Chat client wrapper classes

var Pibb = function(){
	var self = {
		doc  						: function() { return window.frames[0].document },
		message_window 	: function() { return self.doc().getElementsByClassName('EntriesView-Entries')[0] },
		message_input		: function() { return self.doc().getElementsByClassName('gwt-TextBox EntriesView-textbox')[0] },
		footer					: function() { return self.doc().getElementsByClassName('Footer')[0] },
		new_class				: 'NewEntry'
	}

	return self
}

///////////////////////////////////////////////////////////////////////////////
// Initialization

// only create pibb instance for second frame(set) (they all run this script)
if (window.loaded_once){
	var the_pibb = new ChatRoom(new Pibb())
	window.loaded_once = false
}else
	window.loaded_once = true<|endoftext|>


<commit_before>$(document).on('ready page:load', function (event) {
  $('#calendar').fullCalendar({
    header: {
      left: 'prev,next today',
      center: 'title',
      right: 'month,agendaWeek,agendaDay'
    },
    events: '/events/',
    timezone: 'local',
    aspectRatio: 2.5
  });

  $(".quick-datetime-select").quickDatetimeSelector();
});
<commit_msg>add locale Korean<commit_after>$(document).on('ready page:load', function (event) {
  $('#calendar').fullCalendar({
    header: {
      left: 'prev,next today',
      center: 'title',
      right: 'month,agendaWeek,agendaDay'
    },
    events: '/events/',
    timezone: 'local',
    aspectRatio: 2.5
  });

  $(".quick-datetime-select").quickDatetimeSelector({
    locale: {
      Today: '오늘',
      Tomorrow: '내일',
      ThisWeek: '이번 주',
      NextWeek: '다음 주',
      day: {
        Sunday: '일요일',
        Monday: '월요일',
        Tuesday: '화요일',
        Wednesday: '수요일',
        Thursday: '목요일',
        Friday: '금요일',
        Saturday: '토요일'
      }
    }
  });
});
<|endoftext|>


<commit_before>(function(){

  'use strict';

  angular
    .module('app')
    .config(function($stateProvider, $urlRouterProvider){
      $stateProvider
        .state('login', {
          url: '/',
          templateUrl: 'views/login.html',
          controller: 'loginController as loginCtrl',
          onEnter: function($state, Auth){
            Auth.currentUser().then(function(data){
              $state.go('list', {id: data.list.id})
            })
          }
        })

      $stateProvider
        .state('userPurchases', {
          url: '/users/:id/purchases',
          templateUrl: 'views/purchases.html',
          controller: 'purchaseController as purchaseCtrl',
          onEnter: function($state, Auth){
            if (!Auth._currentUser){
              $state.go('login')
            }
          }
        })
        .state('userEvents', {
          url: '/users/:id/events',
          templateUrl: 'views/events.html',
          controller: 'eventController as eventCtrl',
          onEnter: function($state, Auth){
            if (!Auth._currentUser){
              $state.go('login')
            }
          }
        })
        .state('userProfile', {
          url: '/users/:id',
          templateUrl: 'views/profile.html',
          controller: 'profileController as profileCtrl',
          onEnter: function($state, Auth){
            if (!Auth._currentUser){
              $state.go('login')
            }
          }
        })
        .state('userProfileEdit', {
          url: '/users/:id/edit',
          templateUrl: 'views/editProfile.html',
          controller: 'editProfileController as editProfCtrl',
          onEnter: function($state, Auth){
            if (!Auth._currentUser){
              $state.go('login')
            }
          }
        })

      $stateProvider
        .state('userFriends', {
          url: '/users/:id/friends',
          templateUrl: 'views/friends.html',
          controller: 'friendshipController as friendshipCtrl',
          onEnter: function($state, Auth){
            if (!Auth._currentUser){
              $state.go('login');
            }
          }
        })

      $stateProvider
        .state('list', {
          url: '/list/:id',
          templateUrl: 'views/list.html',
          controller: 'listController as listCtrl',
          onEnter: function($state, Auth){
            if (!Auth._currentUser){
              $state.go('login')
            }
          }
        })

        $stateProvider
          .state('listItemEdit', {
            url: '/list/:list_id/items/:item_id/edit',
            templateUrl: 'views/items/edit.html',
            controller: 'itemController as itemCtrl',
            onEnter: function($state, Auth){
              if (!Auth._currentUser){
                $state.go('login')
              }
            }
          })
          .state('listItemShow', {
            url: '/list/:list_id/items/:item_id',
            templateUrl: 'views/items/show.html',
            controller: 'itemController as itemCtrl',
            onEnter: function($state, Auth){
              if (!Auth._currentUser){
                $state.go('login')
              }
            }
          })

      $urlRouterProvider.otherwise('/')
    })

}())<commit_msg>changed around some injector formats<commit_after>(function(){

  'use strict';

  angular
    .module('app')
    .config([$stateProvider, $urlRouterProvider, function($stateProvider, $urlRouterProvider){
      $stateProvider
        .state('login', {
          url: '/',
          templateUrl: 'views/login.html',
          controller: 'loginController as loginCtrl',
          onEnter: ['$state', 'Auth', function($state, Auth){
            Auth.currentUser().then(function(data){
              $state.go('list', {id: data.list.id})
            })
          }]
        })

      $stateProvider
        .state('userPurchases', {
          url: '/users/:id/purchases',
          templateUrl: 'views/purchases.html',
          controller: 'purchaseController as purchaseCtrl',
          onEnter: ['$state', 'Auth', function($state, Auth){
            if (!Auth._currentUser){
              $state.go('login')
            }
          }]
        })
        .state('userEvents', {
          url: '/users/:id/events',
          templateUrl: 'views/events.html',
          controller: 'eventController as eventCtrl',
          onEnter: ['$state', 'Auth', function($state, Auth){
            if (!Auth._currentUser){
              $state.go('login')
            }
          }]
        })
        .state('userProfile', {
          url: '/users/:id',
          templateUrl: 'views/profile.html',
          controller: 'profileController as profileCtrl',
          onEnter: ['$state', 'Auth', function($state, Auth){
            if (!Auth._currentUser){
              $state.go('login')
            }
          }]
        })
        .state('userProfileEdit', {
          url: '/users/:id/edit',
          templateUrl: 'views/editProfile.html',
          controller: 'editProfileController as editProfCtrl',
          onEnter: ['$state', 'Auth', function($state, Auth){
            if (!Auth._currentUser){
              $state.go('login')
            }
          }]
        })

      $stateProvider
        .state('userFriends', {
          url: '/users/:id/friends',
          templateUrl: 'views/friends.html',
          controller: 'friendshipController as friendshipCtrl',
          onEnter: ['$state', 'Auth', function($state, Auth){
            if (!Auth._currentUser){
              $state.go('login');
            }
          }]
        })

      $stateProvider
        .state('list', {
          url: '/list/:id',
          templateUrl: 'views/list.html',
          controller: 'listController as listCtrl',
          onEnter: ['$state', 'Auth', function($state, Auth){
            if (!Auth._currentUser){
              $state.go('login')
            }
          }]
        })

        $stateProvider
          .state('listItemEdit', {
            url: '/list/:list_id/items/:item_id/edit',
            templateUrl: 'views/items/edit.html',
            controller: 'itemController as itemCtrl',
            onEnter: ['$state', 'Auth', function($state, Auth){
              if (!Auth._currentUser){
                $state.go('login')
              }
            }]
          })
          .state('listItemShow', {
            url: '/list/:list_id/items/:item_id',
            templateUrl: 'views/items/show.html',
            controller: 'itemController as itemCtrl',
            onEnter: ['$state', 'Auth', function($state, Auth){
              if (!Auth._currentUser){
                $state.go('login')
              }
            }]
          })

      $urlRouterProvider.otherwise('/')
    }])

}())<|endoftext|>