<commit_before>/*
Copyright [2009-2014] EMBL-European Bioinformatics Institute
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
     http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

/**
 * Manage Genoverse embedded browser.
 */

;(function(){

  /**
   * Internal object for storing the browser state.
   */
  params = {
    'chromosome': '',
    'start': '',
    'end': '',
    'species': '',
    '_species': '', // previous species
  };

  /**
   * Main function for launching Genoverse.
   */
  display_genomic_location = function() {

    show_genoverse_section_header();
    initialize_genoverse();
    navigate_to_feature();

    /**
     * Load Genoverse for the first time or switch to a different species.
     */
    function initialize_genoverse() {
      if (typeof window.browser === 'undefined' || this.params._species !== this.params.species) {
          // (re-)create Genoverse object
          window.browser = new Genoverse(get_genoverse_config_object());
      }
    }

    /**
     * Navigate to the region of interest.
     */
    function navigate_to_feature() {
      browser.moveTo(this.params.start, this.params.end, false);
      browser.zoomOut();
    }

    /**
     * Display Genoverse section header.
     */
    function show_genoverse_section_header() {
      $('.genoverse-wrap h2').show();
    }

  };

  /**
   * Configure Genoverse initialization object.
   */
  get_genoverse_config_object = function() {

    var genoverseConfig = {
      container     : '#genoverse',
      chromosomeSize: Math.pow(10, 20), // should be greater than any chromosome size
      // genome: 'grch37',
      chr           : this.params.chromosome,
      showUrlCoords : false, // do not show genomic coordinates in the url
      plugins       : [ 'controlPanel', 'karyotype', 'resizer', 'fileDrop' ],
      tracks        : [
        Genoverse.Track.Scalebar,
        Genoverse.Track.extend({
          name      : 'Sequence',
          model     : configure_genoverse_model('ensembl_sequence'),
          view      : Genoverse.Track.View.Sequence,
          resizable : 'auto',
          100000    : false,
        }),
        Genoverse.Track.extend({
          name      : 'Ensembl genes',
          info      : 'Ensembl API genes',
          resizable : 'auto',
          labels : true,
          model  : configure_genoverse_model('ensembl_gene'),
          view   : Genoverse.Track.View.Gene.Ensembl,
        }),
        Genoverse.Track.extend({
          name      : 'Ensembl transcripts',
          info      : 'Ensembl API transcripts',
          resizable : 'auto',
          labels : true,
          model  : configure_genoverse_model('ensembl_transcript'),
          view   : Genoverse.Track.View.Transcript.Ensembl,
        }),
        Genoverse.Track.extend({
          name      : 'RNAcentral',
          id        : 'RNAcentral',
          info      : 'Unique RNAcentral Sequences',
          resizable : 'auto',
          labels : true,
          model  : configure_genoverse_model('rnacentral'),
          view   : Genoverse.Track.View.Transcript.Ensembl,
        })
      ]
    };

    return genoverseConfig;

    /**
     * Each Genoverse model is configured with an organism-specific url.
     * In addition, a new RNAcentral models that's mimicking Ensembl API is defined.
     */
    function configure_genoverse_model(model_type) {

      var model;

      if (model_type === 'ensembl_gene') {
        // Ensembl Gene track
        new_url = '//beta.rest.ensembl.org/feature/region/__SPECIES__/__CHR__:__START__-__END__?feature=gene;content-type=application/json'.replace('__SPECIES__', this.params.species);
        model = Genoverse.Track.Model.Gene.Ensembl.extend({
          url: new_url,
        });
      } else if (model_type === 'ensembl_transcript') {
        // Ensembl Transcript track
        new_url = '//rest.ensembl.org/overlap/region/__SPECIES__/__CHR__:__START__-__END__?feature=transcript;feature=exon;feature=cds;content-type=application/json'.replace('__SPECIES__', this.params.species);
        model = Genoverse.Track.Model.Transcript.Ensembl.extend({
          url: new_url,
        });
      } else if (model_type === 'ensembl_sequence') {
        // Ensembl sequence view
        new_url = '//beta.rest.ensembl.org/sequence/region/__SPECIES__/__CHR__:__START__-__END__?content-type=text/plain'.replace('__SPECIES__', this.params.species);
        model = Genoverse.Track.Model.Sequence.Ensembl.extend({
          url: new_url,
        });
      } else if (model_type === 'rnacentral') {
        // custom RNAcentral track
        if (!window.location.origin) {
          window.location.origin = window.location.protocol + "//" + window.location.host + '/';
        }
        new_url = window.location.origin + '/api/v1/feature/region/__SPECIES__/__CHR__:__START__-__END__'.replace('__SPECIES__', this.params.species);
        model = Genoverse.Track.Model.Gene.Ensembl.extend({
          url: new_url,

          parseData: function (data) {
            for (var i = 0; i < data.length; i++) {
              var feature = data[i];

              if (feature.feature_type === 'transcript' && !this.featuresById[feature.ID]) {
                feature.id    = feature.ID;
                feature.label = feature.external_name;
                feature.exons = [];
                feature.cds   = [];

                this.insertFeature(feature);
              } else if (feature.feature_type === 'exon' && this.featuresById[feature.Parent]) {
                feature.id = feature.ID;

                if (!this.featuresById[feature.Parent].exons[feature.id]) {
                  this.featuresById[feature.Parent].exons.push(feature);
                  this.featuresById[feature.Parent].exons[feature.id] = feature;
                }
              }
            }
          }
        });
      }

      return model;
    }

  };

  /**
   * Maximize Genoverse container width.
   */
  set_genoverse_width = function() {
    var w = $('.container').width();
    $('.wrap').width(w);
    $('#genoverse').width(w);
  };

  /**
   * Attach all event handlers.
   */
  bind_events = function() {
    resize_genoverse_on_window_resize();
    genoverse_trigger();

    /**
     * Ensure Genoverse is resized when the browser window is resized.
     */
    function resize_genoverse_on_window_resize() {
      window.onresize = function() {
        set_genoverse_width();
      };
    }

    /**
     * Create an event for launching Genoverse.
     */
    function genoverse_trigger()  {
      $('body').on("click", '.genoverse-xref', function(e){
          e.preventDefault();
          set_params($(this));
          display_genomic_location();
      });

      /**
       * Store new parameters in the internal object.
       */
      function set_params($this) {

        var species = $this.data('species');
        if (species !== this.params.species) {
          this.params._species = this.params.species;
        }

        this.params = {
          'chromosome': $this.data('chromosome'),
          'start': $this.data('genomic-start'),
          'end': $this.data('genomic-end'),
          'species': species,
          'endpoint': $this.data('endpoint'),
        };
      }
    }

  };

  /**
   * Run module.
   */
  (function(){
    set_genoverse_width();
    bind_events();
  })();

})();
<commit_msg>Better detection of switching between species for Genoverse<commit_after>/*
Copyright [2009-2014] EMBL-European Bioinformatics Institute
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
     http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

/**
 * Manage Genoverse embedded browser.
 */

;(function(){

  /**
   * Internal object for storing the browser state.
   */
  params = {
    'chromosome': '',
    'start': '',
    'end': '',
    'species': '',
    '_species': '', // previous species
  };

  /**
   * Main function for launching Genoverse.
   */
  display_genomic_location = function() {

    show_genoverse_section_header();
    initialize_genoverse();
    navigate_to_feature();

    /**
     * Load Genoverse for the first time or switch to a different species.
     */
    function initialize_genoverse() {
      if (typeof window.browser === 'undefined' || switch_species()) {
          // (re-)create Genoverse object
          window.browser = new Genoverse(get_genoverse_config_object());
      }

      /**
       * Return true if the current and the previous browser states refer to
       * different species.
       */
      function switch_species() {
        return this.params._species !== this.params.species && this.params._species !== '';
      }
    }

    /**
     * Navigate to the region of interest.
     */
    function navigate_to_feature() {
      browser.moveTo(this.params.start, this.params.end, false);
      browser.zoomOut();
    }

    /**
     * Display Genoverse section header.
     */
    function show_genoverse_section_header() {
      $('.genoverse-wrap h2').show();
    }

  };

  /**
   * Configure Genoverse initialization object.
   */
  get_genoverse_config_object = function() {

    var genoverseConfig = {
      container     : '#genoverse',
      chromosomeSize: Math.pow(10, 20), // should be greater than any chromosome size
      // genome: 'grch37',
      chr           : this.params.chromosome,
      showUrlCoords : false, // do not show genomic coordinates in the url
      plugins       : [ 'controlPanel', 'karyotype', 'resizer', 'fileDrop' ],
      tracks        : [
        Genoverse.Track.Scalebar,
        Genoverse.Track.extend({
          name      : 'Sequence',
          model     : configure_genoverse_model('ensembl_sequence'),
          view      : Genoverse.Track.View.Sequence,
          resizable : 'auto',
          100000    : false,
        }),
        Genoverse.Track.extend({
          name      : 'Ensembl genes',
          info      : 'Ensembl API genes',
          resizable : 'auto',
          labels : true,
          model  : configure_genoverse_model('ensembl_gene'),
          view   : Genoverse.Track.View.Gene.Ensembl,
        }),
        Genoverse.Track.extend({
          name      : 'Ensembl transcripts',
          info      : 'Ensembl API transcripts',
          resizable : 'auto',
          labels : true,
          model  : configure_genoverse_model('ensembl_transcript'),
          view   : Genoverse.Track.View.Transcript.Ensembl,
        }),
        Genoverse.Track.extend({
          name      : 'RNAcentral',
          id        : 'RNAcentral',
          info      : 'Unique RNAcentral Sequences',
          resizable : 'auto',
          labels : true,
          model  : configure_genoverse_model('rnacentral'),
          view   : Genoverse.Track.View.Transcript.Ensembl,
        })
      ]
    };

    return genoverseConfig;

    /**
     * Each Genoverse model is configured with an organism-specific url.
     * In addition, a new RNAcentral models that's mimicking Ensembl API is defined.
     */
    function configure_genoverse_model(model_type) {

      var model;

      if (model_type === 'ensembl_gene') {
        // Ensembl Gene track
        new_url = '//beta.rest.ensembl.org/feature/region/__SPECIES__/__CHR__:__START__-__END__?feature=gene;content-type=application/json'.replace('__SPECIES__', this.params.species);
        model = Genoverse.Track.Model.Gene.Ensembl.extend({
          url: new_url,
        });
      } else if (model_type === 'ensembl_transcript') {
        // Ensembl Transcript track
        new_url = '//rest.ensembl.org/overlap/region/__SPECIES__/__CHR__:__START__-__END__?feature=transcript;feature=exon;feature=cds;content-type=application/json'.replace('__SPECIES__', this.params.species);
        model = Genoverse.Track.Model.Transcript.Ensembl.extend({
          url: new_url,
        });
      } else if (model_type === 'ensembl_sequence') {
        // Ensembl sequence view
        new_url = '//beta.rest.ensembl.org/sequence/region/__SPECIES__/__CHR__:__START__-__END__?content-type=text/plain'.replace('__SPECIES__', this.params.species);
        model = Genoverse.Track.Model.Sequence.Ensembl.extend({
          url: new_url,
        });
      } else if (model_type === 'rnacentral') {
        // custom RNAcentral track
        if (!window.location.origin) {
          window.location.origin = window.location.protocol + "//" + window.location.host + '/';
        }
        new_url = window.location.origin + '/api/v1/feature/region/__SPECIES__/__CHR__:__START__-__END__'.replace('__SPECIES__', this.params.species);
        model = Genoverse.Track.Model.Gene.Ensembl.extend({
          url: new_url,

          parseData: function (data) {
            for (var i = 0; i < data.length; i++) {
              var feature = data[i];

              if (feature.feature_type === 'transcript' && !this.featuresById[feature.ID]) {
                feature.id    = feature.ID;
                feature.label = feature.external_name;
                feature.exons = [];
                feature.cds   = [];

                this.insertFeature(feature);
              } else if (feature.feature_type === 'exon' && this.featuresById[feature.Parent]) {
                feature.id = feature.ID;

                if (!this.featuresById[feature.Parent].exons[feature.id]) {
                  this.featuresById[feature.Parent].exons.push(feature);
                  this.featuresById[feature.Parent].exons[feature.id] = feature;
                }
              }
            }
          }
        });
      }

      return model;
    }

  };

  /**
   * Maximize Genoverse container width.
   */
  set_genoverse_width = function() {
    var w = $('.container').width();
    $('.wrap').width(w);
    $('#genoverse').width(w);
  };

  /**
   * Attach all event handlers.
   */
  bind_events = function() {
    resize_genoverse_on_window_resize();
    genoverse_trigger();

    /**
     * Ensure Genoverse is resized when the browser window is resized.
     */
    function resize_genoverse_on_window_resize() {
      window.onresize = function() {
        set_genoverse_width();
      };
    }

    /**
     * Create an event for launching Genoverse.
     */
    function genoverse_trigger()  {
      $('body').on("click", '.genoverse-xref', function(e){
          e.preventDefault();
          set_params($(this));
          display_genomic_location();
      });

      /**
       * Store new parameters in the internal object.
       */
      function set_params($this) {

        var species = $this.data('species');
        if (species !== this.params.species) {
          _species = this.params.species;
        }

        this.params = {
          'chromosome': $this.data('chromosome'),
          'start': $this.data('genomic-start'),
          'end': $this.data('genomic-end'),
          'species': species,
          '_species': _species,
          'endpoint': $this.data('endpoint'),
        };
      }
    }

  };

  /**
   * Run module.
   */
  (function(){
    set_genoverse_width();
    bind_events();
  })();

})();
<|endoftext|>


<commit_before>(function () {
    'use strict';

    function serializeMoney(amount) {
        return {
            amount: amount.toTokens(),
            currency: amount.currency
        };
    }

    function deserializeCurrency(json) {
        // It's not a perfect solution.
        // Currencies created here won't be equivalent (===) to predefined currencies
        return new Currency(json.currency);
    }

    function deserializeMoney(json) {
        return Money.fromTokens(json.amount, deserializeCurrency(json.currency));
    }

    function serializeOrder(order) {
        return {
            id: order.id,
            status: order.status,
            type: order.type,
            quantity: serializeMoney(order.quantity),
            price: serializeMoney(order.price),
            total: serializeMoney(order.total)
        };
    }

    function deserializeOrder(json) {
        return {
            id: json.id,
            status: json.status,
            type: json.type,
            quantity: deserializeMoney(json.quantity),
            price: deserializeMoney(json.price),
            total: deserializeMoney(json.total)
        };
    }

    function buildPairKey(pair) {
        return pair.amountAssetId + '_' + pair.priceAssetId;
    }

    function DexOrderService(storageService, matcherRequestService, matcherApiService) {
        function loadState() {
            return storageService.loadState().then(function (state) {
                state = state || {};
                if (!state.orders) {
                    state.orders = {};
                }
                return state;
            });
        }

        this.addOrder = function (pair, order, sender) {
            return loadState().then(function (state) {
                return Promise.resolve()
                    .then(matcherApiService.loadMatcherKey)
                    .then(function (matcherKey) {
                        order.matcherKey = matcherKey;
                        return matcherRequestService.buildCreateOrderRequest(order, sender);
                    })
                    .then(function (signedOrder) {
                        return signedOrder;
                    })
                    .then(matcherApiService.createOrder)
                    .then(function (response) {
                        console.log(response); // TODO : make a notification.
                        var array = state.orders[buildPairKey(pair)] || [];
                        array.push(serializeOrder(order));
                        state.orders[buildPairKey(pair)] = array;

                        return state;
                    });
            }).then(storageService.saveState);
        };

        this.removeOrder = function (pair, order) {
            return loadState().then(function (state) {
                var array = state.orders[buildPairKey(pair)] || [];
                var index = _.findIndex(array, {id: order.id});
                if (index >= 0) {
                    array.splice(index, 1);
                }
                state.orders[buildPairKey(pair)] = array;

                return state;
            }).then(storageService.saveState);
        };

        this.getOrders = function (pair) {
            return loadState().then(function (state) {
                return state.orders[buildPairKey(pair)] || [];
            }).then(function (rawOrders) {
                return _.map(rawOrders, deserializeOrder);
            });
        };
    }

    DexOrderService.$inject = ['storageService', 'matcherRequestService', 'matcherApiService'];

    angular
        .module('app.dex')
        .service('dexOrderService', DexOrderService);
})();
<commit_msg>Fixed deserialization failure in dex order.service<commit_after>(function () {
    'use strict';

    function serializeMoney(amount) {
        return {
            amount: amount.toTokens(),
            currency: amount.currency
        };
    }

    function deserializeCurrency(json) {
        // It's not a perfect solution.
        // Currencies created here won't be equivalent (===) to predefined currencies
        return new Currency(json);
    }

    function deserializeMoney(json) {
        return Money.fromTokens(json.amount, deserializeCurrency(json.currency));
    }

    function serializeOrder(order) {
        return {
            id: order.id,
            status: order.status,
            type: order.type,
            quantity: serializeMoney(order.quantity),
            price: serializeMoney(order.price),
            total: serializeMoney(order.total)
        };
    }

    function deserializeOrder(json) {
        return {
            id: json.id,
            status: json.status,
            type: json.type,
            quantity: deserializeMoney(json.quantity),
            price: deserializeMoney(json.price),
            total: deserializeMoney(json.total)
        };
    }

    function buildPairKey(pair) {
        return pair.amountAssetId + '_' + pair.priceAssetId;
    }

    function DexOrderService(storageService, matcherRequestService, matcherApiService) {
        function loadState() {
            return storageService.loadState().then(function (state) {
                state = state || {};
                if (!state.orders) {
                    state.orders = {};
                }
                return state;
            });
        }

        this.addOrder = function (pair, order, sender) {
            return loadState().then(function (state) {
                return Promise.resolve()
                    .then(matcherApiService.loadMatcherKey)
                    .then(function (matcherKey) {
                        order.matcherKey = matcherKey;
                        return matcherRequestService.buildCreateOrderRequest(order, sender);
                    })
                    .then(function (signedOrder) {
                        return signedOrder;
                    })
                    .then(matcherApiService.createOrder)
                    .then(function (response) {
                        console.log(response); // TODO : make a notification.
                        var array = state.orders[buildPairKey(pair)] || [];
                        array.push(serializeOrder(order));
                        state.orders[buildPairKey(pair)] = array;

                        return state;
                    });
            }).then(storageService.saveState);
        };

        this.removeOrder = function (pair, order) {
            return loadState().then(function (state) {
                var array = state.orders[buildPairKey(pair)] || [];
                var index = _.findIndex(array, {id: order.id});
                if (index >= 0) {
                    array.splice(index, 1);
                }
                state.orders[buildPairKey(pair)] = array;

                return state;
            }).then(storageService.saveState);
        };

        this.getOrders = function (pair) {
            return loadState().then(function (state) {
                return state.orders[buildPairKey(pair)] || [];
            }).then(function (rawOrders) {
                return _.map(rawOrders, deserializeOrder);
            });
        };
    }

    DexOrderService.$inject = ['storageService', 'matcherRequestService', 'matcherApiService'];

    angular
        .module('app.dex')
        .service('dexOrderService', DexOrderService);
})();
<|endoftext|>


<commit_before>
console.log('starting function')
exports.handle = function(e, ctx) {
  console.log('processing event: %j', e)
  ctx.succeed({ hello: 'world' })
}<commit_msg>refactor boilerplate to use callback param<commit_after>console.log('starting function')
exports.handle = function(e, ctx, cb) {
  console.log('processing event: %j', e)
  cb(null, { hello: 'world' })
}
<|endoftext|>


<commit_before>'use strict';

function classDirective(name, selector) {
  name = 'ngClass' + name;
  return function() {
    return {
      restrict: 'AC',
      link: function(scope, element, attr) {
        var oldVal;

        scope.$watch(attr[name], ngClassWatchAction, true);

        attr.$observe('class', function(value) {
          ngClassWatchAction(scope.$eval(attr[name]));
        });

        if (name !== 'ngClass') {
          scope.$watch('$index', function($index, old$index) {
            // jshint bitwise: false
            var mod = $index & 1;
            if (mod !== old$index & 1) {
              if (mod === selector) {
                addClass(scope.$eval(attr[name]));
              } else {
                removeClass(scope.$eval(attr[name]));
              }
            }
          });
        }

        function ngClassWatchAction(newVal) {
          if (selector === true || scope.$index % 2 === selector) {
            if (oldVal && !equals(newVal,oldVal)) {
              removeClass(oldVal);
            }
            addClass(newVal);
          }
          oldVal = copy(newVal);
        }

        function removeClass(classVal) {
          attr.$removeClass(flattenClasses(classVal));
        }

        function addClass(classVal) {
          attr.$addClass(flattenClasses(classVal));
        }

        function flattenClasses(classVal) {
          if(isArray(classVal)) {
            return classVal.join(' ');
          } else if (isObject(classVal)) {
            var classes = [], i = 0;
            forEach(classVal, function(v, k) {
              if (v) {
                classes.push(k);
              }
            });
            return classes.join(' ');
          }

          return classVal;
        }
      }
    };
  };
}

/**
 * @ngdoc directive
 * @name ng.directive:ngClass
 * @restrict AC
 *
 * @description
 * The `ngClass` directive allows you to dynamically set CSS classes on an HTML element by databinding
 * an expression that represents all classes to be added.
 *
 * The directive won't add duplicate classes if a particular class was already set.
 *
 * When the expression changes, the previously added classes are removed and only then the
 * new classes are added.
 *
 * @animations
 * add - happens just before the class is applied to the element
 * remove - happens just before the class is removed from the element
 *
 * @element ANY
 * @param {expression} ngClass {@link guide/expression Expression} to eval. The result
 *   of the evaluation can be a string representing space delimited class
 *   names, an array, or a map of class names to boolean values. In the case of a map, the
 *   names of the properties whose values are truthy will be added as css classes to the
 *   element.
 *
 * @example Example that demostrates basic bindings via ngClass directive.
   <example>
     <file name="index.html">

Map Syntax Example

       <input type="checkbox" ng-model="bold"> bold
       <input type="checkbox" ng-model="strike"> strike
       <input type="checkbox" ng-model="red"> red

Using String Syntax

       <input type="text" ng-model="style" placeholder="Type: bold strike red">

Using Array Syntax

       <input ng-model="style1" placeholder="Type: bold">

       <input ng-model="style2" placeholder="Type: strike">

       <input ng-model="style3" placeholder="Type: red">

     </file>
     <file name="style.css">
       .strike {
         text-decoration: line-through;
       }
       .bold {
           font-weight: bold;
       }
       .red {
           color: red;
       }
     </file>
     <file name="scenario.js">
       it('should let you toggle the class', function() {

         expect(element('.doc-example-live p:first').prop('className')).not().toMatch(/bold/);
         expect(element('.doc-example-live p:first').prop('className')).not().toMatch(/red/);

         input('bold').check();
         expect(element('.doc-example-live p:first').prop('className')).toMatch(/bold/);

         input('red').check();
         expect(element('.doc-example-live p:first').prop('className')).toMatch(/red/);
       });

       it('should let you toggle string example', function() {
         expect(element('.doc-example-live p:nth-of-type(2)').prop('className')).toBe('');
         input('style').enter('red');
         expect(element('.doc-example-live p:nth-of-type(2)').prop('className')).toBe('red');
       });

       it('array example should have 3 classes', function() {
         expect(element('.doc-example-live p:last').prop('className')).toBe('');
         input('style1').enter('bold');
         input('style2').enter('strike');
         input('style3').enter('red');
         expect(element('.doc-example-live p:last').prop('className')).toBe('bold strike red');
       });
     </file>
   </example>

   ## Animations

   The example below demonstrates how to perform animations using ngClass.

   <example animations="true">
     <file name="index.html">
      <input type="button" value="set" ng-click="myVar='my-class'">
      <input type="button" value="clear" ng-click="myVar=''">

      Sample Text
     </file>
     <file name="style.css">
       .my-class-add, .my-class-remove {
         -webkit-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s;
         -moz-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s;
         -o-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s;
         transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s;
       }

       .my-class,
       .my-class-add.my-class-add-active {
         color: red;
         font-size:3em;
       }

       .my-class-remove.my-class-remove-active {
         font-size:1.0em;
         color:black;
       }
     </file>
     <file name="scenario.js">
       it('should check ng-class', function() {
         expect(element('.doc-example-live span').prop('className')).not().
           toMatch(/my-class/);

         using('.doc-example-live').element(':button:first').click();

         expect(element('.doc-example-live span').prop('className')).
           toMatch(/my-class/);

         using('.doc-example-live').element(':button:last').click();

         expect(element('.doc-example-live span').prop('className')).not().
           toMatch(/my-class/);
       });
     </file>
   </example>

   ## ngClass and pre-existing CSS3 Transitions/Animations
   The ngClass directive still supports CSS3 Transitions/Animations even if they do not follow the ngAnimate CSS naming structure.
   Therefore, if any CSS3 Transition/Animation styles (outside of ngAnimate) are set on the element, then, if a ngClass animation
   is triggered, the ngClass animation will be skipped so that ngAnimate can allow for the pre-existing transition or animation to
   take over. This restriction allows for ngClass to still work with standard CSS3 Transitions/Animations that are defined
   outside of ngAnimate.
 */
var ngClassDirective = classDirective('', true);

/**
 * @ngdoc directive
 * @name ng.directive:ngClassOdd
 * @restrict AC
 *
 * @description
 * The `ngClassOdd` and `ngClassEven` directives work exactly as
 * {@link ng.directive:ngClass ngClass}, except they work in
 * conjunction with `ngRepeat` and take effect only on odd (even) rows.
 *
 * This directive can be applied only within the scope of an
 * {@link ng.directive:ngRepeat ngRepeat}.
 *
 * @element ANY
 * @param {expression} ngClassOdd {@link guide/expression Expression} to eval. The result
 *   of the evaluation can be a string representing space delimited class names or an array.
 *
 * @example
   <example>
     <file name="index.html">

             {{name}}

     </file>
     <file name="style.css">
       .odd {
         color: red;
       }
       .even {
         color: blue;
       }
     </file>
     <file name="scenario.js">
       it('should check ng-class-odd and ng-class-even', function() {
         expect(element('.doc-example-live li:first span').prop('className')).
           toMatch(/odd/);
         expect(element('.doc-example-live li:last span').prop('className')).
           toMatch(/even/);
       });
     </file>
   </example>
 */
var ngClassOddDirective = classDirective('Odd', 0);

/**
 * @ngdoc directive
 * @name ng.directive:ngClassEven
 * @restrict AC
 *
 * @description
 * The `ngClassOdd` and `ngClassEven` directives work exactly as
 * {@link ng.directive:ngClass ngClass}, except they work in
 * conjunction with `ngRepeat` and take effect only on odd (even) rows.
 *
 * This directive can be applied only within the scope of an
 * {@link ng.directive:ngRepeat ngRepeat}.
 *
 * @element ANY
 * @param {expression} ngClassEven {@link guide/expression Expression} to eval. The
 *   result of the evaluation can be a string representing space delimited class names or an array.
 *
 * @example
   <example>
     <file name="index.html">

             {{name}}

     </file>
     <file name="style.css">
       .odd {
         color: red;
       }
       .even {
         color: blue;
       }
     </file>
     <file name="scenario.js">
       it('should check ng-class-odd and ng-class-even', function() {
         expect(element('.doc-example-live li:first span').prop('className')).
           toMatch(/odd/);
         expect(element('.doc-example-live li:last span').prop('className')).
           toMatch(/even/);
       });
     </file>
   </example>
 */
var ngClassEvenDirective = classDirective('Even', 1);
<commit_msg>docs(ngClass): fix typo<commit_after>'use strict';

function classDirective(name, selector) {
  name = 'ngClass' + name;
  return function() {
    return {
      restrict: 'AC',
      link: function(scope, element, attr) {
        var oldVal;

        scope.$watch(attr[name], ngClassWatchAction, true);

        attr.$observe('class', function(value) {
          ngClassWatchAction(scope.$eval(attr[name]));
        });

        if (name !== 'ngClass') {
          scope.$watch('$index', function($index, old$index) {
            // jshint bitwise: false
            var mod = $index & 1;
            if (mod !== old$index & 1) {
              if (mod === selector) {
                addClass(scope.$eval(attr[name]));
              } else {
                removeClass(scope.$eval(attr[name]));
              }
            }
          });
        }

        function ngClassWatchAction(newVal) {
          if (selector === true || scope.$index % 2 === selector) {
            if (oldVal && !equals(newVal,oldVal)) {
              removeClass(oldVal);
            }
            addClass(newVal);
          }
          oldVal = copy(newVal);
        }

        function removeClass(classVal) {
          attr.$removeClass(flattenClasses(classVal));
        }

        function addClass(classVal) {
          attr.$addClass(flattenClasses(classVal));
        }

        function flattenClasses(classVal) {
          if(isArray(classVal)) {
            return classVal.join(' ');
          } else if (isObject(classVal)) {
            var classes = [], i = 0;
            forEach(classVal, function(v, k) {
              if (v) {
                classes.push(k);
              }
            });
            return classes.join(' ');
          }

          return classVal;
        }
      }
    };
  };
}

/**
 * @ngdoc directive
 * @name ng.directive:ngClass
 * @restrict AC
 *
 * @description
 * The `ngClass` directive allows you to dynamically set CSS classes on an HTML element by databinding
 * an expression that represents all classes to be added.
 *
 * The directive won't add duplicate classes if a particular class was already set.
 *
 * When the expression changes, the previously added classes are removed and only then the
 * new classes are added.
 *
 * @animations
 * add - happens just before the class is applied to the element
 * remove - happens just before the class is removed from the element
 *
 * @element ANY
 * @param {expression} ngClass {@link guide/expression Expression} to eval. The result
 *   of the evaluation can be a string representing space delimited class
 *   names, an array, or a map of class names to boolean values. In the case of a map, the
 *   names of the properties whose values are truthy will be added as css classes to the
 *   element.
 *
 * @example Example that demonstrates basic bindings via ngClass directive.
   <example>
     <file name="index.html">

Map Syntax Example

       <input type="checkbox" ng-model="bold"> bold
       <input type="checkbox" ng-model="strike"> strike
       <input type="checkbox" ng-model="red"> red

Using String Syntax

       <input type="text" ng-model="style" placeholder="Type: bold strike red">

Using Array Syntax

       <input ng-model="style1" placeholder="Type: bold">

       <input ng-model="style2" placeholder="Type: strike">

       <input ng-model="style3" placeholder="Type: red">

     </file>
     <file name="style.css">
       .strike {
         text-decoration: line-through;
       }
       .bold {
           font-weight: bold;
       }
       .red {
           color: red;
       }
     </file>
     <file name="scenario.js">
       it('should let you toggle the class', function() {

         expect(element('.doc-example-live p:first').prop('className')).not().toMatch(/bold/);
         expect(element('.doc-example-live p:first').prop('className')).not().toMatch(/red/);

         input('bold').check();
         expect(element('.doc-example-live p:first').prop('className')).toMatch(/bold/);

         input('red').check();
         expect(element('.doc-example-live p:first').prop('className')).toMatch(/red/);
       });

       it('should let you toggle string example', function() {
         expect(element('.doc-example-live p:nth-of-type(2)').prop('className')).toBe('');
         input('style').enter('red');
         expect(element('.doc-example-live p:nth-of-type(2)').prop('className')).toBe('red');
       });

       it('array example should have 3 classes', function() {
         expect(element('.doc-example-live p:last').prop('className')).toBe('');
         input('style1').enter('bold');
         input('style2').enter('strike');
         input('style3').enter('red');
         expect(element('.doc-example-live p:last').prop('className')).toBe('bold strike red');
       });
     </file>
   </example>

   ## Animations

   The example below demonstrates how to perform animations using ngClass.

   <example animations="true">
     <file name="index.html">
      <input type="button" value="set" ng-click="myVar='my-class'">
      <input type="button" value="clear" ng-click="myVar=''">

      Sample Text
     </file>
     <file name="style.css">
       .my-class-add, .my-class-remove {
         -webkit-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s;
         -moz-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s;
         -o-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s;
         transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s;
       }

       .my-class,
       .my-class-add.my-class-add-active {
         color: red;
         font-size:3em;
       }

       .my-class-remove.my-class-remove-active {
         font-size:1.0em;
         color:black;
       }
     </file>
     <file name="scenario.js">
       it('should check ng-class', function() {
         expect(element('.doc-example-live span').prop('className')).not().
           toMatch(/my-class/);

         using('.doc-example-live').element(':button:first').click();

         expect(element('.doc-example-live span').prop('className')).
           toMatch(/my-class/);

         using('.doc-example-live').element(':button:last').click();

         expect(element('.doc-example-live span').prop('className')).not().
           toMatch(/my-class/);
       });
     </file>
   </example>

   ## ngClass and pre-existing CSS3 Transitions/Animations
   The ngClass directive still supports CSS3 Transitions/Animations even if they do not follow the ngAnimate CSS naming structure.
   Therefore, if any CSS3 Transition/Animation styles (outside of ngAnimate) are set on the element, then, if a ngClass animation
   is triggered, the ngClass animation will be skipped so that ngAnimate can allow for the pre-existing transition or animation to
   take over. This restriction allows for ngClass to still work with standard CSS3 Transitions/Animations that are defined
   outside of ngAnimate.
 */
var ngClassDirective = classDirective('', true);

/**
 * @ngdoc directive
 * @name ng.directive:ngClassOdd
 * @restrict AC
 *
 * @description
 * The `ngClassOdd` and `ngClassEven` directives work exactly as
 * {@link ng.directive:ngClass ngClass}, except they work in
 * conjunction with `ngRepeat` and take effect only on odd (even) rows.
 *
 * This directive can be applied only within the scope of an
 * {@link ng.directive:ngRepeat ngRepeat}.
 *
 * @element ANY
 * @param {expression} ngClassOdd {@link guide/expression Expression} to eval. The result
 *   of the evaluation can be a string representing space delimited class names or an array.
 *
 * @example
   <example>
     <file name="index.html">

             {{name}}

     </file>
     <file name="style.css">
       .odd {
         color: red;
       }
       .even {
         color: blue;
       }
     </file>
     <file name="scenario.js">
       it('should check ng-class-odd and ng-class-even', function() {
         expect(element('.doc-example-live li:first span').prop('className')).
           toMatch(/odd/);
         expect(element('.doc-example-live li:last span').prop('className')).
           toMatch(/even/);
       });
     </file>
   </example>
 */
var ngClassOddDirective = classDirective('Odd', 0);

/**
 * @ngdoc directive
 * @name ng.directive:ngClassEven
 * @restrict AC
 *
 * @description
 * The `ngClassOdd` and `ngClassEven` directives work exactly as
 * {@link ng.directive:ngClass ngClass}, except they work in
 * conjunction with `ngRepeat` and take effect only on odd (even) rows.
 *
 * This directive can be applied only within the scope of an
 * {@link ng.directive:ngRepeat ngRepeat}.
 *
 * @element ANY
 * @param {expression} ngClassEven {@link guide/expression Expression} to eval. The
 *   result of the evaluation can be a string representing space delimited class names or an array.
 *
 * @example
   <example>
     <file name="index.html">

             {{name}}

     </file>
     <file name="style.css">
       .odd {
         color: red;
       }
       .even {
         color: blue;
       }
     </file>
     <file name="scenario.js">
       it('should check ng-class-odd and ng-class-even', function() {
         expect(element('.doc-example-live li:first span').prop('className')).
           toMatch(/odd/);
         expect(element('.doc-example-live li:last span').prop('className')).
           toMatch(/even/);
       });
     </file>
   </example>
 */
var ngClassEvenDirective = classDirective('Even', 1);
<|endoftext|>


<commit_before>    // node.js built-in modules
var assert   = require('assert');

// npm modules
var fixtures = require('haraka-test-fixtures');

//Default config
var default_config = {
    main: {
        path: path.join(process.env.HARAKA, "accounting_files"),
        separator: "	",
        files_extension: "tsv",
        default_move_to_dir: "archive",
        move: 'false',
        move_interval: 86400,
        max_size: 200
    },
    location:
    {
        delivered: '/delivered',
        deferred: '/deferred',
        bounce: '/bounces'
    },
    fields:
    {
        delivered: 'type,timeLogged,timeQueued,rcpt,srcMta,srcIp,destIp,vmta,dsnStatus,dsnMsg',
        deferred:  'type,timeLogged,timeQueued,rcpt,srcMta,srcIp,destIp,vmta,dsnStatus,dsnMsg,delay',
        bounce:    'type,timeLogged,timeQueued,rcpt,srcMta,srcIp,destIp,vmta,dsnStatus,dsnMsg,bounceCat'
    }
};

beforeEach(function (done) {
    //this.outbound = new fixtures.plugin('outbound');
    this.plugin = new fixtures.plugin('index');
    this.plugin.cfg = default_config;

    this.connection = new fixtures.connection.createConnection();
    this.connection.transaction = fixtures.transaction.createTransaction();

    done();  // if a test hangs, assure you called done()
});

describe('Accounting-files plugin', function () {
    it('load', function (done) {
        assert.ok(this.plugin);
        done();
    });
});

var next = function () {
    test.equal(undefined, arguments[0]);
    test.done();
};

describe('Accounting-files config file', function () {
    it('loads "accounting_files.ini" from "config/accounting_files.ini"', function (done) {
        this.plugin.load_accounting_file_ini();

        assert.ok(this.plugin.cfg);

        done();
    });

    /*it('Check availability of "x-vmta" inside Header', function (done) {
        this.connection.transaction.header.add('x-vmta', "vmta_test");

        assert.ok( this.connection.transaction.header.headers['x-vmta'] );
        done();
    });

    it('Check availability of "mta1" inside Config file', function (done) {
        assert.ok(this.plugin.cfg.mta1);
        done();
    });*/
    //console.log(this.plugin.localAddresses());

});<commit_msg>Base test file fix<commit_after>// node.js built-in modules
var assert   = require('assert');

// npm modules
var fixtures = require('haraka-test-fixtures');
var path 	 = require("path");

//Default config
var default_config = {
    main: {
        path: path.join(process.env.HARAKA, "accounting_files"),
        separator: "	",
        files_extension: "tsv",
        default_move_to_dir: "archive",
        move: 'false',
        move_interval: 86400,
        max_size: 200
    },
    location:
    {
        delivered: '/delivered',
        deferred: '/deferred',
        bounce: '/bounces'
    },
    fields:
    {
        delivered: 'type,timeLogged,timeQueued,rcpt,srcMta,srcIp,destIp,vmta,dsnStatus,dsnMsg',
        deferred:  'type,timeLogged,timeQueued,rcpt,srcMta,srcIp,destIp,vmta,dsnStatus,dsnMsg,delay',
        bounce:    'type,timeLogged,timeQueued,rcpt,srcMta,srcIp,destIp,vmta,dsnStatus,dsnMsg,bounceCat'
    }
};

beforeEach(function (done) {
    //this.outbound = new fixtures.plugin('outbound');
    this.plugin = new fixtures.plugin('index');
    this.plugin.cfg = default_config;

    this.connection = new fixtures.connection.createConnection();
    this.connection.transaction = fixtures.transaction.createTransaction();

    done();  // if a test hangs, assure you called done()
});

describe('Accounting-files plugin', function () {
    it('load', function (done) {
        assert.ok(this.plugin);
        done();
    });
});

/*var next = function () {
    test.equal(undefined, arguments[0]);
    test.done();
};*/

describe('Accounting-files config file', function () {
    it('loads "accounting_files.ini" from "config/accounting_files.ini"', function (done) {
        this.plugin.load_accounting_file_ini();

        assert.ok(this.plugin.cfg);

        done();
    });

    /*it('Check availability of "x-vmta" inside Header', function (done) {
        this.connection.transaction.header.add('x-vmta', "vmta_test");

        assert.ok( this.connection.transaction.header.headers['x-vmta'] );
        done();
    });

    it('Check availability of "mta1" inside Config file', function (done) {
        assert.ok(this.plugin.cfg.mta1);
        done();
    });*/
    //console.log(this.plugin.localAddresses());

});<|endoftext|>


<commit_before>// $.pjax fallback tests should run on both pushState and
// non-pushState compatible browsers.
module("$.pjax fallback", {
  setup: function() {
    var self = this
    stop()
    this.loaded = function(frame) {
      self.frame  = frame
      self.loaded = $.noop
      start()
    }
    window.iframeLoad = function(frame) {
      setTimeout(function() { self.loaded(frame) }, 0)
    }
    $("#qunit-fixture").append("<iframe src='home.html'>")
  },
  teardown: function() {
    delete window.iframeLoad
  }
})

asyncTest("sets new url", function() {
  var frame = this.frame

  this.loaded = function() {
    equal(frame.location.pathname, "/hello.html")
    start()
  }

  frame.$.pjax({
    url: "hello.html",
    container: "#main"
  })
})

asyncTest("sets new url for function", function() {
  var frame = this.frame

  this.loaded = function() {
    equal(frame.location.pathname, "/hello.html")
    start()
  }

  frame.$.pjax({
    url: function() { return "hello.html" },
    container: "#main"
  })
})

asyncTest("updates container html", function() {
  var frame = this.frame

  this.loaded = function(frame) {
    equal(frame.$("#main p").html(), "Hello!")
    start()
  }

  frame.$.pjax({
    url: "/hello.html",
    container: "#main"
  })
})

asyncTest("sets title to response <title>", function() {
  var frame = this.frame

  this.loaded = function(frame) {
    equal(frame.document.title, "Hello")
    start()
  }

  frame.$.pjax({
    url: "/hello.html",
    container: "#main"
  })
})
<commit_msg>Test adding history entries<commit_after>// $.pjax fallback tests should run on both pushState and
// non-pushState compatible browsers.
module("$.pjax fallback", {
  setup: function() {
    var self = this
    stop()
    this.loaded = function(frame) {
      self.frame  = frame
      self.loaded = $.noop
      start()
    }
    window.iframeLoad = function(frame) {
      setTimeout(function() { self.loaded(frame) }, 0)
    }
    $("#qunit-fixture").append("<iframe src='home.html'>")
  },
  teardown: function() {
    delete window.iframeLoad
  }
})

asyncTest("sets new url", function() {
  var frame = this.frame

  this.loaded = function() {
    equal(frame.location.pathname, "/hello.html")
    start()
  }

  frame.$.pjax({
    url: "hello.html",
    container: "#main"
  })
})

asyncTest("sets new url for function", function() {
  var frame = this.frame

  this.loaded = function() {
    equal(frame.location.pathname, "/hello.html")
    start()
  }

  frame.$.pjax({
    url: function() { return "hello.html" },
    container: "#main"
  })
})

asyncTest("updates container html", function() {
  var frame = this.frame

  this.loaded = function(frame) {
    equal(frame.$("#main p").html(), "Hello!")
    start()
  }

  frame.$.pjax({
    url: "/hello.html",
    container: "#main"
  })
})

asyncTest("sets title to response <title>", function() {
  var frame = this.frame

  this.loaded = function(frame) {
    equal(frame.document.title, "Hello")
    start()
  }

  frame.$.pjax({
    url: "/hello.html",
    container: "#main"
  })
})

asyncTest("adds entry to browser history", function() {
  var frame = this.frame
  var count = 0

  this.loaded = function() {
    count++

    if (count == 1) {
      equal(frame.location.pathname, "/hello.html")
      ok(frame.history.length > 1)
      frame.history.back()
    } else if (count == 2) {
      equal(frame.location.pathname, "/home.html")
      frame.history.forward()
      start()
    }
  }

  frame.$.pjax({
    url: "hello.html",
    container: "#main"
  })
})
<|endoftext|>


<commit_before>var Game = function(player1, player2){
  this.player1 = player1;
  this.player2 = player2;
  console.log('New Game created with' + this.player1 + 'and' + this.player2);
};

module.exports = Game;
<commit_msg>Added countdown to Game<commit_after>var Game = function(player1, player2) {
  this.player1 = player1;
  this.player2 = player2;
  this.sendCountdown(player1, 3);
  this.sendCountdown(player2, 3);
};

Game.prototype.sendCountdown = function(player, count) {
  player.emit('countdown', {count: count});
};

module.exports = Game;
<|endoftext|>


<commit_before>const os   = require('os');
const path = require('path');

module.exports = require('rc')('did', {

  // path to the database
  database: path.join(os.homedir(), '.did.sqlite3'),

  // colorized output
  color: {
    id        : 'cyan',
    timestamp : 'green',
    entry     : 'white',
    match     : 'yellow',
  },

  // timestamp display format
  dateFormat : 'dd MMM | hh:mm tt',

  // EDITOR
  editor     : process.env.EDITOR,
});
<commit_msg>app/config<commit_after>module.exports = require('rc')('did', {

  // path to the database
  database: '~/.did.sqlite3',

  // colorized output
  color: {
    id        : 'cyan',
    timestamp : 'green',
    entry     : 'white',
    match     : 'yellow',
  },

  // timestamp display format
  dateFormat : 'dd MMM | hh:mm tt',

  // EDITOR
  editor     : process.env.EDITOR,
});
<|endoftext|>


<commit_before>/**
 * Created by AAravindan on 5/10/16.
 */
"use strict"

const LinkedList = require('../Utils/FixedSizeLinkedList');
const SMA        = require('../moving_averages/SMA');
const nf         = require('../Utils/NumberFormatter');

let Stochastic;

module.exports = Stochastic = function(input) {

  let lows = input.low;
  let highs = input.high;
  let closes = input.close;
  let period = input.period;
  let signalPeriod = input.signalPeriod;
  let format = input.format || nf;

  if(!((lows.length === highs.length) && (highs.length === closes.length) )){
    throw ('Inputs(low,high, close) not of equal size');
  }

  this.result = [];
  //%K = (Current Close - Lowest Low)/(Highest High - Lowest Low) * 100
  //%D = 3-day SMA of %K
  //
  //Lowest Low = lowest low for the look-back period
  //Highest High = highest high for the look-back period
  //%K is multiplied by 100 to move the decimal point two places
  this.generator = (function* (){
    let index = 1;
    let pastHighPeriods = new LinkedList(period, true, false);
    let pastLowPeriods = new LinkedList(period, false, true);
    let dSma           = new SMA({
      period : signalPeriod,
      values : []
    });
    let k,d;
    var tick = yield;
    while (true) {
      pastHighPeriods.push(tick.high);
      pastLowPeriods.push(tick.low);
      if(index < period){
        index++;
        tick = yield;
        continue;
      }
      let periodLow = pastLowPeriods.periodLow;
      k = format((tick.close - periodLow) / (pastHighPeriods.periodHigh - periodLow) * 100);
      d = dSma.nextValue(k);
      tick = yield {
        k : k,
        d : d
      }
    }
  })();

  this.generator.next();

  lows.forEach((tick, index) => {
    var result = this.generator.next({
      high : highs[index],
      low  : lows[index],
      close : closes[index]
    });
    if(result.value !== undefined){
      this.result.push(result.value);
    }
  });
};

Stochastic.calculate = function(input) {
  if(input.reversedInput) {
    input.high.reverse();
    input.low.reverse();
    input.close.reverse();
  }
  let result = (new Stochastic(input)).result;
  input.reversedInput ? result.reverse():undefined;
  return result;
};

Stochastic.prototype.getResult = function () {
  return this.result;
};

Stochastic.prototype.nextValue = function (input) {
  let nextResult = this.generator.next(input);
  if(nextResult.value !== undefined)
    return nextResult.value;
};
<commit_msg>missing fix on "Pass number format setting to prevent accuracy lost"<commit_after>/**
 * Created by AAravindan on 5/10/16.
 */
"use strict"

const LinkedList = require('../Utils/FixedSizeLinkedList');
const SMA        = require('../moving_averages/SMA');
const nf         = require('../Utils/NumberFormatter');

let Stochastic;

module.exports = Stochastic = function(input) {

  let lows = input.low;
  let highs = input.high;
  let closes = input.close;
  let period = input.period;
  let signalPeriod = input.signalPeriod;
  let format = input.format || nf;

  if(!((lows.length === highs.length) && (highs.length === closes.length) )){
    throw ('Inputs(low,high, close) not of equal size');
  }

  this.result = [];
  //%K = (Current Close - Lowest Low)/(Highest High - Lowest Low) * 100
  //%D = 3-day SMA of %K
  //
  //Lowest Low = lowest low for the look-back period
  //Highest High = highest high for the look-back period
  //%K is multiplied by 100 to move the decimal point two places
  this.generator = (function* (){
    let index = 1;
    let pastHighPeriods = new LinkedList(period, true, false);
    let pastLowPeriods = new LinkedList(period, false, true);
    let dSma           = new SMA({
      period : signalPeriod,
      values : [],
      format : (v) => {return v}
    });
    let k,d;
    var tick = yield;
    while (true) {
      pastHighPeriods.push(tick.high);
      pastLowPeriods.push(tick.low);
      if(index < period){
        index++;
        tick = yield;
        continue;
      }
      let periodLow = pastLowPeriods.periodLow;
      k = (tick.close - periodLow) / (pastHighPeriods.periodHigh - periodLow) * 100;
      d = dSma.nextValue(k);
      tick = yield {
        k : format(k),
        d : d ? format(d) : undefined
      }
    }
  })();

  this.generator.next();

  lows.forEach((tick, index) => {
    var result = this.generator.next({
      high : highs[index],
      low  : lows[index],
      close : closes[index]
    });
    if(result.value !== undefined){
      this.result.push(result.value);
    }
  });
};

Stochastic.calculate = function(input) {
  if(input.reversedInput) {
    input.high.reverse();
    input.low.reverse();
    input.close.reverse();
  }
  let result = (new Stochastic(input)).result;
  input.reversedInput ? result.reverse():undefined;
  return result;
};

Stochastic.prototype.getResult = function () {
  return this.result;
};

Stochastic.prototype.nextValue = function (input) {
  let nextResult = this.generator.next(input);
  if(nextResult.value !== undefined)
    return nextResult.value;
};
<|endoftext|>


<commit_before>var assert = require('chai').assert;

var defaultWordBreaker = require('../../build/intermediate').wordBreakers['default'];
var decorateWithJoin = require('../../build/intermediate').wordBreakers['join_'];

describe('The join word breaker decorator', function () {
  it('should decorate an existing word breaker', function () {
    let breakWords = decorateWithJoin(defaultWordBreaker, ['-']);
    assert.isFunction(breakWords);
  });

  const TEST_CASES = [
    /* input,      joiners,  default breaks,        breaks with joins */
    // Original test case from https://github.com/keymanapp/keyman/issues/2753
    ['khui-chhùi', ['-'],   ["khui", "-", "chhùi"], ["khui-chhùi"]],

    // Plains Cree SRO:
    ['ê-kotiskâwêyâhk', ['-'], ['ê', '-', 'kotiskâwêyâhk'], ['ê-kotiskâwêyâhk']],

    // Edge cases:

    // Joiner alone:
    ['-', ['-'], ['-'], ['-']],
    // Joiner at the end:
    ['ni-', ['-'], ['ni', '-'], ['ni-']],
    // Joiner at the end:
    ['-ân', ['-'], ['-', 'ân'], ['-ân']],

    // This was my guiding test case:
    [
      "-yâhk ê-nitawi-kotiskâwêyâhk ni-",
      ["-"],
      ["-", "yâhk", "ê", "-", "nitawi", "-", "kotiskâwêyâhk", "ni", "-"],
      ["-yâhk", "ê-nitawi-kotiskâwêyâhk", "ni-"]
    ],

    // Do not perform any joins:
    ["hello world", "-", ["hello", "world"], ["hello", "world"]],

    // Joining using multiple joiners
    [
      "Email: no-body@example.com",
      ["@", "-"],
      ["Email", ":", "no", "-", "body", "@", "example.com"],
      ["Email", ":", "no-body@example.com"]
    ],

    // Joining with two or more joiners in a row
    [
      "nobody@@example.com",
      ["@"],
      ["nobody", "@", "@", "example.com"],
      ["nobody@@example.com"]
    ],

    // it should NOT join non-contiguous spans:
    [
      "this- is -bad",
      ["-"],
      ["this", "-", "is", "-", "bad"],
      ["this-", "is", "-bad"]
    ],
  ]

  for (let [phrase, joiners, unjoined, expected] of TEST_CASES) {
    it.only(`should break «${[phrase]}» as [${expected.join(' ;; ')}]`, function () {
      let breakWords = decorateWithJoin(defaultWordBreaker, joiners);
      let unjoinedResult = defaultWordBreaker(phrase).map(onlyText);
      assert.deepEqual(unjoinedResult, unjoined);
      let actualResult = breakWords(phrase).map(onlyText);
      assert.deepEqual(actualResult, expected);
    });
  }

  /**
   * Get just the text from a span.
   * @param {Span} span
   */
  function onlyText(span) {
    return span.text;
  }
});<commit_msg>fix(common/lmlayer): remove it.only accidentally left it 😬<commit_after>var assert = require('chai').assert;

var defaultWordBreaker = require('../../build/intermediate').wordBreakers['default'];
var decorateWithJoin = require('../../build/intermediate').wordBreakers['join_'];

describe('The join word breaker decorator', function () {
  it('should decorate an existing word breaker', function () {
    let breakWords = decorateWithJoin(defaultWordBreaker, ['-']);
    assert.isFunction(breakWords);
  });

  const TEST_CASES = [
    /* input,      joiners,  default breaks,        breaks with joins */
    // Original test case from https://github.com/keymanapp/keyman/issues/2753
    ['khui-chhùi', ['-'],   ["khui", "-", "chhùi"], ["khui-chhùi"]],

    // Plains Cree SRO:
    ['ê-kotiskâwêyâhk', ['-'], ['ê', '-', 'kotiskâwêyâhk'], ['ê-kotiskâwêyâhk']],

    // Edge cases:

    // Joiner alone:
    ['-', ['-'], ['-'], ['-']],
    // Joiner at the end:
    ['ni-', ['-'], ['ni', '-'], ['ni-']],
    // Joiner at the end:
    ['-ân', ['-'], ['-', 'ân'], ['-ân']],

    // This was my guiding test case:
    [
      "-yâhk ê-nitawi-kotiskâwêyâhk ni-",
      ["-"],
      ["-", "yâhk", "ê", "-", "nitawi", "-", "kotiskâwêyâhk", "ni", "-"],
      ["-yâhk", "ê-nitawi-kotiskâwêyâhk", "ni-"]
    ],

    // Do not perform any joins:
    ["hello world", "-", ["hello", "world"], ["hello", "world"]],

    // Joining using multiple joiners
    [
      "Email: no-body@example.com",
      ["@", "-"],
      ["Email", ":", "no", "-", "body", "@", "example.com"],
      ["Email", ":", "no-body@example.com"]
    ],

    // Joining with two or more joiners in a row
    [
      "nobody@@example.com",
      ["@"],
      ["nobody", "@", "@", "example.com"],
      ["nobody@@example.com"]
    ],

    // it should NOT join non-contiguous spans:
    [
      "this- is -bad",
      ["-"],
      ["this", "-", "is", "-", "bad"],
      ["this-", "is", "-bad"]
    ],
  ]

  for (let [phrase, joiners, unjoined, expected] of TEST_CASES) {
    it(`should break «${[phrase]}» as [${expected.join(' ;; ')}]`, function () {
      let breakWords = decorateWithJoin(defaultWordBreaker, joiners);
      let unjoinedResult = defaultWordBreaker(phrase).map(onlyText);
      assert.deepEqual(unjoinedResult, unjoined);
      let actualResult = breakWords(phrase).map(onlyText);
      assert.deepEqual(actualResult, expected);
    });
  }

  /**
   * Get just the text from a span.
   * @param {Span} span
   */
  function onlyText(span) {
    return span.text;
  }
});<|endoftext|>


<commit_before>/*
Account is a Person
A person is either alive, dead, undead, or fictional.
http://schema.org/Person
*/

const mongoose = require('mongoose')
const Schema = mongoose.Schema

const passportLocalMongoose = require('passport-local-mongoose')
const sequence = require('mongoose-sequence')

const AccountSchema = new Schema({
  name: {
    type: String,
    required: true,
    first: {
      type: String,
      required: false
    },
    middle: {
      type: String,
      required: false
    },
    last: {
      type: String,
      required: false
    }
  },
  username: {
    type: String,
    required: true,
    unique: true
  },
  email: {
    type: String,
    required: true,
    unique: true
  },
  password: {
    type: String,
    required: false
  },
  verified: {
    type: Boolean,
    required: false
  },
  image: {
    type: String,
    required: false
  },
  gender: {
    type: Number,
    required: false
  },
  birthDate: {
    type: Date,
    required: false
  },
  age: {
    type: Number,
    required: false
  },
  telephone: {
    type: String,
    required: false
  },
  affiliation: {
    type: String,
    required: false
  },
  url: {
    type: String,
    required: false
  },
  books: [
    {
      type: String,
      required: false,
      foreignField: 'isbn',
      ref: 'Book'
    }
  ],
  createdBy: [
    {
      type: Number,
      required: false,
      foreignField: 'accountId',
      ref: 'Account'
    }
  ],
  updatedBy: [
    {
      type: Number,
      required: false,
      foreignField: 'accountId',
      ref: 'Account'
    }
  ]
}, {
  timestamps: true
})

// Auto increment accountId
AccountSchema.plugin(sequence, { inc_field: 'accountId' })

// Auto hash and salt the password field
AccountSchema.plugin(passportLocalMongoose)

// -----------------------------------------------------------------------------
// POPULATE

// AccountSchema.plugin(deepPopulate)

// AccountSchema.pre('find', function (next) {
//   this.populate('books.isbn', 'name')
//   next()
// })
// AccountSchema.pre('findOne', function (next) {
//   this.populate('books.isbn', 'name')
//   next()
// })
// -----------------------------------------------------------------------------

module.exports = mongoose.model('Account', AccountSchema)
<commit_msg>Swap packages and add validator<commit_after>/*
Account is a Person
A person is either alive, dead, undead, or fictional.
http://schema.org/Person
*/

const bcrypt = require('bcryptjs')
const mongoose = require('mongoose')
const sequence = require('mongoose-sequence')
const validate = require('mongoose-validator')

const Schema = mongoose.Schema

const roleTypes = ['super', 'admin', 'dev', 'ops', 'test', 'user']
const authTypes = ['local', 'github', 'twitter', 'facebook', 'google']

// -----------------------------------------------------------------------------

const validateName = validate({
  validator: 'isLength',
  arguments: [3, 50],
  message: 'Name must between {ARGS[0]} and {ARGS[1]} characters'
})

const validateEmail = [
  validate({
    validator: 'isEmail',
    message: 'Email must be a valid email (name@example.com)'
  })
]

const validateUsername = [
  validate({
    validator: 'isLength',
    arguments: [1, 50],
    message: 'Username must between {ARGS[0]} and {ARGS[1]} characters'
  }),
  validate({
    validator: 'isAlphanumeric',
    passIfEmpty: true,
    message: 'Name should contain alpha-numeric characters only'
  })
]

const validateURL = [
  validate({
    validator: 'isURL',
    message: 'URL must be a valid URL (http://example.com/path/to/image.png)'
  })
]

// -----------------------------------------------------------------------------

const AccountSchema = new Schema({
  // Internal
  name: {
    type: String,
    validate: validateName
  },
  username: {
    type: String,
    required: true,
    unique: true
  },
  email: {
    type: String,
    required: true,
    unique: true
  },
  password: {
    type: String,
    required: false
  },
  verified: {
    type: Boolean,
    required: false
  },
  image: {
    type: String,
    required: false
  },
  gender: {
    type: Number,
    required: false
  },
  birthDate: {
    type: Date,
    required: false
  },
  age: {
    type: Number,
    required: false
  },
  telephone: {
    type: String,
    required: false
  },
  affiliation: {
    type: String,
    required: false
  },
  url: {
    type: String,
    required: false
  },
  books: [
    {
      type: String,
      required: false,
      foreignField: 'isbn',
      ref: 'Book'
    }
  ],
  createdBy: [
    {
      type: Number,
      required: false,
      foreignField: 'accountId',
      ref: 'Account'
    }
  ],
  updatedBy: [
    {
      type: Number,
      required: false,
      foreignField: 'accountId',
      ref: 'Account'
    }
  ]
}, {
  timestamps: true
})

// Auto increment accountId
AccountSchema.plugin(sequence, { inc_field: 'accountId' })

// Auto hash and salt the password field
AccountSchema.plugin(passportLocalMongoose)

// -----------------------------------------------------------------------------
// POPULATE

// AccountSchema.plugin(deepPopulate)

// AccountSchema.pre('find', function (next) {
//   this.populate('books.isbn', 'name')
//   next()
// })
// AccountSchema.pre('findOne', function (next) {
//   this.populate('books.isbn', 'name')
//   next()
// })
// -----------------------------------------------------------------------------

module.exports = mongoose.model('Account', AccountSchema)
<|endoftext|>


<commit_before>var placement = function (units, objects, container, placementContainer) {
  var picker = document.createElement('ul');

  var selectedUnit;
  for (let unit of units) {
    var unitEl = document.createElement('li');
    unitEl.innerHTML = unit;
    unitEl.onclick = function () {
      selectedUnit = unit;
    };

    picker.appendChild(unitEl);
  }

  for (let object of objects.filter(o => o.type === 'marker')) {
    object.callback = function () {
      if (!selectedUnit) {
        return;
      }

      object.type = 'unit';
      object.unitType = selectedUnit;
      /* XXX I'd like to find some CLEANER way than calling draw manually */
      draw(objects, container);
    };
  }

  placementContainer.appendChild(picker);
};
<commit_msg>Add a cancel marker<commit_after>var placement = function (units, objects, container, placementContainer) {
  var picker = document.createElement('ul');

  var selectedUnit;
  for (let unit of ['(remove)', ...units]) {
    var unitEl = document.createElement('li');
    unitEl.innerHTML = unit;
    unitEl.onclick = function () {
      selectedUnit = unit;
    };

    picker.appendChild(unitEl);
  }

  for (let object of objects.filter(o => o.type === 'marker')) {
    object.callback = function () {
      if (!selectedUnit) {
        return;
      }

      if (selectedUnit == '(remove)') {
        object.type = 'marker';
        delete object.unitType;
      } else {
        object.type = 'unit';
        object.unitType = selectedUnit;
      }

      /* XXX I'd like to find some CLEANER way than calling draw manually */
      draw(objects, container);
    };
  }

  placementContainer.appendChild(picker);
};
<|endoftext|>


<commit_before>/** @jsx React.DOM */
var React = require('react');
var Router = require('react-router-component');

var EditIconLink = React.createClass({displayName: 'EditIconLink',
    propTypes:{
        href: React.PropTypes.string.isRequired
    },
    render: function () {
        var Link = Router.Link;
        return(this.transferPropsTo(Link(null, React.DOM.i( {className:"edit icon"}))));
    }
});

module.exports = EditIconLink;<commit_msg>Delete EditIconLink.js<commit_after><|endoftext|>


<commit_before>angular.module('ui.bootstrap.datetimepicker', ["ui.bootstrap.dateparser", "ui.bootstrap.datepicker", "ui.bootstrap.timepicker"])
  .directive('datepickerPopup', function () {
    return {
      restrict: 'EAC',
      require: 'ngModel',
      link: function (scope, element, attr, controller) {
        //remove the default formatter from the input directive to prevent conflict
        controller.$formatters.shift();
      }
    }
  })
  .directive('datetimepicker', [
    function () {
      if (angular.version.full < '1.4.0') {
        return {
          restrict: 'EA',
          template: "
Angular 1.4.0 or above is required for datetimepicker to work correctly
"
        };
      }
      return {
        restrict: 'EA',
        require: 'ngModel',
        scope: {
          ngModel: '=',
          dayFormat: "=",
          monthFormat: "=",
          yearFormat: "=",
          dayHeaderFormat: "=",
          dayTitleFormat: "=",
          monthTitleFormat: "=",
          yearRange: "=",
          minDate: "=",
          maxDate: "=",
          dateOptions: "=?",
          dateDisabled: "&",
          dateNgClick: "&",
          hourStep: "=",
          dateOpened: "=",
          minuteStep: "=",
          showMeridian: "=",
          meredians: "=",
          mousewheel: "=",
          readonlyTime: "=",
          readonlyDate: "=",
          hiddenTime: "=",
          hiddenDate: "="
        },
        template: function (elem, attrs) {
          function dashCase(name) {
            return name.replace(/[A-Z]/g, function (letter, pos) {
              return (pos ? '-' : '') + letter.toLowerCase();
            });
          }

          function createAttr(innerAttr, dateTimeAttrOpt) {
            var dateTimeAttr = angular.isDefined(dateTimeAttrOpt) ? dateTimeAttrOpt : innerAttr;
            if (attrs[dateTimeAttr]) {
              return dashCase(innerAttr) + "=\"" + dateTimeAttr + "\" ";
            } else {
              return '';
            }
          }

          function createFuncAttr(innerAttr, funcArgs, dateTimeAttrOpt, defaultImpl) {
            var dateTimeAttr = angular.isDefined(dateTimeAttrOpt) ? dateTimeAttrOpt : innerAttr;
            if (attrs[dateTimeAttr]) {
              return dashCase(innerAttr) + "=\"" + dateTimeAttr + "({" + funcArgs + "})\" ";
            } else {
              return angular.isDefined(defaultImpl) ? dashCase(innerAttr) + "=\"" + defaultImpl + "\"" : "";
            }
          }

          function createEvalAttr(innerAttr, dateTimeAttrOpt) {
            var dateTimeAttr = angular.isDefined(dateTimeAttrOpt) ? dateTimeAttrOpt : innerAttr;
            if (attrs[dateTimeAttr]) {
              return dashCase(innerAttr) + "=\"" + attrs[dateTimeAttr] + "\" ";
            } else {
              return dashCase(innerAttr) + " ";
            }
          }

          function createAttrConcat(previousAttrs, attr) {
            return previousAttrs + createAttr.apply(null, attr)
          }

          var dateTmpl = "
" +
            "<input class=\"form-control\" type=\"text\" " +
            "ng-change=\"date_change($event)\" " +
            "is-open=\"innerDateOpened\" " +
            "datepicker-options=\"dateOptions\" " +
            "uib-datepicker-popup=\"{{dateFormat}}\"" +
            "ng-model=\"ngModel\" " + [
              ["dayFormat"],
              ["monthFormat"],
              ["yearFormat"],
              ["dayHeaderFormat"],
              ["dayTitleFormat"],
              ["monthTitleFormat"],
              ["yearRange"],
              ["ngHide", "hiddenDate"],
              ["ngDisabled", "readonlyDate"]
            ].reduce(createAttrConcat, '') +
            createFuncAttr("ngClick",
              "$event: $event, opened: opened",
              "dateNgClick",
              "open($event)") +
            createEvalAttr("currentText", "currentText") +
            createEvalAttr("clearText", "clearText") +
            createEvalAttr("datepickerAppendToBody", "datepickerAppendToBody") +
            createEvalAttr("closeText", "closeText") +
            createEvalAttr("placeholder", "placeholder") +
            "/>\n" +
            "
\n";
          var timeTmpl = "
\n" +
            "<uib-timepicker " + [
              ["hourStep"],
              ["minuteStep"],
              ["showMeridian"],
              ["meredians"],
              ["mousewheel"],
              ["min", "minDate"],
              ["max", "maxDate"],
              ["ngHide", "hiddenTime"],
              ["readonlyInput", "readonlyTime"]
            ].reduce(createAttrConcat, '') +
            createEvalAttr("showSpinners", "showSpinners") +
            "></timepicker>\n" +
            "
";
          var tmpl = "<ng-form name=\"datetimepickerForm\" isolate-form>" + dateTmpl + timeTmpl + "</ng-form>";
          return tmpl;
        },
        controller: ['$scope', '$attrs',
          function ($scope, $attrs) {
            $scope.createDateOptionsWatch = function(dateAttr) {
              $scope.$watch(dateAttr, function (value) {
                var date = new Date(value);
                $scope.dateOptions[dateAttr] = date;
                if ($scope[dateAttr]) {
                  $scope[dateAttr] = date;
                }
              }, true);
            }
            $scope.date_change = function () {
              // If we changed the date only, set the time (h,m) on it.
              // This is important in case the previous date was null.
              // This solves the issue when the user set a date and time, cleared the date, and chose another date,
              // and then, the time was cleared too - which is unexpected
              var time = $scope.time;
              if ($scope.ngModel && $scope.time) { // if ngModel is null, that's because the user cleared the date field
                $scope.ngModel.setHours(time.getHours(), time.getMinutes(), 0, 0);
              }
            };

            $scope.time_change = function () {

              if ($scope.ngModel && $scope.time) {
                // convert from ISO format to Date
                if (!($scope.ngModel instanceof Date)) $scope.ngModel = new Date($scope.ngModel);
                $scope.ngModel.setHours($scope.time.getHours(), $scope.time.getMinutes(), 0, 0);
              } else {
                $scope.ngModel = new Date();
              }
            };
            $scope.open = function ($event) {
              $event.preventDefault();
              $event.stopPropagation();
              $scope.innerDateOpened = true;
            };
            $attrs.$observe('dateFormat', function(newDateFormat, oldValue) {
              $scope.dateFormat = newDateFormat;
            });
            $scope.dateOptions = angular.isDefined($scope.dateOptions) ? $scope.dateOptions : {};
            $scope.createDateOptionsWatch('minDate');
            $scope.createDateOptionsWatch('maxDate');
            $scope.dateOptions.dateDisabled = $scope.dateDisabled;
          }
        ],
        link: function (scope, element, attrs, ctrl) {
          var firstTimeAssign = true;

          scope.$watch(function () {
            return scope.ngModel;
          }, function (newTime) {
            var timeElement = document.evaluate(".//*[@ng-model='time']",
              element[0], null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;

            // if a time element is focused, updating its model will cause hours/minutes to be formatted by padding with leading zeros
            if (timeElement && !timeElement.contains(document.activeElement)) {

              if (newTime === null || newTime === '') { // if the newTime is not defined
                if (firstTimeAssign) { // if it's the first time we assign the time value
                  // create a new default time where the hours, minutes, seconds and milliseconds are set to 0.
                  newTime = new Date();
                  newTime.setHours(0, 0, 0, 0);
                } else { // clear the time
                  scope.time = null;
                  return;
                }
              }
              // Update timepicker (watch on ng-model in timepicker does not use object equality),
              // also if the ngModel was not a Date, convert it to date
              newTime = new Date(newTime);

              if (isNaN(newTime.getTime()) === false) {
                scope.time = newTime; // change the time in timepicker
                if (firstTimeAssign) {
                  firstTimeAssign = false;
                }
              }
            }
          }, true);

          scope.$watch(function () {
            return scope.datetimepickerForm.$error;
          }, function (errors) {
            Object.keys(ctrl.$error).forEach(function (error) {
              ctrl.$setValidity(error, true);
            });
            Object.keys(errors).forEach(function (error) {
              ctrl.$setValidity(error, false);
            });
          }, true);

          scope.$watch('dateOpened', function (value) {
            scope.innerDateOpened = value;
          });
          scope.$watch('innerDateOpened', function (value) {
            if (angular.isDefined(scope.dateOpened)) {
              scope.dateOpened = value;
            }
          });
        }
      }
    }
  ]).directive('isolateForm', [function () {
  return {
    restrict: 'A',
    require: '?form',
    link: function (scope, elm, attrs, ctrl) {
      if (!ctrl) {
        return;
      }
      // Do a copy of the controller
      var ctrlCopy = {};
      angular.copy(ctrl, ctrlCopy);

      // Get the parent of the form
      var parent = elm.parent().controller('form');
      // Remove parent link to the controller
      if (!parent) {
        return;
      }
      parent.$removeControl(ctrl);

      // Replace form controller with a "isolated form"
      var isolatedFormCtrl = {
        $setValidity: function (validationToken, isValid, control) {
          ctrlCopy.$setValidity(validationToken, isValid, control);
          parent.$setValidity(validationToken, true, ctrl);
        },
        $setDirty: function () {
          elm.removeClass('ng-pristine').addClass('ng-dirty');
          ctrl.$dirty = true;
          ctrl.$pristine = false;
        }
      };
      angular.extend(ctrl, isolatedFormCtrl);
    }
  };
}]);
<commit_msg>readonlyTime should correspond to ngDisabled<commit_after>angular.module('ui.bootstrap.datetimepicker', ["ui.bootstrap.dateparser", "ui.bootstrap.datepicker", "ui.bootstrap.timepicker"])
  .directive('datepickerPopup', function () {
    return {
      restrict: 'EAC',
      require: 'ngModel',
      link: function (scope, element, attr, controller) {
        //remove the default formatter from the input directive to prevent conflict
        controller.$formatters.shift();
      }
    }
  })
  .directive('datetimepicker', [
    function () {
      if (angular.version.full < '1.4.0') {
        return {
          restrict: 'EA',
          template: "
Angular 1.4.0 or above is required for datetimepicker to work correctly
"
        };
      }
      return {
        restrict: 'EA',
        require: 'ngModel',
        scope: {
          ngModel: '=',
          dayFormat: "=",
          monthFormat: "=",
          yearFormat: "=",
          dayHeaderFormat: "=",
          dayTitleFormat: "=",
          monthTitleFormat: "=",
          yearRange: "=",
          minDate: "=",
          maxDate: "=",
          dateOptions: "=?",
          dateDisabled: "&",
          dateNgClick: "&",
          hourStep: "=",
          dateOpened: "=",
          minuteStep: "=",
          showMeridian: "=",
          meredians: "=",
          mousewheel: "=",
          readonlyTime: "=",
          readonlyDate: "=",
          hiddenTime: "=",
          hiddenDate: "="
        },
        template: function (elem, attrs) {
          function dashCase(name) {
            return name.replace(/[A-Z]/g, function (letter, pos) {
              return (pos ? '-' : '') + letter.toLowerCase();
            });
          }

          function createAttr(innerAttr, dateTimeAttrOpt) {
            var dateTimeAttr = angular.isDefined(dateTimeAttrOpt) ? dateTimeAttrOpt : innerAttr;
            if (attrs[dateTimeAttr]) {
              return dashCase(innerAttr) + "=\"" + dateTimeAttr + "\" ";
            } else {
              return '';
            }
          }

          function createFuncAttr(innerAttr, funcArgs, dateTimeAttrOpt, defaultImpl) {
            var dateTimeAttr = angular.isDefined(dateTimeAttrOpt) ? dateTimeAttrOpt : innerAttr;
            if (attrs[dateTimeAttr]) {
              return dashCase(innerAttr) + "=\"" + dateTimeAttr + "({" + funcArgs + "})\" ";
            } else {
              return angular.isDefined(defaultImpl) ? dashCase(innerAttr) + "=\"" + defaultImpl + "\"" : "";
            }
          }

          function createEvalAttr(innerAttr, dateTimeAttrOpt) {
            var dateTimeAttr = angular.isDefined(dateTimeAttrOpt) ? dateTimeAttrOpt : innerAttr;
            if (attrs[dateTimeAttr]) {
              return dashCase(innerAttr) + "=\"" + attrs[dateTimeAttr] + "\" ";
            } else {
              return dashCase(innerAttr) + " ";
            }
          }

          function createAttrConcat(previousAttrs, attr) {
            return previousAttrs + createAttr.apply(null, attr)
          }

          var dateTmpl = "
" +
            "<input class=\"form-control\" type=\"text\" " +
            "ng-change=\"date_change($event)\" " +
            "is-open=\"innerDateOpened\" " +
            "datepicker-options=\"dateOptions\" " +
            "uib-datepicker-popup=\"{{dateFormat}}\"" +
            "ng-model=\"ngModel\" " + [
              ["dayFormat"],
              ["monthFormat"],
              ["yearFormat"],
              ["dayHeaderFormat"],
              ["dayTitleFormat"],
              ["monthTitleFormat"],
              ["yearRange"],
              ["ngHide", "hiddenDate"],
              ["ngDisabled", "readonlyDate"]
            ].reduce(createAttrConcat, '') +
            createFuncAttr("ngClick",
              "$event: $event, opened: opened",
              "dateNgClick",
              "open($event)") +
            createEvalAttr("currentText", "currentText") +
            createEvalAttr("clearText", "clearText") +
            createEvalAttr("datepickerAppendToBody", "datepickerAppendToBody") +
            createEvalAttr("closeText", "closeText") +
            createEvalAttr("placeholder", "placeholder") +
            "/>\n" +
            "
\n";
          var timeTmpl = "
\n" +
            "<uib-timepicker " + [
              ["hourStep"],
              ["minuteStep"],
              ["showMeridian"],
              ["meredians"],
              ["mousewheel"],
              ["min", "minDate"],
              ["max", "maxDate"],
              ["ngHide", "hiddenTime"],
              ["ngDisabled", "readonlyTime"]
            ].reduce(createAttrConcat, '') +
            createEvalAttr("showSpinners", "showSpinners") +
            "></timepicker>\n" +
            "
";
          var tmpl = "<ng-form name=\"datetimepickerForm\" isolate-form>" + dateTmpl + timeTmpl + "</ng-form>";
          return tmpl;
        },
        controller: ['$scope', '$attrs',
          function ($scope, $attrs) {
            $scope.createDateOptionsWatch = function(dateAttr) {
              $scope.$watch(dateAttr, function (value) {
                var date = new Date(value);
                $scope.dateOptions[dateAttr] = date;
                if ($scope[dateAttr]) {
                  $scope[dateAttr] = date;
                }
              }, true);
            }
            $scope.date_change = function () {
              // If we changed the date only, set the time (h,m) on it.
              // This is important in case the previous date was null.
              // This solves the issue when the user set a date and time, cleared the date, and chose another date,
              // and then, the time was cleared too - which is unexpected
              var time = $scope.time;
              if ($scope.ngModel && $scope.time) { // if ngModel is null, that's because the user cleared the date field
                $scope.ngModel.setHours(time.getHours(), time.getMinutes(), 0, 0);
              }
            };

            $scope.time_change = function () {

              if ($scope.ngModel && $scope.time) {
                // convert from ISO format to Date
                if (!($scope.ngModel instanceof Date)) $scope.ngModel = new Date($scope.ngModel);
                $scope.ngModel.setHours($scope.time.getHours(), $scope.time.getMinutes(), 0, 0);
              } else {
                $scope.ngModel = new Date();
              }
            };
            $scope.open = function ($event) {
              $event.preventDefault();
              $event.stopPropagation();
              $scope.innerDateOpened = true;
            };
            $attrs.$observe('dateFormat', function(newDateFormat, oldValue) {
              $scope.dateFormat = newDateFormat;
            });
            $scope.dateOptions = angular.isDefined($scope.dateOptions) ? $scope.dateOptions : {};
            $scope.createDateOptionsWatch('minDate');
            $scope.createDateOptionsWatch('maxDate');
            $scope.dateOptions.dateDisabled = $scope.dateDisabled;
          }
        ],
        link: function (scope, element, attrs, ctrl) {
          var firstTimeAssign = true;

          scope.$watch(function () {
            return scope.ngModel;
          }, function (newTime) {
            var timeElement = document.evaluate(".//*[@ng-model='time']",
              element[0], null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;

            // if a time element is focused, updating its model will cause hours/minutes to be formatted by padding with leading zeros
            if (timeElement && !timeElement.contains(document.activeElement)) {

              if (newTime === null || newTime === '') { // if the newTime is not defined
                if (firstTimeAssign) { // if it's the first time we assign the time value
                  // create a new default time where the hours, minutes, seconds and milliseconds are set to 0.
                  newTime = new Date();
                  newTime.setHours(0, 0, 0, 0);
                } else { // clear the time
                  scope.time = null;
                  return;
                }
              }
              // Update timepicker (watch on ng-model in timepicker does not use object equality),
              // also if the ngModel was not a Date, convert it to date
              newTime = new Date(newTime);

              if (isNaN(newTime.getTime()) === false) {
                scope.time = newTime; // change the time in timepicker
                if (firstTimeAssign) {
                  firstTimeAssign = false;
                }
              }
            }
          }, true);

          scope.$watch(function () {
            return scope.datetimepickerForm.$error;
          }, function (errors) {
            Object.keys(ctrl.$error).forEach(function (error) {
              ctrl.$setValidity(error, true);
            });
            Object.keys(errors).forEach(function (error) {
              ctrl.$setValidity(error, false);
            });
          }, true);

          scope.$watch('dateOpened', function (value) {
            scope.innerDateOpened = value;
          });
          scope.$watch('innerDateOpened', function (value) {
            if (angular.isDefined(scope.dateOpened)) {
              scope.dateOpened = value;
            }
          });
        }
      }
    }
  ]).directive('isolateForm', [function () {
  return {
    restrict: 'A',
    require: '?form',
    link: function (scope, elm, attrs, ctrl) {
      if (!ctrl) {
        return;
      }
      // Do a copy of the controller
      var ctrlCopy = {};
      angular.copy(ctrl, ctrlCopy);

      // Get the parent of the form
      var parent = elm.parent().controller('form');
      // Remove parent link to the controller
      if (!parent) {
        return;
      }
      parent.$removeControl(ctrl);

      // Replace form controller with a "isolated form"
      var isolatedFormCtrl = {
        $setValidity: function (validationToken, isValid, control) {
          ctrlCopy.$setValidity(validationToken, isValid, control);
          parent.$setValidity(validationToken, true, ctrl);
        },
        $setDirty: function () {
          elm.removeClass('ng-pristine').addClass('ng-dirty');
          ctrl.$dirty = true;
          ctrl.$pristine = false;
        }
      };
      angular.extend(ctrl, isolatedFormCtrl);
    }
  };
}]);
<|endoftext|>


<commit_before>function pilihFaskes(tipe) {
  console.log('User choose: ' + tipe);
  window.location.href = tipe + 'index.html';
}
<commit_msg>Added / on the link function<commit_after>function pilihFaskes(tipe) {
  console.log('User choose: ' + tipe);
  window.location.href = tipe + '/index.html';
}
<|endoftext|>


<commit_before>var sakai = sakai || {};

sakai._print = {};
sakai.print = function(){

	var doInit = function(){

		var qs = new Querystring();
		var pagetitle = qs.get("pagetitle","");
		$("#pagetitle").text(pagetitle);

		sdata.Ajax.request({
			url: "/sdata/p/_print/content",
			httpMethod: "GET",
			onSuccess: function(data){
				$(".content").html(data);
				window.print();
			},
			onFail: function(status){
			},
		});
	}

	doInit();

}

sdata.registerForLoad("sakai.print");<commit_msg>SAK-15773<commit_after>var sakai = sakai || {};

sakai._print = {};
sakai.print = function(){

	var doInit = function(){

		var qs = new Querystring();
		var pagetitle = qs.get("pagetitle","");
		$("#pagetitle").text(pagetitle);

		sdata.Ajax.request({
			url: "/sdata/p/_print/content",
			httpMethod: "GET",
			onSuccess: function(data){
				$(".content").html(data);
				window.print();
			},
			onFail: function(status){
			}
		});
	}

	doInit();

}

sdata.registerForLoad("sakai.print");<|endoftext|>