<commit_before>/*
 *  Dateutil
 *  - provides formatting, parsing and other utility functions for dates.
 *
 * Copyright (c) 2009 Borgar Þorsteinsson
 * Licensed under the terms of the MIT (LICENSE.txt) software license.
 *
 */
 (function(__global__){

  var SECOND_SIZE = 1000;
  var MINUTE_SIZE = SECOND_SIZE * 60;
  var HOUR_SIZE   = MINUTE_SIZE * 60;
  var DAY_SIZE    = HOUR_SIZE * 24;
  var WEEK_SIZE   = DAY_SIZE * 7;
  var MONTH_SIZE  = DAY_SIZE * 30.436875; // average month size
  var YEAR_SIZE   = DAY_SIZE * 365.2425;  // average year size

  var month_names = 'January February March April May June July August September October November December'.split(' ');
  var day_names = 'Sunday Monday Tuesday Wednesday Thursday Friday Saturday'.split(' ');

  var method_map = {
    'yr': 'FullYear',
    'year': 'FullYear',
    'years': 'FullYear',
    'mn': 'Month',
    'month': 'Month',
    'months': 'Month',
    'day': 'Date',
    'days': 'Date',
    'date': 'Date',
    'hr': 'Hours',
    'hour': 'Hours',
    'hours': 'Hours',
    'min': 'Minutes',
    'minute': 'Minutes',
    'minutes': 'Minutes',
    'sec': 'Seconds',
    'second': 'Seconds',
    'seconds': 'Seconds',
    'ms': 'Milliseconds',
    'millisecond': 'Milliseconds',
    'milliseconds': 'Milliseconds',
  };

  // *****************************************
  // *** *** *** formats & parsers *** *** ***
  // *****************************************

  var date_parsers = __global__._parsers = {

    // year + month + day + time
    // -- currently doesn't really support fractions on anything other than seconds >> FIXME
    // -- does not support timezones other than Zulu
    date_and_time: {
      test: /^[+-]?\d{4,6}(?:(?:\-\d\d){1,2}|\d{4})[T ](?:\d\d)(?::?\d\d){0,2}(?:[\.,]\d+)?(?:Z|[+-]\d\d(:?\d\d)?)?$/,
      size: 1,
      parse: function ( str ) {
        var b = str.split( /[T ]/ );
        var date = date_parsers.date.parse( b[0] );
        var m = b[1].replace( /:/g, '' )
                      .match( /^(\d\d)(\d\d)?(\d\d)?(?:[.,](\d+))?([+-](?:\d\d){1,2})?/ );
        // TODO: timezone (I have no need for this feature yet)
        // if ( m[5] ) { var zone = m[5] || '0000'; }
        var fs = 0, t = date.getTime() +
                parseInt( m[1], 10 ) * HOUR_SIZE +
                parseInt( m[2] || '0', 10 ) * MINUTE_SIZE +
                parseInt( m[3] || '0', 10 ) * SECOND_SIZE;
             if ( m[3] ) { fs = SECOND_SIZE; }
        else if ( m[2] ) { fs = MINUTE_SIZE; }
        else if ( m[1] ) { fs = HOUR_SIZE; }
        t += parseFloat( '0.' + ( m[4] || '0' ) ) * fs;
        date.setTime( t );
        date.size = 0;
        return date;
      }
    },

    // year + month + day
    date: {
      test: /^[+-]?\d{4,6}(?:-\d\d-\d\d|-?\d\d\d\d)$/,
      size: DAY_SIZE,
      parse: function ( str ) {
        var s = str.replace( /\D/g, '' );
        var d = parseInt( s.substr( s.length -2 ), 10 );
        var m = parseInt( s.substr( s.length -4, 2 ), 10 );
        var y = parseInt( s.substring( 0, s.length -4 ), 10 );
        d = new Date( y, m - 1, d );
        d.size = DAY_SIZE;
        return d;
      }
    },

    // year + month
    year_and_month: {
      test: /^[+-]?\d{4,6}[\/-](?:0[1-9]|1[012])$/,
      size: MONTH_SIZE,
      parse: function ( str ) {
        var b = str.split( /[\/-]/ );
        d = new Date( parseInt( b[0], 10 ), parseInt( b[1], 10 ) - 1, 1 );
        d.size = __global__.daysInMonth( d ) * DAY_SIZE;
        return d;
      }
    },

    // year
    year: {
      test: /^[+-]?\d{4,6}$/,
      size: YEAR_SIZE,
      parse: function ( str ) {
        var d = new Date( parseInt( str, 10 ), 0, 1 );
        d.size = DAY_SIZE * ( __global__.isLeapYear( d ) ? 366 : 365 );
        return d;
      }
    },

    // year + iso week + [day]
    year_and_week: {
      test: /^[+-]?\d{4,6}\-?[Ww]\d\d(?:\-?\d)?$/,
      size: WEEK_SIZE,
      parse: function ( str ) {
        var s = str.toLowerCase().replace( /[^w\d]/g, '' ).split('w');
        var d = new Date( parseInt( s[0], 10 ), 0, 3 );  // Jan 3
        d.setUTCDate( 3 - d.getUTCDay() +
                      ( parseInt( s[1].substr( 0, 2 ), 10 ) - 1 ) * 7 +
                      parseInt( s[1].substr( 2, 1 ) || '1', 10 ) );
        d.size = WEEK_SIZE;
        return d;
      }
    },

    // year + day-of-year
    // -- we don't allow the short form yyyyddd because of ambiguity with yyyymmdd
    // -- 5 letter years would clash with cal-dates: yyyyyddd ~ yyyymmdd
    year_and_ordinal: {
      test: /^[+-]?\d{4,6}\-[0-3]\d\d$/,
      size: DAY_SIZE,
      parse: function ( str ) {
        var d = new Date(0);
        var b = str.split('-');
        d.setUTCFullYear( parseInt( b[0], 10 ) );
        d.setDate( parseInt( b[1], 10 ) );
        d.size = DAY_SIZE;
        return d;
      }
    },

    // year + quarter
    year_and_quarter: {
      test: /^[+-]?\d{4,6}\-?[Qq][1-4]$/,
      size: YEAR_SIZE / 4,
      parse: function ( str ) {
        var d = new Date(0);
        var b = str.split(/\-?[Qq]/);
        d.setUTCFullYear( parseInt( b[0], 10 ) );
        d.setUTCMonth( ( parseInt( b[1], 10 ) - 1 ) * 3 );
        d.size = DAY_SIZE;
        return d;
      }
    }

  };

  var date_formatters = __global__._formats = {
    // Lowercase Ante meridiem and Post meridiem
    a: function (d) { return d.getUTCHours() >= 12 ? 'pm' : 'am'; },
    // Uppercase Ante meridiem and Post meridiem
    A: function (d) { return d.getUTCHours() >= 12 ? 'PM' : 'AM'; },
    // ISO 8601 date
    c: function (d) { return __global__.format( d, 'Y-m-d\\TH:i:s.' ) + this.u(d,3) + 'Z'; },
    // Day of the month, 2 digits with leading zeros
    d: function (d) { return pad( d.getUTCDate() ); },
    // A textual representation of a day, three letters
    D: function (d) { return __global__._( day_names[ d.getUTCDay() ].substr( 0, 3 ) ); },
    // Time zone identifier
    e: function (d) { return 'UTC'; },
    // A full textual representation of a month
    F: function (d) { return __global__._( month_names[ d.getUTCMonth() ] ); },
    // 12-hour format of an hour without leading zeros
    g: function (d) { return d.getUTCHours() % 12 || 12; },
    // 24-hour format of an hour without leading zeros
    G: function (d) { return d.getUTCHours(); },
    // 12-hour format of an hour with leading zeros
    h: function (d) { return pad( d.getUTCHours() % 12 || 12 ); },
    // 24-hour format of an hour with leading zeros
    H: function (d) { return pad( d.getUTCHours() ); },
    // Minutes with leading zeros
    i: function (d) { return pad( d.getUTCMinutes() ); },
    // Day of the month without leading zeros
    j: function (d) { return d.getUTCDate(); },
    // A full textual representation of the day of the week
    l: function (d) { return __global__._( day_names[ d.getUTCDay() ] ); },
    // Whether it's a leap year (0 = yes, 1 = no)
    L: function (d) { return __global__.isLeapYear( d ) * 1; },
    // Numeric representation of a month, with leading zeros
    m: function (d) { return pad( d.getUTCMonth() + 1 ); },
    // A short textual representation of a month, three letters
    M: function (d) { return __global__._( month_names[ d.getUTCMonth() ].substr( 0, 3 ) ); },
    // Numeric representation of a month, without leading zeros
    n: function (d) { return d.getUTCMonth() + 1; },
    // ISO-8601 numeric representation of the day of the week
    N: function (d) { return d.getUTCDay() || 7; },
    // ISO-8601 year number
    o: function (d) { return pad( __global__.isocalendar(d)[0], 4 ); },
    // Time zone designator
    O: function (d) { return '+0000'; },
    // Time zone difference
    P: function (d) { return '+00:00'; },
    // Quarter of the year
    q: function (d) { return ~~( d.getUTCMonth() / 3 ) + 1; },
    // RFC 2822 formatted date
    r: function (d) { return __global__.format( d, 'D, d M Y H:i:s O' ); },
    // Seconds, with leading zeros
    s: function (d) { return pad( d.getUTCSeconds() ); },
    // English ordinal suffix for the day of the month, 2 characters
    S: function (d) {
      var a = d.getUTCDate() % 10, b = d.getUTCDate() % 100;
      return (a == 1) && (b !== 11) && 'st' ||
             (a == 2) && (b !== 12) && 'nd' ||
             (a == 3) && (b !== 13) && 'rd' || 'th';
    },
    // Number of days in the given month
    t: function (d) { return __global__.daysInMonth( d ); },
    // Time zone abbreviation
    T: function (d) { return 'UTC'; },
    // Microseconds
    u: function (d, l) { return pad( d.getUTCMilliseconds(), l || 6 ); },
    // Seconds since the Unix Epoch
    U: function (d) { return ~~( d / 1000 ); },
    // Numeric representation of the day of the week
    w: function (d) { return d.getUTCDay(); },
    // ISO-8601 week number of year, weeks starting on Monday
    W: function (d) { return pad( __global__.isocalendar(d)[1] ); },
    // A short numeric representation of a year, 2 digits
    y: function (d) { return (d.getUTCFullYear() + '').substr(2); },
    // A full numeric representation of a year, 4 digits
    Y: function (d) { return d.getUTCFullYear(); },
    // The day of the year (starting from 0)
    z: function (d) { return Math.floor( ( d - (new Date(d.getUTCFullYear(), 0, 1)) ) / DAY_SIZE ); },
  };

  // **************************************
  // *** *** *** utility methods *** *** ***
  // **************************************

  function pad ( n, l ) {
    var s = '0000000000' + n;
    return s.substring( s.length -( l || 2 ) );
  }

  // **************************************
  // *** *** *** module methods *** *** ***
  // **************************************

  // is a given year a leap year
  __global__.isLeapYear = function ( y ) {
    if ( y instanceof Date ) { y = y.getUTCFullYear(); }
    return (( y % 4 == 0 ) && ( y % 100 != 0 )) || ( y % 400 == 0 );
  };

  // return the number of days in a date's month
  __global__.daysInMonth = function ( dt ) {
    return 32 - new Date( dt.getUTCFullYear(), dt.getUTCMonth(), 32 ).getUTCDate();
  };

  // return a 3-tuple, (ISO year, ISO week number, ISO weekday).
  __global__.isocalendar = function ( dt ) {
    var d = dt.getUTCDay();
    var t = new Date( dt.valueOf() );
    t.setDate( t.getDate() - ((d + 6) % 7) + 3 );
    var iso_year = t.getUTCFullYear();
    var w = Math.floor( (t.getTime() - new Date(iso_year, 0, 1, -6)) / 86400000 );
    return [ iso_year, 1+Math.floor(w/7), d||7 ];
  };

  // Allow setting multiple properties at once using object notation:
  // `mydate.set({ hour: 8, minute: 12, second: 0 });`
  __global__.set = function ( dt, values ) {
    if ( typeof values === 'object' ) {
      for ( var key in values ) if ( key in method_map ) {
        dt[ 'setUTC' + method_map[ key ] ]( values[ key ] );
      }
    }
    return dt;
  };

  // parse a date
  __global__.parse = function ( str ) {
    var d;
    if ( typeof str !== 'string' ) {
      throw new TypeError( "dateutil parser can't parse non-strings." );
    }
    for ( var dtype in date_parsers ) {
      if ( date_parsers[dtype].test( str ) ) {
        d = date_parsers[ dtype ].parse( str );
        d.type = dtype;
        d.size = d.size || 0;
        break;
      }
    }
    // default parser supports RFC and a few more, or returns an "invalid date"
    if ( !d ) {
      d = new Date( str );
      d.size = 0;
      d.type = 'unknown_date';
    }
    return d;
  };

  // format a date to string
  __global__.format = function ( d, fmt ) {
    d = d || new Date();
    for ( var r=[], c, l=fmt.length, i=0; i<l; i++ ) {
      c = fmt.charAt( i );
      // format characters
      if ( c !== '\\' ) {
        r.push( (c in date_formatters) ? date_formatters[ c ]( d ) : c );
      }
      // escaped characters & unreconized characters
      else {
        c = i < fmt.length ? fmt.charAt( ++i ) : c;
        r.push( c );
      }
    }
    return r.join( '' );
  };

  // return a Date object for the current date (0 time)
  __global__.today = function () {
    return __global__.set( new Date(), {
      hour: 0, minute: 0, second: 0, millisecond: 0
    });
  };

  // return timestamp for the moment
  __global__.now = (typeof Date.now === 'function')
            ? Date.now
            : function () { return +new Date(); };

  // translation hook
  __global__._ = function ( s ) { return s; };

})(
  (typeof module !== 'undefined' && module.exports)
    ? module.exports
    : (this.dateutil = {})
);<commit_msg>Fixed a parsing problem with negative year ordinal dates.<commit_after>/*
 *  Dateutil
 *  - provides formatting, parsing and other utility functions for dates.
 *
 * Copyright (c) 2009 Borgar Þorsteinsson
 * Licensed under the terms of the MIT (LICENSE.txt) software license.
 *
 */
 (function(__global__){

  var SECOND_SIZE = 1000;
  var MINUTE_SIZE = SECOND_SIZE * 60;
  var HOUR_SIZE   = MINUTE_SIZE * 60;
  var DAY_SIZE    = HOUR_SIZE * 24;
  var WEEK_SIZE   = DAY_SIZE * 7;
  var MONTH_SIZE  = DAY_SIZE * 30.436875; // average month size
  var YEAR_SIZE   = DAY_SIZE * 365.2425;  // average year size

  var month_names = 'January February March April May June July August September October November December'.split(' ');
  var day_names = 'Sunday Monday Tuesday Wednesday Thursday Friday Saturday'.split(' ');

  var method_map = {
    'yr': 'FullYear',
    'year': 'FullYear',
    'years': 'FullYear',
    'mn': 'Month',
    'month': 'Month',
    'months': 'Month',
    'day': 'Date',
    'days': 'Date',
    'date': 'Date',
    'hr': 'Hours',
    'hour': 'Hours',
    'hours': 'Hours',
    'min': 'Minutes',
    'minute': 'Minutes',
    'minutes': 'Minutes',
    'sec': 'Seconds',
    'second': 'Seconds',
    'seconds': 'Seconds',
    'ms': 'Milliseconds',
    'millisecond': 'Milliseconds',
    'milliseconds': 'Milliseconds',
  };

  // *****************************************
  // *** *** *** formats & parsers *** *** ***
  // *****************************************

  var date_parsers = __global__._parsers = {

    // year + month + day + time
    // -- currently doesn't really support fractions on anything other than seconds >> FIXME
    // -- does not support timezones other than Zulu
    date_and_time: {
      test: /^[+-]?\d{4,6}(?:(?:\-\d\d){1,2}|\d{4})[T ](?:\d\d)(?::?\d\d){0,2}(?:[\.,]\d+)?(?:Z|[+-]\d\d(:?\d\d)?)?$/,
      size: 1,
      parse: function ( str ) {
        var b = str.split( /[T ]/ );
        var date = date_parsers.date.parse( b[0] );
        var m = b[1].replace( /:/g, '' )
                      .match( /^(\d\d)(\d\d)?(\d\d)?(?:[.,](\d+))?([+-](?:\d\d){1,2})?/ );
        // TODO: timezone (I have no need for this feature yet)
        // if ( m[5] ) { var zone = m[5] || '0000'; }
        var fs = 0, t = date.getTime() +
                parseInt( m[1], 10 ) * HOUR_SIZE +
                parseInt( m[2] || '0', 10 ) * MINUTE_SIZE +
                parseInt( m[3] || '0', 10 ) * SECOND_SIZE;
             if ( m[3] ) { fs = SECOND_SIZE; }
        else if ( m[2] ) { fs = MINUTE_SIZE; }
        else if ( m[1] ) { fs = HOUR_SIZE; }
        t += parseFloat( '0.' + ( m[4] || '0' ) ) * fs;
        date.setTime( t );
        date.size = 0;
        return date;
      }
    },

    // year + month + day
    date: {
      test: /^[+-]?\d{4,6}(?:-\d\d-\d\d|-?\d\d\d\d)$/,
      size: DAY_SIZE,
      parse: function ( str ) {
        var s = str.replace( /\D/g, '' );
        var d = parseInt( s.substr( s.length -2 ), 10 );
        var m = parseInt( s.substr( s.length -4, 2 ), 10 );
        var y = parseInt( s.substring( 0, s.length -4 ), 10 );
        d = new Date( y, m - 1, d );
        d.size = DAY_SIZE;
        return d;
      }
    },

    // year + month
    year_and_month: {
      test: /^[+-]?\d{4,6}[\/-](?:0[1-9]|1[012])$/,
      size: MONTH_SIZE,
      parse: function ( str ) {
        var b = str.split( /[\/-]/ );
        d = new Date( parseInt( b[0], 10 ), parseInt( b[1], 10 ) - 1, 1 );
        d.size = __global__.daysInMonth( d ) * DAY_SIZE;
        return d;
      }
    },

    // year
    year: {
      test: /^[+-]?\d{4,6}$/,
      size: YEAR_SIZE,
      parse: function ( str ) {
        var d = new Date( parseInt( str, 10 ), 0, 1 );
        d.size = DAY_SIZE * ( __global__.isLeapYear( d ) ? 366 : 365 );
        return d;
      }
    },

    // year + iso week + [day]
    year_and_week: {
      test: /^[+-]?\d{4,6}\-?[Ww]\d\d(?:\-?\d)?$/,
      size: WEEK_SIZE,
      parse: function ( str ) {
        var s = str.toLowerCase().replace( /[^w\d]/g, '' ).split('w');
        var d = new Date( parseInt( s[0], 10 ), 0, 3 );  // Jan 3
        d.setUTCDate( 3 - d.getUTCDay() +
                      ( parseInt( s[1].substr( 0, 2 ), 10 ) - 1 ) * 7 +
                      parseInt( s[1].substr( 2, 1 ) || '1', 10 ) );
        d.size = WEEK_SIZE;
        return d;
      }
    },

    // year + day-of-year
    // -- we don't allow the short form yyyyddd because of ambiguity with yyyymmdd
    // -- 5 letter years would clash with cal-dates: yyyyyddd ~ yyyymmdd
    year_and_ordinal: {
      test: /^[+-]?\d{4,6}\-[0-3]\d\d$/,
      size: DAY_SIZE,
      parse: function ( str ) {
        var d = new Date(0);
        d.setUTCFullYear( parseInt( str.substr(0,str.length-4), 10 ) );
        d.setDate( parseInt( str.substr(str.length-3), 10 ) );
        d.size = DAY_SIZE;
        return d;
      }
    },

    // year + quarter
    year_and_quarter: {
      test: /^[+-]?\d{4,6}\-?[Qq][1-4]$/,
      size: YEAR_SIZE / 4,
      parse: function ( str ) {
        var d = new Date(0);
        var b = str.split(/\-?[Qq]/);
        d.setUTCFullYear( parseInt( b[0], 10 ) );
        d.setUTCMonth( ( parseInt( b[1], 10 ) - 1 ) * 3 );
        d.size = DAY_SIZE;
        return d;
      }
    }

  };

  var date_formatters = __global__._formats = {
    // Lowercase Ante meridiem and Post meridiem
    a: function (d) { return d.getUTCHours() >= 12 ? 'pm' : 'am'; },
    // Uppercase Ante meridiem and Post meridiem
    A: function (d) { return d.getUTCHours() >= 12 ? 'PM' : 'AM'; },
    // ISO 8601 date
    c: function (d) { return __global__.format( d, 'Y-m-d\\TH:i:s.' ) + this.u(d,3) + 'Z'; },
    // Day of the month, 2 digits with leading zeros
    d: function (d) { return pad( d.getUTCDate() ); },
    // A textual representation of a day, three letters
    D: function (d) { return __global__._( day_names[ d.getUTCDay() ].substr( 0, 3 ) ); },
    // Time zone identifier
    e: function (d) { return 'UTC'; },
    // A full textual representation of a month
    F: function (d) { return __global__._( month_names[ d.getUTCMonth() ] ); },
    // 12-hour format of an hour without leading zeros
    g: function (d) { return d.getUTCHours() % 12 || 12; },
    // 24-hour format of an hour without leading zeros
    G: function (d) { return d.getUTCHours(); },
    // 12-hour format of an hour with leading zeros
    h: function (d) { return pad( d.getUTCHours() % 12 || 12 ); },
    // 24-hour format of an hour with leading zeros
    H: function (d) { return pad( d.getUTCHours() ); },
    // Minutes with leading zeros
    i: function (d) { return pad( d.getUTCMinutes() ); },
    // Day of the month without leading zeros
    j: function (d) { return d.getUTCDate(); },
    // A full textual representation of the day of the week
    l: function (d) { return __global__._( day_names[ d.getUTCDay() ] ); },
    // Whether it's a leap year (0 = yes, 1 = no)
    L: function (d) { return __global__.isLeapYear( d ) * 1; },
    // Numeric representation of a month, with leading zeros
    m: function (d) { return pad( d.getUTCMonth() + 1 ); },
    // A short textual representation of a month, three letters
    M: function (d) { return __global__._( month_names[ d.getUTCMonth() ].substr( 0, 3 ) ); },
    // Numeric representation of a month, without leading zeros
    n: function (d) { return d.getUTCMonth() + 1; },
    // ISO-8601 numeric representation of the day of the week
    N: function (d) { return d.getUTCDay() || 7; },
    // ISO-8601 year number
    o: function (d) { return pad( __global__.isocalendar(d)[0], 4 ); },
    // Time zone designator
    O: function (d) { return '+0000'; },
    // Time zone difference
    P: function (d) { return '+00:00'; },
    // Quarter of the year
    q: function (d) { return ~~( d.getUTCMonth() / 3 ) + 1; },
    // RFC 2822 formatted date
    r: function (d) { return __global__.format( d, 'D, d M Y H:i:s O' ); },
    // Seconds, with leading zeros
    s: function (d) { return pad( d.getUTCSeconds() ); },
    // English ordinal suffix for the day of the month, 2 characters
    S: function (d) {
      var a = d.getUTCDate() % 10, b = d.getUTCDate() % 100;
      return (a == 1) && (b !== 11) && 'st' ||
             (a == 2) && (b !== 12) && 'nd' ||
             (a == 3) && (b !== 13) && 'rd' || 'th';
    },
    // Number of days in the given month
    t: function (d) { return __global__.daysInMonth( d ); },
    // Time zone abbreviation
    T: function (d) { return 'UTC'; },
    // Microseconds
    u: function (d, l) { return pad( d.getUTCMilliseconds(), l || 6 ); },
    // Seconds since the Unix Epoch
    U: function (d) { return ~~( d / 1000 ); },
    // Numeric representation of the day of the week
    w: function (d) { return d.getUTCDay(); },
    // ISO-8601 week number of year, weeks starting on Monday
    W: function (d) { return pad( __global__.isocalendar(d)[1] ); },
    // A short numeric representation of a year, 2 digits
    y: function (d) { return (d.getUTCFullYear() + '').substr(2); },
    // A full numeric representation of a year, 4 digits
    Y: function (d) { return d.getUTCFullYear(); },
    // The day of the year (starting from 0)
    z: function (d) { return Math.floor( ( d - (new Date(d.getUTCFullYear(), 0, 1)) ) / DAY_SIZE ); },
  };

  // **************************************
  // *** *** *** utility methods *** *** ***
  // **************************************

  function pad ( n, l ) {
    var s = '0000000000' + n;
    return s.substring( s.length -( l || 2 ) );
  }

  // **************************************
  // *** *** *** module methods *** *** ***
  // **************************************

  // is a given year a leap year
  __global__.isLeapYear = function ( y ) {
    if ( y instanceof Date ) { y = y.getUTCFullYear(); }
    return (( y % 4 == 0 ) && ( y % 100 != 0 )) || ( y % 400 == 0 );
  };

  // return the number of days in a date's month
  __global__.daysInMonth = function ( dt ) {
    return 32 - new Date( dt.getUTCFullYear(), dt.getUTCMonth(), 32 ).getUTCDate();
  };

  // return a 3-tuple, (ISO year, ISO week number, ISO weekday).
  __global__.isocalendar = function ( dt ) {
    var d = dt.getUTCDay();
    var t = new Date( dt.valueOf() );
    t.setDate( t.getDate() - ((d + 6) % 7) + 3 );
    var iso_year = t.getUTCFullYear();
    var w = Math.floor( (t.getTime() - new Date(iso_year, 0, 1, -6)) / 86400000 );
    return [ iso_year, 1+Math.floor(w/7), d||7 ];
  };

  // Allow setting multiple properties at once using object notation:
  // `mydate.set({ hour: 8, minute: 12, second: 0 });`
  __global__.set = function ( dt, values ) {
    if ( typeof values === 'object' ) {
      for ( var key in values ) if ( key in method_map ) {
        dt[ 'setUTC' + method_map[ key ] ]( values[ key ] );
      }
    }
    return dt;
  };

  // parse a date
  __global__.parse = function ( str ) {
    var d;
    if ( typeof str !== 'string' ) {
      throw new TypeError( "dateutil parser can't parse non-strings." );
    }
    for ( var dtype in date_parsers ) {
      if ( date_parsers[dtype].test( str ) ) {
        d = date_parsers[ dtype ].parse( str );
        d.type = dtype;
        d.size = d.size || 0;
        break;
      }
    }
    // default parser supports RFC and a few more, or returns an "invalid date"
    if ( !d ) {
      d = new Date( str );
      d.size = 0;
      d.type = 'unknown_date';
    }
    return d;
  };

  // format a date to string
  __global__.format = function ( d, fmt ) {
    d = d || new Date();
    for ( var r=[], c, l=fmt.length, i=0; i<l; i++ ) {
      c = fmt.charAt( i );
      // format characters
      if ( c !== '\\' ) {
        r.push( (c in date_formatters) ? date_formatters[ c ]( d ) : c );
      }
      // escaped characters & unreconized characters
      else {
        c = i < fmt.length ? fmt.charAt( ++i ) : c;
        r.push( c );
      }
    }
    return r.join( '' );
  };

  // return a Date object for the current date (0 time)
  __global__.today = function () {
    return __global__.set( new Date(), {
      hour: 0, minute: 0, second: 0, millisecond: 0
    });
  };

  // return timestamp for the moment
  __global__.now = (typeof Date.now === 'function')
            ? Date.now
            : function () { return +new Date(); };

  // translation hook
  __global__._ = function ( s ) { return s; };

})(
  (typeof module !== 'undefined' && module.exports)
    ? module.exports
    : (this.dateutil = {})
);<|endoftext|>


<commit_before>import debug from "debug";
import data from "../../data/schedule";
import React from "react";
import { App } from "./components/app";

const log = debug("app:app");

const OE_GUESSTIMATE = 180;

const initialState = {
    main: {
        view: "next-up"
    },
    time: {
        today: new Date(new Date().getFullYear(), new Date().getMonth(), new Date().getDate()),
        now: new Date()
    },
    update: {
        available: false
    }
};

let currentState = initialState;

function getState() {
    return { ...currentState };
}

function updateState(branch, patch) {
    if ("." === branch) {
        currentState = { ...currentState, ...patch };
    } else {
        currentState = { ...currentState, [branch]: { ...currentState[branch], ...patch } };
    }

    return true;
}

function renderMain(props) {
    React.render(
        React.createElement(App, props),
        document.querySelector("body")
    );
}

function normaliseSessionData(conference) {
    let days = Object.keys(data.days).map((d, did) => {
        return { id: did, date: new Date(d), tracks: data.days[d].tracks };
    });

    let tracks = days.map(day => {
        return Object.keys(day.tracks).map(t => ({ name: t, day: day.id, sessions: day.tracks[t] }));
    }).
    reduce((a, ts) => a.concat(ts), []).
    map((t, tid) => ({ id: tid, ...t }));

    let sessions = tracks.map(track => {
        return track.sessions.map(s => ({ ...s, track: track.id, start: new Date(days[track.day].date).setHours(...s.start.split(":")) }));
    }).
    reduce((a, ts) => a.concat(ts), []).
    map((s, sid) => ({ id: sid, ...s }));

    return { ...conference, days, tracks, sessions };
}

function updateUpcomingSessions(state) {
    const { sessions, time: { now } } = state;

    let upcoming = sessions.filter(s => now <= s.start).sort((a, b) => a.start - b.start).map(s => s.id);

    return updateState("upcoming", { sessions: upcoming });
}

function updateCurrentSessions(state) {
    const { sessions, time: { now } } = state;

    let current = sessions.filter(s => {
        let duration = (s.hasOwnProperty("duration") ? s.duration : OE_GUESSTIMATE) * 60 * 1000;
        let sessionEnd = Number(s.start) + duration;
        return now >= s.start && Number(now) <= sessionEnd;
    }).
    sort((a, b) => a.start - b.start).
    map(s => s.id);

    return updateState("current", { sessions: current });
}

function updateTimer() {
    return updateState("time", { now: new Date() });
}

export function start() {
    // Wrapped update so state updates re-render the app
    let wrappedUpdate = (...update) => {
        if (updateState(...update)) {
            renderApp();
        }
    };

    let renderApp = () => {
        renderMain({ getState, updateState: wrappedUpdate });
    };

    let tick = () => {
        let updates = [
            updateTimer(),
            updateUpcomingSessions(getState()),
            updateCurrentSessions(getState())
        ];

        if (updates.some(u => u)) {
            renderApp();
        }

        setTimeout(tick, 1000);
    };

    // Subscribe to AppCache events so we can show a notice when an update is available
    window.applicationCache.addEventListener(
        "updateready",
        () => updateState("update", { available: true }),
        false);

    // initial state
    updateState(".", { ...initialState, ...normaliseSessionData(data) });

    // Start ticking
    tick();
}
<commit_msg>Refactor fix unnormalised properties in days and tracks<commit_after>import debug from "debug";
import data from "../../data/schedule";
import React from "react";
import { App } from "./components/app";

const log = debug("app:app");

const OE_GUESSTIMATE = 180;

const initialState = {
    main: {
        view: "next-up"
    },
    time: {
        today: new Date(new Date().getFullYear(), new Date().getMonth(), new Date().getDate()),
        now: new Date()
    },
    update: {
        available: false
    }
};

let currentState = initialState;

function getState() {
    return { ...currentState };
}

function updateState(branch, patch) {
    if ("." === branch) {
        currentState = { ...currentState, ...patch };
    } else {
        currentState = { ...currentState, [branch]: { ...currentState[branch], ...patch } };
    }

    return true;
}

function renderMain(props) {
    React.render(
        React.createElement(App, props),
        document.querySelector("body")
    );
}

function normaliseSessionData(conference) {
    let days = Object.keys(conference.days).map((d, did) => {
        return { id: did, date: new Date(d), tracks: data.days[d].tracks };
    }).
    map(day => {
        return {
            ...day,
            tracks: Object.keys(day.tracks).map(t => ({ name: t, day: day.id, sessions: day.tracks[t] }))
        };
    });

    let tracks = days.map(d => d.tracks).
    reduce((a, ts) => a.concat(ts), []).
    map((t, tid) => ({ id: tid, ...t }));

    let sessions = tracks.map(track => {
        return track.sessions.map(s => ({ ...s, track: track.id, start: new Date(days[track.day].date).setHours(...s.start.split(":")) }));
    }).
    reduce((a, ts) => a.concat(ts), []).
    map((s, sid) => ({ id: sid, ...s }));

    // Drop sessions from tracks
    tracks = tracks.map(t => {
        let { sessions, ...rest } = t;
        return rest;
    });

    // Drop tracks from days
    days = days.map(d => {
        let { tracks, ...rest } = d;
        return rest;
    });

    return { ...conference, sessions, tracks, days };
}

function updateUpcomingSessions(state) {
    const { sessions, time: { now } } = state;

    let upcoming = sessions.filter(s => now <= s.start).sort((a, b) => a.start - b.start).map(s => s.id);

    return updateState("upcoming", { sessions: upcoming });
}

function updateCurrentSessions(state) {
    const { sessions, time: { now } } = state;

    let current = sessions.filter(s => {
        let duration = (s.hasOwnProperty("duration") ? s.duration : OE_GUESSTIMATE) * 60 * 1000;
        let sessionEnd = Number(s.start) + duration;
        return now >= s.start && Number(now) <= sessionEnd;
    }).
    sort((a, b) => a.start - b.start).
    map(s => s.id);

    return updateState("current", { sessions: current });
}

function updateTimer() {
    return updateState("time", { now: new Date() });
}

export function start() {
    // Wrapped update so state updates re-render the app
    let wrappedUpdate = (...update) => {
        if (updateState(...update)) {
            renderApp();
        }
    };

    let renderApp = () => {
        renderMain({ getState, updateState: wrappedUpdate });
    };

    let tick = () => {
        let updates = [
            updateTimer(),
            updateUpcomingSessions(getState()),
            updateCurrentSessions(getState())
        ];

        if (updates.some(u => u)) {
            renderApp();
        }

        setTimeout(tick, 1000);
    };

    // Subscribe to AppCache events so we can show a notice when an update is available
    window.applicationCache.addEventListener(
        "updateready",
        () => updateState("update", { available: true }),
        false);

    // initial state
    updateState(".", { ...initialState, ...normaliseSessionData(data) });

    // Start ticking
    tick();
}
<|endoftext|>


<commit_before>'use strict';

describe('services module', function() {

  beforeEach(module('freeSamplerApp.services'));

  describe('sha256', function() {
    var sha256;

    beforeEach(inject(function(_sha256_) {
      sha256 = _sha256_;
    }));

    it('should hash a string correctly', function() {
      expect(sha256('foo'))
        .toBe('2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae');
    });

  });

  describe('getSample', function() {
    var getSample;

    beforeEach(inject(function(_getSample_) {
      getSample = _getSample_;
    }));

    it('should sample 1 item from 1000 items correctly', function() {
      expect(getSample('0', 1000, 1)).toBe(905);
    });

  });

  describe('getSamples', function() {
    var getSamples;

    beforeEach(inject(function(_getSamples_) {
      getSamples = _getSamples_;
    }));

    it('should sample 3 items from 1000 correctly', function() {
      expect(getSamples('abcde', 1000, 3))
        .toEqual([247, 427, 157]);
    });

  });

  describe('getSamplesUnique', function() {
    var getSamplesUnique;

    beforeEach(inject(function(_getSamplesUnique_) {
      getSamplesUnique = _getSamplesUnique_;
    }));

    it('should handle duplicates', function() {
      expect(getSamplesUnique('abcde', 5, 2))
        .toEqual([[2, 3], [2, 2, 2, 3]]);
    });

    it('should handle a sample size larger than the total', function() {
      expect(getSamplesUnique('abcde', 3, 4))
        .toEqual([[2, 3, 1], [2, 3, 2, 1]]);
    });

  });

  describe('rivest-sampler-tests', function() {
    var getSamples, tests;

    beforeEach(inject(function($window, _getSamples_) {
      var json;
      getSamples = _getSamples_;
      json = $window.__html__['bower_components/rivest-sampler-tests/tests.json'];
      tests = angular.fromJson(json);
    }));

    it('should have JSON test cases', function() {
      expect(tests.length).toBeGreaterThan(0);
    });

    it('should pass its JSON test cases', function() {
      var test, testData;
      for (var i = 0,  len = tests.length; i < len; i++) {
        test = tests[i];
        testData = test.data;

        expect(getSamples(testData.seed, testData.total, testData.count))
          .toEqual(test.expected);
      }

    });

  });

});
<commit_msg>Enhance unique sampling tests.<commit_after>'use strict';

describe('services module', function() {

  beforeEach(module('freeSamplerApp.services'));

  describe('sha256', function() {
    var sha256;

    beforeEach(inject(function(_sha256_) {
      sha256 = _sha256_;
    }));

    it('should hash a string correctly', function() {
      expect(sha256('foo'))
        .toBe('2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae');
    });

  });

  describe('getSample', function() {
    var getSample;

    beforeEach(inject(function(_getSample_) {
      getSample = _getSample_;
    }));

    it('should sample 1 item from 1000 items correctly', function() {
      expect(getSample('0', 1000, 1)).toBe(905);
    });

  });

  describe('getSamples', function() {
    var getSamples;

    beforeEach(inject(function(_getSamples_) {
      getSamples = _getSamples_;
    }));

    it('should sample 3 items from 1000 correctly', function() {
      expect(getSamples('abcde', 1000, 3))
        .toEqual([247, 427, 157]);
    });

  });

  describe('getSamplesUnique', function() {
    var getSamples,
        getSamplesUnique;

    beforeEach(inject(function(_getSamples_, _getSamplesUnique_) {
      getSamples = _getSamples_;
      getSamplesUnique = _getSamplesUnique_;
    }));

    it('should handle duplicates', function() {
      expect(getSamplesUnique('abcde', 5, 2))
        .toEqual([[2, 3], [2, 2, 2, 3]]);
      // Check the raw array against getSamples().
      expect(getSamples('abcde', 5, 4))
        .toEqual([2, 2, 2, 3]);
    });

    it('should handle a sample size larger than the total', function() {
      expect(getSamplesUnique('abcde', 3, 4))
        .toEqual([[2, 3, 1], [2, 3, 2, 1]]);
      // Check the raw array against getSamples().
      expect(getSamples('abcde', 3, 4))
        .toEqual([2, 3, 2, 1]);
    });

  });

  describe('rivest-sampler-tests', function() {
    var getSamples, tests;

    beforeEach(inject(function($window, _getSamples_) {
      var json;
      getSamples = _getSamples_;
      json = $window.__html__['bower_components/rivest-sampler-tests/tests.json'];
      tests = angular.fromJson(json);
    }));

    it('should have JSON test cases', function() {
      expect(tests.length).toBeGreaterThan(0);
    });

    it('should pass its JSON test cases', function() {
      var test, testData;
      for (var i = 0,  len = tests.length; i < len; i++) {
        test = tests[i];
        testData = test.data;

        expect(getSamples(testData.seed, testData.total, testData.count))
          .toEqual(test.expected);
      }

    });

  });

});
<|endoftext|>


<commit_before>
/*
 Maps namespace

 gnt.maps
*/
gnt.maps = {};

var map = undefined;
gnt.maps.layer = undefined;
gnt.maps.layers = [];

/*
This function creates the map and layers.

Additional parameters and layers can be given to the
function.

map_div -- id of the element to create the map into
initial_extent -- initial extent where the map should open
callback_function -- callback function the to be called after creation
    The callback_function will get the map as a parameter
*/
gnt.maps.create_map = function (map_div, callback_function) {
    var mapOptions;
    var map_options_created = false;
    {% for p in layer_data %}
        {% if p.protocol = 'ARCcache' %}
            var layer_info = {{ p.layer_info|safe }};
            layer = new OpenLayers.Layer.ArcGISCache(
                "{{ p.name }}",
                "{{ p.source }}",
                { layerInfo: layer_info}
            );
            gnt.maps.layers.push(layer);
            mapOptions = {
                maxExtent: layer.maxExtent,
                units: layer.units,
                resolutions: layer.resolutions,
                numZoomLevels: layer.lods.length,
                tileSize: layer.tileSize,
                projection: layer.projection,
                restrictedExtent: layer.maxExtent
            };
            map_options_created = true;
        {% else %}
        {% if p.protocol = 'WMTS' %}
            var matrixIds = new Array(16);
            for (var i=0; i<16; ++i) {
                matrixIds[i] = "EPSG:{{ map_data.projection }}:" + i;
            }
            layer = new OpenLayers.Layer.WMTS({
                name: "{{ p.name }}",
                url: "{{ p.source }}",
                layer: "{{ p.layers }}",
                matrixSet: "EPSG:{{ map_data.projection }}",
                matrixIds: matrixIds,
                format: "image/png",
                style: "_null",
                opacity: 0.7,
                /*{% if p.layer_type = 'BL'%}
                    isBaseLayer: true,
                    {% else %}*/
                 //   isBaseLayer: false,
                //{% endif %}*/
               //wrapDateLine: false,
                //visibility: true
            });
            gnt.maps.layers.push(layer);
        {% else %}
        {% if p.protocol = 'ARCGIS' %}
            layer = new OpenLayers.Layer.ArcGIS93Rest(
                "{{ p.name }}",
                "{{ p.source }}",
                {layers: "show:{{ p.layers }}",
                format: "png24",
                transparent: true},
                {% if p.layer_type = 'BL'%}
                    {isBaseLayer: true}
                    {% else %}
                    {isBaseLayer: false}
                {% endif %}
                );
            gnt.maps.layers.push(layer);
        {% else %}
        {% if p.protocol = 'OSM' %}
            layer = new OpenLayers.Layer.OSM();
            gnt.maps.layers.push(layer);
        {% else %}
        {% if p.protocol = 'WMS' %}
            layer = new OpenLayers.Layer.WMS(
                "{{ p.name }}",
                "{{ p.source }}",
                {layers: "{{ p.layers }}"},
                {% if p.layer_type = 'BL'%}
                {isBaseLayer: true}
                {% else %}
                {isBaseLayer: false}
                {% endif %}
                );
            gnt.maps.layers.push(layer);
        {% else %}
        {% if p.protocol = 'WFS' %}
            layer = new OpenLayers.Layer.Vector(
                "{{ p.name }}",
                {strategies: [new OpenLayers.Strategy.BBOX()],
                protocol: new OpenLayers.Protocol.WFS({
                    url:  "{{ p.source }}",
                    version: "1.1.0",
                    featureType: "{{ p.layer }}",
                    featureNS: "http://localhost:8080/geoserver/BaseTest",
                    geometryName: "the_geom"
                    }),
                    visibility: false,
                    onFeatureInsert: function(event) {
                        count_order(event);
                    },
                    {% if p.layer_type = 'BL'%}
                    isBaseLayer: true
                    {% else %}
                    isBaseLayer: false
                    {% endif %}
                });
            gnt.maps.layers.push(layer);
        {% endif %}
        {% endif %}
        {% endif %}
        {% endif %}
        {% endif %}
        {% endif %}
        if(map_options_created === false) {
            mapOptions = {
                projection: "EPSG:{{ map_data.projection }}",
                maxExtent: new OpenLayers.Bounds({{ map_data.max_extent }}),
                units: "m",
                maxResolution: {{ map_data.max_resolution }},
                zoom: {{ map_data.zoom_level }},
                tileSize: new OpenLayers.Size({{ map_data.tile_size }})
            };
        }
    {% endfor %}

    //make sure mapOptions controls are set correct
    mapOptions.controls = [new OpenLayers.Control.Navigation(),
                           new OpenLayers.Control.Zoom(),
                           new OpenLayers.Control.LayerSwitcher()];

    //mapOptions.controls = [new OpenLayers.Control.ZoomPanel()];
    mapOptions['theme'] = null;

    map = new OpenLayers.Map(map_div, mapOptions);
    map.addLayers(gnt.maps.layers);

    if(callback_function !== undefined) {
        callback_function(map);
    }
};
<commit_msg>removed layerswitcher from default controls<commit_after>
/*
 Maps namespace

 gnt.maps
*/
gnt.maps = {};

var map = undefined;
gnt.maps.layer = undefined;
gnt.maps.layers = [];

/*
This function creates the map and layers.

Additional parameters and layers can be given to the
function.

map_div -- id of the element to create the map into
initial_extent -- initial extent where the map should open
callback_function -- callback function the to be called after creation
    The callback_function will get the map as a parameter
*/
gnt.maps.create_map = function (map_div, callback_function) {
    var mapOptions;
    var map_options_created = false;
    {% for p in layer_data %}
        {% if p.protocol = 'ARCcache' %}
            var layer_info = {{ p.layer_info|safe }};
            layer = new OpenLayers.Layer.ArcGISCache(
                "{{ p.name }}",
                "{{ p.source }}",
                { layerInfo: layer_info}
            );
            gnt.maps.layers.push(layer);
            mapOptions = {
                maxExtent: layer.maxExtent,
                units: layer.units,
                resolutions: layer.resolutions,
                numZoomLevels: layer.lods.length,
                tileSize: layer.tileSize,
                projection: layer.projection,
                restrictedExtent: layer.maxExtent
            };
            map_options_created = true;
        {% else %}
        {% if p.protocol = 'WMTS' %}
            var matrixIds = new Array(16);
            for (var i=0; i<16; ++i) {
                matrixIds[i] = "EPSG:{{ map_data.projection }}:" + i;
            }
            layer = new OpenLayers.Layer.WMTS({
                name: "{{ p.name }}",
                url: "{{ p.source }}",
                layer: "{{ p.layers }}",
                matrixSet: "EPSG:{{ map_data.projection }}",
                matrixIds: matrixIds,
                format: "image/png",
                style: "_null",
                opacity: 0.7,
                /*{% if p.layer_type = 'BL'%}
                    isBaseLayer: true,
                    {% else %}*/
                 //   isBaseLayer: false,
                //{% endif %}*/
               //wrapDateLine: false,
                //visibility: true
            });
            gnt.maps.layers.push(layer);
        {% else %}
        {% if p.protocol = 'ARCGIS' %}
            layer = new OpenLayers.Layer.ArcGIS93Rest(
                "{{ p.name }}",
                "{{ p.source }}",
                {layers: "show:{{ p.layers }}",
                format: "png24",
                transparent: true},
                {% if p.layer_type = 'BL'%}
                    {isBaseLayer: true}
                    {% else %}
                    {isBaseLayer: false}
                {% endif %}
                );
            gnt.maps.layers.push(layer);
        {% else %}
        {% if p.protocol = 'OSM' %}
            layer = new OpenLayers.Layer.OSM();
            gnt.maps.layers.push(layer);
        {% else %}
        {% if p.protocol = 'WMS' %}
            layer = new OpenLayers.Layer.WMS(
                "{{ p.name }}",
                "{{ p.source }}",
                {layers: "{{ p.layers }}"},
                {% if p.layer_type = 'BL'%}
                {isBaseLayer: true}
                {% else %}
                {isBaseLayer: false}
                {% endif %}
                );
            gnt.maps.layers.push(layer);
        {% else %}
        {% if p.protocol = 'WFS' %}
            layer = new OpenLayers.Layer.Vector(
                "{{ p.name }}",
                {strategies: [new OpenLayers.Strategy.BBOX()],
                protocol: new OpenLayers.Protocol.WFS({
                    url:  "{{ p.source }}",
                    version: "1.1.0",
                    featureType: "{{ p.layer }}",
                    featureNS: "http://localhost:8080/geoserver/BaseTest",
                    geometryName: "the_geom"
                    }),
                    visibility: false,
                    onFeatureInsert: function(event) {
                        count_order(event);
                    },
                    {% if p.layer_type = 'BL'%}
                    isBaseLayer: true
                    {% else %}
                    isBaseLayer: false
                    {% endif %}
                });
            gnt.maps.layers.push(layer);
        {% endif %}
        {% endif %}
        {% endif %}
        {% endif %}
        {% endif %}
        {% endif %}
        if(map_options_created === false) {
            mapOptions = {
                projection: "EPSG:{{ map_data.projection }}",
                maxExtent: new OpenLayers.Bounds({{ map_data.max_extent }}),
                units: "m",
                maxResolution: {{ map_data.max_resolution }},
                zoom: {{ map_data.zoom_level }},
                tileSize: new OpenLayers.Size({{ map_data.tile_size }})
            };
        }
    {% endfor %}

    //make sure mapOptions controls are set correct
    mapOptions.controls = [new OpenLayers.Control.Navigation(),
                           new OpenLayers.Control.Zoom()];

    mapOptions['theme'] = null;

    map = new OpenLayers.Map(map_div, mapOptions);
    map.addLayers(gnt.maps.layers);

    if(callback_function !== undefined) {
        callback_function(map);
    }
};
<|endoftext|>


<commit_before>
//
// Node PHP Process
//

function NodePhpProcess(handler) {
	this.data = '';

	this.init = () => {
		if(handler) {
			this.handle = handler;
		}
		else {
			throw new Error('No handler defined');
		}

		process.stdin.on('data', this.onData);
		process.stdin.on('end', this.onEnd);
	};

	this.onData = (chunk) => {
		this.data += chunk;
	};

	this.onEnd = () => {
		this.data = JSON.parse(this.data);
		this.handle(this.data);
	};

	this.init();
}

module.exports = NodePhpProcess;
<commit_msg>master: modified callback to conform to typical error feedback<commit_after>
//
// Node PHP Process
//

function NodePhpProcess(handler) {
	this.data = '';

	this.init = () => {
		if(handler) {
			this.handle = handler;
		}
		else {
			this.handle(new Error('No handler defined'));
			return;
		}

		process.stdin.on('data', this.onData);
		process.stdin.on('end', this.onEnd);
	};

	this.onData = (chunk) => {
		this.data += chunk;
	};

	this.onEnd = () => {
		this.data = JSON.parse(this.data);
		this.handle(null, this.data);
	};

	this.init();
}

module.exports = NodePhpProcess;
<|endoftext|>


<commit_before>#!/usr/bin/env node

(function() {
var Router, argv, http, router, server, clean_up;

try {
  Router = require('node-simple-router');
} catch (e) {
  console.log('node-simple-router must be installed for this to work');
  process.exit(-1);
}

http = require('http');

router = Router({
  list_dir: false
});

/*
Example routes
*/

router.get("/", function(request, response) {
    response.writeHead(200, {
      'Content-type': 'text/html'
    });
    response.write("
Home

");
    response.write('
Hello Page
');
    response.write('
Users Page
');
    return response.end('
User 77 home page
');
});

router.get("/hello", function(request, response) {
  return response.end("Hello, World!, Hola, Mundo!");
});

router.get("/users", function(request, response) {
  response.writeHead(200, {
  'Content-type': 'text/html'
  });
  response.write("
Active members registry

");
  response.write('
<form action="/users" method="POST">');
  response.write('User ID: ');
  response.write('<input type="number" name="user_id" /><input type="submit" value="Search" />');
  return response.end('</form>
');
});

router.post("/users", function(request, response) {
  return response.end("User " + request.post.user_id + " requested. Trying to figure out who she is...");
});

router.any("/users/:id", function(request, response) {
  response.writeHead(200, {
    'Content-type': 'text/html'
  });
  return response.end("
User No: " + request.params.id + "
");
});

/*
End of example routes
*/

argv = process.argv.slice(2);

server = http.createServer(router);

server.on('listening', function() {
  var addr;
  addr = server.address() || {
    address: '0.0.0.0',
    port: argv[0] || 23666
  };
  return router.log("Serving web content at " + addr.address + ":" + addr.port + " - PID: " + process.pid);
});

clean_up = function() {
  router.log(" ");
  router.log("Server shutting up...");
  router.log(" ");
  server.close();
  return process.exit(0);
};

process.on('SIGINT', clean_up);
process.on('SIGHUP', clean_up);
process.on('SIGQUIT', clean_up);
process.on('SIGTERM', clean_up);

server.listen((argv[0] != null) && !isNaN(parseInt(argv[0])) ? parseInt(argv[0]) : 8000);

}).call(this);
<commit_msg>Cleaning up<commit_after><|endoftext|>


<commit_before>(function(ext) {
    // Cleanup function when the extension is unloaded
    ext._shutdown = function() {};

    // Status reporting code
    // Use this to report missing hardware, plugin or unsupported browser
    ext._getStatus = function() {
        return {status: 2, msg: 'Ready'};
    };

	ext.my_first_block = function() {
        console.log("hello, world.");
    };

	    ext.power = function(base, exponent) {
        return Math.pow(base, exponent);
    };

    // Block and block menu descriptions
    var descriptor = {
        blocks: [
			['', 'My First Block', 'my_first_block'],
			['r', '%n ^ %n', 'power', 2, 3],
        ]
    };

    // Register the extension
    ScratchExtensions.register('Kinect2Scratch', descriptor, ext);
})({});<commit_msg>Try a drop down box<commit_after>(function(ext) {
    // Cleanup function when the extension is unloaded
    ext._shutdown = function() {};

    // Status reporting code
    // Use this to report missing hardware, plugin or unsupported browser
    ext._getStatus = function() {
        return {status: 2, msg: 'Ready'};
    };

        // Block and block menu descriptions
    var descriptor = {
        blocks: [
			['', 'My First Block', 'my_first_block'],
			['r', '%n ^ %n', 'power', 2, 3],
            ['r', '%m.k', 'k', 'headx']
        ]
    };

	ext.my_first_block = function() {
        console.log("hello, world.");
    };

    ext.power = function(base, exponent) {
        return Math.pow(base, exponent);
    };

    ext.k = function(m) {
        switch(m){
            case 'headx':
            case 'heady':
            case 'righthandx':
            case 'righthandy':
        }
    };

    // Register the extension
    ScratchExtensions.register('Kinect2Scratch', descriptor, ext);
})({});<|endoftext|>


<commit_before>/* jshint newcap: false */
(function() {
	"use strict";

	/**
	 * Voyeur "constructor". Never initilize with the new keyword.
	 * @param {HTMLElement|Array of elements} nodes Array of nodes to create a Voyeur object with
	 * @return {Voyeur} Voyeur extended Node
	 */
	var Voyeur = function(nodes) {
		if(nodes instanceof HTMLElement) {
			//Single node so extend it's children
			Voyeur.extendChildren(nodes);
		}

		//Create the `create` instance
		nodes.create = Voyeur.extendTags({}, function(tag) {
			return Voyeur.create.bind({
				tag: tag,
				parents: nodes
			})();
		});

		/**
		 * Use the current scope
		 * @param  {Function} fn The callback function with the current scope sent as parameter
		 * @return {Voyeur}      The root node
		 */
		nodes.use = function(fn) {
			if(fn) {
				if(nodes instanceof Array) {
					nodes.forEach(function(elem, i) {
						elem = Voyeur(elem);
						fn.call(elem, elem, i);
					});
				} else {
					fn.call(nodes, nodes);
				}
			}

			return nodes.root;
		};

		/**
		 * Find via selector inside the current scope
		 * @param  {String} selector The selector
		 * @return {Voyeur}          The new Voyeur object
		 */
		nodes.find = function(selector) {
			var children;
			if(nodes instanceof Array) {
				children = [];
				nodes.forEach(function(node) {
					children = children.concat(Array.prototype.slice.call(node.querySelectorAll(selector)));
				});
			} else {
				children = Array.prototype.slice.call(nodes.querySelectorAll(selector));
			}

			if(children.length) {
				return Voyeur(children.length === 1 ? children[0] : children);
			}
		};

		/**
		 * Select part of an array
		 * @param  {number} u The start index
		 * @param  {number} v The end index (optional)
		 * @return {Voyeur}   The selected nodes
		 */
		nodes.eq = function(u, v) {
			if(nodes instanceof Array) {
				var newNodes = nodes.slice(u, v || (u + 1));
				return Voyeur(newNodes.length === 1 ? newNodes[0] : newNodes);
			} else {
				return nodes;
			}
		};

		return nodes;
	};

	/**
	 * Extends a node's children unto it
	 * @param  {Object} node  The node to extend it's children unto
	 * @param {Array} children An array of children to expand to
	 * @return {Object}      The object extended
	 */
	Voyeur.extendChildren = function(node, children) {
		children = Array.prototype.slice.call(children || node.children);

		//The tag map
		var map = {};

		for(var i = 0, cache = children.length; i < cache; i++) {
			var child = children[i],
				tag = child.tagName.toLowerCase();

			if(!map[tag]) {
				map[tag] = [];
			}

			map[tag].push(child);
		}

		/* jshint loopfunc: true */
		for(var key in map) {
			(function(key) { //Closure required
				Object.defineProperty(node, key, {
					get: function() {
						return Voyeur(map[key].length === 1 ? map[key][0] : map[key]);
					},

					configurable: true
				});
			})(key);
		}
	};

	/**
	 * Voyeur.create recursive function
	 * @param  {Array|HTMLElement} parents The array of parents|htmlelement
	 * @return {Object}         A create object
	 */
	Voyeur.create = function(parents) {
		var self = parents || Voyeur.createElement(this.parents, this.tag);
		self.root = this.root || self;
		self.parents = this.parents;

		Voyeur.extendTags(self, function(tag) {
			Voyeur.unextendTags(self);

			return Voyeur.create.bind({
				root: self.root,
				parents: self,
				tag: tag
			})();
		});

		self.use = function(fn) {
			if(fn) {
				if(self instanceof Array) {
					self.forEach(function(elem, i) {
						elem = Voyeur(elem);
						fn.call(elem, elem, i);
					});
				} else {
					var vSelf = Voyeur(self);
					fn.call(vSelf, vSelf);
				}
			}

			Voyeur.unextendTags(self.root);

			return Voyeur(self.root);
		};

		self.mult = function(factor) {
			//Get rid of the inital node
			self.parentNode.removeChild(self);

			var elems = [];
			for(var i = 0; i < factor; i++) {
				var elem = Voyeur.createElement(self.parents, self.tagName.toLowerCase());
				elems.push(elem);
			}
			return Voyeur.create.bind({
				root: self.root
			})(elems);
		};

		self.special = function(tag) {
			return Voyeur.create.bind({
				root: self.root,
				parents: self,
				tag: tag
			})();
		};

		return self;

	};

	/**
	 * Create an element and insert it into parents if passed
	 * @param  {Array|HTMLElement} parents Parent(s) to insert into (optional)
	 * @param  {String} tag     The HTML element tag
	 * @return {Array|HTMLElement}         The array of new parents or element
	 */
	Voyeur.createElement = function(parents, tag) {

		// helper
		function create() {
			return document.createElement(tag);
		}

		if(parents) {
			if(parents instanceof Array) {
				var newParents = [];
				parents.forEach(function(mummy) {
					var elem = create();
					mummy.appendChild(elem);
					newParents.push(elem);
				});

				return newParents;
			} else {
				var elem = create();
				parents.appendChild(elem);
				return elem;
			}
		} else {
			return create();
		}

	};

	Voyeur.nodes = "a,abbr,acronym,address,applet,area,article,aside,audio,b,base,basefont,bdi,bdo,bgsound,big,blink,blockquote,br,button,canvas,caption,center,cite,code,col,colgroup,data,datalist,dd,del,details,dfn,dir,div,dl,dt,em,embed,fieldset,figcaption,figure,font,footer,form,frame,frameset,h1,h2,h3,h4,h5,h6,header,hgroup,hr,i,iframe,img,input,ins,isindex,kbd,keygen,label,legend,li,link,listing,main,map,mark,marquee,menu,menuitem,meta,meter,nav,nobr,noframes,noscript,object,ol,optgroup,option,output,p,param,plaintext,pre,progress,q,rp,rt,ruby,s,samp,section,select,small,source,spacer,span,strike,strong,sub,summary,sup,table,tbody,td,textarea,tfoot,th,thead,time,tr,track,tt,u,ul,var,video,wbr,xmp".split(",");

	/**
	 * Extends all of the Voyeur.nodes tags onto an object via a getter
	 * @param  {Object}   obj The reciever object
	 * @param  {Function} fn  The function on get with `tag` sent to it
	 * @return {Object}       The reciever object
	 */
	Voyeur.extendTags = function(obj, fn) {
		Voyeur.nodes.forEach(function(tag) {
			Object.defineProperty(obj, tag, {
				get: function() {
					return fn.call(obj, tag);
				},

				configurable: true
			});
		});

		return obj;
	};

	Voyeur.unextendTags = function(obj) {
		Voyeur.nodes.forEach(function(tag) {
			delete obj[tag];
		});

		return obj;
	};

	document.addEventListener("DOMContentLoaded", function() {
		//Initilize Voyeur on the document
		window.Voyeur = Voyeur(document.body);

		//Create for the root Voyeur
		window.Voyeur.create = Voyeur.extendTags({}, function(tag) {
			return Voyeur.create.bind({
				tag: tag
			})();
		});

		//Special create function
		window.Voyeur.create.special = function(tag) {
			return Voyeur.create.bind({
				tag: tag
			})();
		};
	});
})();<commit_msg>don't need to convert NodeList to array in extendChildren<commit_after>/* jshint newcap: false */
(function() {
	"use strict";

	/**
	 * Voyeur "constructor". Never initilize with the new keyword.
	 * @param {HTMLElement|Array of elements} nodes Array of nodes to create a Voyeur object with
	 * @return {Voyeur} Voyeur extended Node
	 */
	var Voyeur = function(nodes) {
		if(nodes instanceof HTMLElement) {
			//Single node so extend it's children
			Voyeur.extendChildren(nodes);
		}

		//Create the `create` instance
		nodes.create = Voyeur.extendTags({}, function(tag) {
			return Voyeur.create.bind({
				tag: tag,
				parents: nodes
			})();
		});

		/**
		 * Use the current scope
		 * @param  {Function} fn The callback function with the current scope sent as parameter
		 * @return {Voyeur}      The root node
		 */
		nodes.use = function(fn) {
			if(fn) {
				if(nodes instanceof Array) {
					nodes.forEach(function(elem, i) {
						elem = Voyeur(elem);
						fn.call(elem, elem, i);
					});
				} else {
					fn.call(nodes, nodes);
				}
			}

			return nodes.root;
		};

		/**
		 * Find via selector inside the current scope
		 * @param  {String} selector The selector
		 * @return {Voyeur}          The new Voyeur object
		 */
		nodes.find = function(selector) {
			var children;
			if(nodes instanceof Array) {
				children = [];
				nodes.forEach(function(node) {
					children = children.concat(Array.prototype.slice.call(node.querySelectorAll(selector)));
				});
			} else {
				children = Array.prototype.slice.call(nodes.querySelectorAll(selector));
			}

			if(children.length) {
				return Voyeur(children.length === 1 ? children[0] : children);
			}
		};

		/**
		 * Select part of an array
		 * @param  {number} u The start index
		 * @param  {number} v The end index (optional)
		 * @return {Voyeur}   The selected nodes
		 */
		nodes.eq = function(u, v) {
			if(nodes instanceof Array) {
				var newNodes = nodes.slice(u, v || (u + 1));
				return Voyeur(newNodes.length === 1 ? newNodes[0] : newNodes);
			} else {
				return nodes;
			}
		};

		return nodes;
	};

	/**
	 * Extends a node's children unto it
	 * @param  {Object} node  The node to extend it's children unto
	 * @param {Array} children An array of children to expand to
	 * @return {Object}      The object extended
	 */
	Voyeur.extendChildren = function(node, children) {
		children = children || node.children;

		//The tag map
		var map = {};

		for(var i = 0, cache = children.length; i < cache; i++) {
			var child = children[i],
				tag = child.tagName.toLowerCase();

			if(!map[tag]) {
				map[tag] = [];
			}

			map[tag].push(child);
		}

		/* jshint loopfunc: true */
		for(var key in map) {
			(function(key) { //Closure required
				Object.defineProperty(node, key, {
					get: function() {
						return Voyeur(map[key].length === 1 ? map[key][0] : map[key]);
					},

					configurable: true
				});
			})(key);
		}
	};

	/**
	 * Voyeur.create recursive function
	 * @param  {Array|HTMLElement} parents The array of parents|htmlelement
	 * @return {Object}         A create object
	 */
	Voyeur.create = function(parents) {
		var self = parents || Voyeur.createElement(this.parents, this.tag);
		self.root = this.root || self;
		self.parents = this.parents;

		Voyeur.extendTags(self, function(tag) {
			Voyeur.unextendTags(self);

			return Voyeur.create.bind({
				root: self.root,
				parents: self,
				tag: tag
			})();
		});

		self.use = function(fn) {
			if(fn) {
				if(self instanceof Array) {
					self.forEach(function(elem, i) {
						elem = Voyeur(elem);
						fn.call(elem, elem, i);
					});
				} else {
					var vSelf = Voyeur(self);
					fn.call(vSelf, vSelf);
				}
			}

			Voyeur.unextendTags(self.root);

			return Voyeur(self.root);
		};

		self.mult = function(factor) {
			//Get rid of the inital node
			self.parentNode.removeChild(self);

			var elems = [];
			for(var i = 0; i < factor; i++) {
				var elem = Voyeur.createElement(self.parents, self.tagName.toLowerCase());
				elems.push(elem);
			}
			return Voyeur.create.bind({
				root: self.root
			})(elems);
		};

		self.special = function(tag) {
			return Voyeur.create.bind({
				root: self.root,
				parents: self,
				tag: tag
			})();
		};

		return self;

	};

	/**
	 * Create an element and insert it into parents if passed
	 * @param  {Array|HTMLElement} parents Parent(s) to insert into (optional)
	 * @param  {String} tag     The HTML element tag
	 * @return {Array|HTMLElement}         The array of new parents or element
	 */
	Voyeur.createElement = function(parents, tag) {

		// helper
		function create() {
			return document.createElement(tag);
		}

		if(parents) {
			if(parents instanceof Array) {
				var newParents = [];
				parents.forEach(function(mummy) {
					var elem = create();
					mummy.appendChild(elem);
					newParents.push(elem);
				});

				return newParents;
			} else {
				var elem = create();
				parents.appendChild(elem);
				return elem;
			}
		} else {
			return create();
		}

	};

	Voyeur.nodes = "a,abbr,acronym,address,applet,area,article,aside,audio,b,base,basefont,bdi,bdo,bgsound,big,blink,blockquote,br,button,canvas,caption,center,cite,code,col,colgroup,data,datalist,dd,del,details,dfn,dir,div,dl,dt,em,embed,fieldset,figcaption,figure,font,footer,form,frame,frameset,h1,h2,h3,h4,h5,h6,header,hgroup,hr,i,iframe,img,input,ins,isindex,kbd,keygen,label,legend,li,link,listing,main,map,mark,marquee,menu,menuitem,meta,meter,nav,nobr,noframes,noscript,object,ol,optgroup,option,output,p,param,plaintext,pre,progress,q,rp,rt,ruby,s,samp,section,select,small,source,spacer,span,strike,strong,sub,summary,sup,table,tbody,td,textarea,tfoot,th,thead,time,tr,track,tt,u,ul,var,video,wbr,xmp".split(",");

	/**
	 * Extends all of the Voyeur.nodes tags onto an object via a getter
	 * @param  {Object}   obj The reciever object
	 * @param  {Function} fn  The function on get with `tag` sent to it
	 * @return {Object}       The reciever object
	 */
	Voyeur.extendTags = function(obj, fn) {
		Voyeur.nodes.forEach(function(tag) {
			Object.defineProperty(obj, tag, {
				get: function() {
					return fn.call(obj, tag);
				},

				configurable: true
			});
		});

		return obj;
	};

	Voyeur.unextendTags = function(obj) {
		Voyeur.nodes.forEach(function(tag) {
			delete obj[tag];
		});

		return obj;
	};

	document.addEventListener("DOMContentLoaded", function() {
		//Initilize Voyeur on the document
		window.Voyeur = Voyeur(document.body);

		//Create for the root Voyeur
		window.Voyeur.create = Voyeur.extendTags({}, function(tag) {
			return Voyeur.create.bind({
				tag: tag
			})();
		});

		//Special create function
		window.Voyeur.create.special = function(tag) {
			return Voyeur.create.bind({
				tag: tag
			})();
		};
	});
})();
<|endoftext|>


<commit_before>const cacheName = 'codecamp-v1.2';
const pathsToCache = [
  '/',
  '/faqs',
  '/coc',
  "/static/manifest.json",
  '/static/stylesheets/fonts.min.css',
  '/static/stylesheets/main.min.css',
  '/static/javascripts/main.min.js',
  '/static/javascripts/sw-register.min.js',
  '/static/images/logo.png',
  '/static/images/logo-md.png',
  '/static/images/gdg-logo.png',
  '/static/images/speakers/bok-thye-yeow.png',
  '/static/images/speakers/chelle-gray.jpg',
  '/static/images/speakers/erica-hanson.png',
  '/static/images/speakers/junho-choi.png',
  '/static/images/speakers/manikanta-krishnamurthy.png',
  '/static/images/speakers/sami-kizilbash.png',
  '/static/images/speakers/shad-roi.jpg',
  '/static/images/speakers/soonson-kwon.png',
  '/static/images/speakers/takuo-suzuki.png',
  '/static/images/sponsors/iec.png',
  '/static/images/sponsors/pldt-innolab.png',
  '/static/images/sponsors/prworks.png',
  '/static/fonts/droid-sans/bold.ttf',
  '/static/fonts/droid-sans/regular.ttf',
  '/static/fonts/quicksand/bold.woff2'
];

self.addEventListener('install', function(e) {
  e.waitUntil(
    caches.open(cacheName)
      .then(function(cache) {
        return cache.addAll(pathsToCache);
      })
      .then(function() {
        return self.skipWaiting();
      })
  );
});

self.addEventListener('activate', function(e) {
  e.waitUntil(
    caches.keys()
      .then(function(cacheKeys) {
        return Promise.all(cacheKeys.map(function(cacheKey) {
          if (cacheKey !== cacheName) {
            caches.delete(cacheKey);
          }
        }));
      })
      .then(function() {
        self.clients.claim();
      })
  );
});

self.addEventListener('fetch', function(e) {
  e.respondWith(
    caches.match(e.request)
      .then(function(response) {
        return response || fetch(e.request);
      })
  );
});
<commit_msg>bump up service worker cache version<commit_after>const cacheName = 'codecamp-v1.3';
const pathsToCache = [
  '/',
  '/faqs',
  '/coc',
  "/static/manifest.json",
  '/static/stylesheets/fonts.min.css',
  '/static/stylesheets/main.min.css',
  '/static/javascripts/main.min.js',
  '/static/javascripts/sw-register.min.js',
  '/static/images/logo.png',
  '/static/images/logo-md.png',
  '/static/images/gdg-logo.png',
  '/static/images/speakers/bok-thye-yeow.png',
  '/static/images/speakers/chelle-gray.jpg',
  '/static/images/speakers/erica-hanson.png',
  '/static/images/speakers/junho-choi.png',
  '/static/images/speakers/manikanta-krishnamurthy.png',
  '/static/images/speakers/sami-kizilbash.png',
  '/static/images/speakers/shad-roi.jpg',
  '/static/images/speakers/soonson-kwon.png',
  '/static/images/speakers/takuo-suzuki.png',
  '/static/images/sponsors/iec.png',
  '/static/images/sponsors/pldt-innolab.png',
  '/static/images/sponsors/prworks.png',
  '/static/fonts/droid-sans/bold.ttf',
  '/static/fonts/droid-sans/regular.ttf',
  '/static/fonts/quicksand/bold.woff2'
];

self.addEventListener('install', function(e) {
  e.waitUntil(
    caches.open(cacheName)
      .then(function(cache) {
        return cache.addAll(pathsToCache);
      })
      .then(function() {
        return self.skipWaiting();
      })
  );
});

self.addEventListener('activate', function(e) {
  e.waitUntil(
    caches.keys()
      .then(function(cacheKeys) {
        return Promise.all(cacheKeys.map(function(cacheKey) {
          if (cacheKey !== cacheName) {
            caches.delete(cacheKey);
          }
        }));
      })
      .then(function() {
        self.clients.claim();
      })
  );
});

self.addEventListener('fetch', function(e) {
  e.respondWith(
    caches.match(e.request)
      .then(function(response) {
        return response || fetch(e.request);
      })
  );
});
<|endoftext|>


<commit_before>var DayCount = (function () {
    'use strict';

    var msPerHour = 60 * 60 * 1000;
    var msPerDay = 24 * msPerHour;
	var months = ["jan", "feb", "mar", "apr", "maj", "jun", "jul", "aug", "sep", "okt", "nov", "dec"];

    function toLocalString(d) {
        d = d.clone();
        d.setMinutes(d.getMinutes() - d.getTimezoneOffset());
        var s = d.toISOString();
        return s.replace(/T/, " ");
    }

    Date.prototype.hms = function () {
        return toLocalString(this).substring(11, 19);
    };

    Date.prototype.ymd = function () {
        return toLocalString(this).substring(0, 10)
    };

    Date.prototype.ymdhm = function () {
        return toLocalString(this).substring(0, 16);
    };

    Date.prototype.ymdhms = function () {
        return toLocalString(this).substring(0, 19);
    };

    Date.prototype.mmmyy = function () {
        return months[this.getMonth()] + " " + (this.getFullYear() % 100).toFixed(0);
    };

    Date.prototype.mmmyyyy = function () {
        return months[this.getMonth()] + " " + this.getFullYear().toFixed(0);
    };

    Date.prototype.addHours = function (h) {
        var t = this.getTime();
        return new Date(t + msPerHour * h);
    };

    Date.prototype.totalHours = function () {
        if (isNaN(this.getTime()))
            return NaN;
        var r = this.getHours() + (this.getMinutes() + this.getSeconds() / 60) / 60;
        if (r < 0)
            r += 24;
        else if (r > 24)
            r -= 24;
        return r;
    };

    Date.prototype.date = function () {
        var d = this.clone();
        d.setHours(0, 0, 0, 0);
        return d;
    }

    Date.prototype.clone = function () {
        return new Date(this.getTime());
    }

    Date.prototype.addDays = function (days) {
        return (new Date(Date.UTC(this.getFullYear(), this.getMonth(), this.getDate() + days, 0, 0, 0))).date();
        //var res = this.clone();
        //res.setDate(res.getDate() + days);
        //return res;
    }

    Date.isLeapYear = function (year) {
        return (((year % 4 === 0) && (year % 100 !== 0)) || (year % 400 === 0));
    };

    Date.getDaysInMonth = function (year, month) {
        return [31, (Date.isLeapYear(year) ? 29 : 28), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][month];
    };

    Date.prototype.getDaysInMonth = function () {
        return Date.getDaysInMonth(this.getFullYear(), this.getMonth());
    };

    Date.prototype.addMonths = function (value) {
        var res = this.clone();
        var n = res.getDate();
        res.setDate(1);
        res.setMonth(res.getMonth() + value);
        res.setDate(Math.min(n, res.getDaysInMonth()));
        return res;
    };

    Date.prototype.addYears = function (value) {
        return this.addMonths(12 * value);
    };

    Date.prototype.dayOfYear = function () {
        let start = new Date(Date.UTC(this.getFullYear(), 0, 0));
        return Math.floor((this - start) / msPerDay);
    };

    Date.prototype.monthNumber = function () {
        return 12 * (this.getFullYear() - 1970) + this.getMonth();
    };

    Date.prototype.endOfMonth = function () {
        let m = this.getMonth();
        let y = this.getFullYear();
        return new Date(Date.UTC(y, m, Date.getDaysInMonth(y, m)));
    };

    Date.prototype.lastDayOfMonth = function () {
        return this.endOfMonth();
    };

    Date.prototype.toUnixTime = function () {
        return Math.floor(this.getTime() / 1000);
    }

	// Monday starting week day
	Date.prototype.weekDay = function () {
		return (this.getDay() + 6) % 7;
	}

	Date.daysBetween = function (d1, d2) {
		return (d2 - d1) / msPerDay;
	}

	// Month 1-12 !
    Date.fromYmd = function (y, m, d) {
        var d = new Date(Date.UTC(y, m - 1, d, 0, 0, 0));
        d.setMinutes(d.getMinutes() + d.getTimezoneOffset());
		return d;
	}

	// Swedish week number
	Date.prototype.weekNumber = function () {
		var y = this.getFullYear();
		var firstJan = Date.fromYmd(y, 1, 1);
		var d0 = firstJan.weekDay();
		var w = Math.floor((Date.daysBetween(firstJan, this) + d0) / 7);
		if (d0 < 4)
			return w + 1;
		if (w >= 1)
			return w;
		firstJan = Date.fromYmd(y - 1, 1, 1);
		d0 = firstJan.weekDay();
		return Math.floor((Date.daysBetween(firstJan, this) + d0) / 7) + ((d0 >= 4) ? 0 : 1);
	}

    /*
    var firstEasterYear = 1990;
    var lastEasterYear = 2040;
    var easterDays = ["1990-04-15", "1991-03-31", "1992-04-19", "1993-04-11", "1994-04-03", "1995-04-16", "1996-04-07",
        "1997-03-30", "1998-04-12", "1999-04-04", "2000-04-23", "2001-04-15", "2002-03-31", "2003-04-20", "2004-04-11", "2005-03-27", "2006-04-16",
        "2007-04-08", "2008-03-23", "2009-04-12", "2010-04-04", "2011-04-24", "2012-04-08", "2013-03-31", "2014-04-20", "2015-04-05", "2016-03-27",
        "2017-04-16", "2018-04-01", "2019-04-21", "2020-04-12", "2021-04-04", "2022-04-17", "2023-04-09", "2024-03-31", "2025-04-20", "2026-04-05",
        "2027-03-28", "2028-04-16", "2029-04-01", "2030-04-21", "2031-04-13", "2032-03-28", "2033-04-17", "2034-04-09", "2035-03-25", "2036-04-13",
        "2037-04-05", "2038-04-25", "2039-04-10", "2040-04-01"].map(d => (new Date(d)).dayOfYear());
    */

    function easterDay(y) {
        var d = (19 * (y % 19) + 24) % 30;
        var e = (2 * (y % 4) + 4 * (y % 7) + 6 * d + 5) % 7;
        var f = d + e;
        var month = ((f + 22) <= 31) ? 3 : 4;
        var day = f + ((month == 3) ? 22 : -9) + (((f - 9) == 26) ? -7 : 0) + (((d == 28) && (e == 6)) ? -7 : 0);
        return Date.fromYmd(y, month, day).dayOfYear();
    }

    Date.prototype.isBusinessDay = function () {
        let w = this.getDay();
        if ((w == 6) || (w == 0))
            return false;
        let m = this.getMonth();
        let d = this.getDate();
        if (m == 0) //jan
            if ((d == 1) || (d == 6))
                return false;
        if (m == 11) //dec
            if ((d == 24) || (d == 25) || (d == 26) || (d == 31))
                return false;
        if (m == 4) //maj
            if (d == 1)
                return false;
        let y = this.getFullYear();
        if (m == 5) { //jun
            if (d == 6)
                return false;
            let w = (new Date(Date.UTC(y, 5, 19))).getDay();
            if (d == (25 - ((w + 1) % 7)))
                return false; // midsommar
        }
        //if ((y >= firstEasterYear) && (y <= lastEasterYear)) {
        let e = this.dayOfYear() - easterDay(y); // easterDays[y - firstEasterYear];
        if ((e == -2) || (e == 1) || (e == 39)) // långfredag, annandag påsk och kristi himmelsfärd
            return false;
        //}
        return true;
    }

    Date.prototype.nextBusinessDay = function () {
        let d = this;
        while (true) {
            d = d.addDays(1);
            if (d.isBusinessDay())
                return d;
        }
    }

    Date.prototype.adjustNextBusinessDay = function () {
        let d = this;
        if (!d.isBusinessDay())
            d = d.nextBusinessDay();
    }

    Date.prototype.previousBusinessDay = function () {
        let d = this;
        while (true) {
            d = d.addDays(-1);
            if (d.isBusinessDay())
                return d;
        }
    }

    Date.prototype.adjustPreviousBusinessDay = function () {
        let d = this;
        if (!d.isBusinessDay())
            d = d.previousBusinessDay();
    }

    Date.prototype.isLastBusinessDayOfMonth = function () {
        return (this.getMonth() != this.nextBusinessDay().getMonth());
    }

    Date.prototype.lastBusinessDayOfMonth = function () {
        let d = this.lastDayOfMonth();
        if (d.isBusinessDay())
            return d;
        return d.previousBusinessDay();
    }
}());

if (typeof DayCount !== 'undefined') {
	DayCount.printMsg = function () {
		console.log();
	}
}

if (typeof module === 'undefined')
    module = {};

module.exports = DayCount;
<commit_msg>Update daycount.js<commit_after>var DayCount = (function () {
    'use strict';

    var msPerHour = 60 * 60 * 1000;
    var msPerDay = 24 * msPerHour;
	var months = ["jan", "feb", "mar", "apr", "maj", "jun", "jul", "aug", "sep", "okt", "nov", "dec"];

    function toLocalString(d) {
        d = d.clone();
        d.setMinutes(d.getMinutes() - d.getTimezoneOffset());
        var s = d.toISOString();
        return s.replace(/T/, " ");
    }

    Date.prototype.hms = function () {
        return toLocalString(this).substring(11, 19);
    };

    Date.prototype.ymd = function () {
        return toLocalString(this).substring(0, 10)
    };

    Date.prototype.ymdhm = function () {
        return toLocalString(this).substring(0, 16);
    };

    Date.prototype.ymdhms = function () {
        return toLocalString(this).substring(0, 19);
    };

    Date.prototype.yymmdd = function () {
        return this.ymd.substring(2);
    };

    Date.prototype.mmmyy = function () {
        return months[this.getMonth()] + " " + (this.getFullYear() % 100).toFixed(0);
    };

    Date.prototype.mmmyyyy = function () {
        return months[this.getMonth()] + " " + this.getFullYear().toFixed(0);
    };

    Date.prototype.addHours = function (h) {
        var t = this.getTime();
        return new Date(t + msPerHour * h);
    };

    Date.prototype.totalHours = function () {
        if (isNaN(this.getTime()))
            return NaN;
        var r = this.getHours() + (this.getMinutes() + this.getSeconds() / 60) / 60;
        if (r < 0)
            r += 24;
        else if (r > 24)
            r -= 24;
        return r;
    };

    Date.prototype.date = function () {
        var d = this.clone();
        d.setHours(0, 0, 0, 0);
        return d;
    }

    Date.prototype.clone = function () {
        return new Date(this.getTime());
    }

    Date.prototype.addDays = function (days) {
        return (new Date(Date.UTC(this.getFullYear(), this.getMonth(), this.getDate() + days, 0, 0, 0))).date();
        //var res = this.clone();
        //res.setDate(res.getDate() + days);
        //return res;
    }

    Date.isLeapYear = function (year) {
        return (((year % 4 === 0) && (year % 100 !== 0)) || (year % 400 === 0));
    };

    Date.getDaysInMonth = function (year, month) {
        return [31, (Date.isLeapYear(year) ? 29 : 28), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][month];
    };

    Date.prototype.getDaysInMonth = function () {
        return Date.getDaysInMonth(this.getFullYear(), this.getMonth());
    };

    Date.prototype.addMonths = function (value) {
        var res = this.clone();
        var n = res.getDate();
        res.setDate(1);
        res.setMonth(res.getMonth() + value);
        res.setDate(Math.min(n, res.getDaysInMonth()));
        return res;
    };

    Date.prototype.addYears = function (value) {
        return this.addMonths(12 * value);
    };

    Date.prototype.dayOfYear = function () {
        let start = new Date(Date.UTC(this.getFullYear(), 0, 0));
        return Math.floor((this - start) / msPerDay);
    };

    Date.prototype.monthNumber = function () {
        return 12 * (this.getFullYear() - 1970) + this.getMonth();
    };

    Date.prototype.endOfMonth = function () {
        let m = this.getMonth();
        let y = this.getFullYear();
        return new Date(Date.UTC(y, m, Date.getDaysInMonth(y, m)));
    };

    Date.prototype.lastDayOfMonth = function () {
        return this.endOfMonth();
    };

    Date.prototype.toUnixTime = function () {
        return Math.floor(this.getTime() / 1000);
    }

	// Monday starting week day
	Date.prototype.weekDay = function () {
		return (this.getDay() + 6) % 7;
	}

	Date.daysBetween = function (d1, d2) {
		return (d2 - d1) / msPerDay;
	}

	// Month 1-12 !
    Date.fromYmd = function (y, m, d) {
        var d = new Date(Date.UTC(y, m - 1, d, 0, 0, 0));
        d.setMinutes(d.getMinutes() + d.getTimezoneOffset());
		return d;
	}

	// Swedish week number
	Date.prototype.weekNumber = function () {
		var y = this.getFullYear();
		var firstJan = Date.fromYmd(y, 1, 1);
		var d0 = firstJan.weekDay();
		var w = Math.floor((Date.daysBetween(firstJan, this) + d0) / 7);
		if (d0 < 4)
			return w + 1;
		if (w >= 1)
			return w;
		firstJan = Date.fromYmd(y - 1, 1, 1);
		d0 = firstJan.weekDay();
		return Math.floor((Date.daysBetween(firstJan, this) + d0) / 7) + ((d0 >= 4) ? 0 : 1);
	}

    /*
    var firstEasterYear = 1990;
    var lastEasterYear = 2040;
    var easterDays = ["1990-04-15", "1991-03-31", "1992-04-19", "1993-04-11", "1994-04-03", "1995-04-16", "1996-04-07",
        "1997-03-30", "1998-04-12", "1999-04-04", "2000-04-23", "2001-04-15", "2002-03-31", "2003-04-20", "2004-04-11", "2005-03-27", "2006-04-16",
        "2007-04-08", "2008-03-23", "2009-04-12", "2010-04-04", "2011-04-24", "2012-04-08", "2013-03-31", "2014-04-20", "2015-04-05", "2016-03-27",
        "2017-04-16", "2018-04-01", "2019-04-21", "2020-04-12", "2021-04-04", "2022-04-17", "2023-04-09", "2024-03-31", "2025-04-20", "2026-04-05",
        "2027-03-28", "2028-04-16", "2029-04-01", "2030-04-21", "2031-04-13", "2032-03-28", "2033-04-17", "2034-04-09", "2035-03-25", "2036-04-13",
        "2037-04-05", "2038-04-25", "2039-04-10", "2040-04-01"].map(d => (new Date(d)).dayOfYear());
    */

    function easterDay(y) {
        var d = (19 * (y % 19) + 24) % 30;
        var e = (2 * (y % 4) + 4 * (y % 7) + 6 * d + 5) % 7;
        var f = d + e;
        var month = ((f + 22) <= 31) ? 3 : 4;
        var day = f + ((month == 3) ? 22 : -9) + (((f - 9) == 26) ? -7 : 0) + (((d == 28) && (e == 6)) ? -7 : 0);
        return Date.fromYmd(y, month, day).dayOfYear();
    }

    Date.prototype.isBusinessDay = function () {
        let w = this.getDay();
        if ((w == 6) || (w == 0))
            return false;
        let m = this.getMonth();
        let d = this.getDate();
        if (m == 0) //jan
            if ((d == 1) || (d == 6))
                return false;
        if (m == 11) //dec
            if ((d == 24) || (d == 25) || (d == 26) || (d == 31))
                return false;
        if (m == 4) //maj
            if (d == 1)
                return false;
        let y = this.getFullYear();
        if (m == 5) { //jun
            if (d == 6)
                return false;
            let w = (new Date(Date.UTC(y, 5, 19))).getDay();
            if (d == (25 - ((w + 1) % 7)))
                return false; // midsommar
        }
        //if ((y >= firstEasterYear) && (y <= lastEasterYear)) {
        let e = this.dayOfYear() - easterDay(y); // easterDays[y - firstEasterYear];
        if ((e == -2) || (e == 1) || (e == 39)) // långfredag, annandag påsk och kristi himmelsfärd
            return false;
        //}
        return true;
    }

    Date.prototype.nextBusinessDay = function () {
        let d = this;
        while (true) {
            d = d.addDays(1);
            if (d.isBusinessDay())
                return d;
        }
    }

    Date.prototype.adjustNextBusinessDay = function () {
        let d = this;
        if (!d.isBusinessDay())
            d = d.nextBusinessDay();
    }

    Date.prototype.previousBusinessDay = function () {
        let d = this;
        while (true) {
            d = d.addDays(-1);
            if (d.isBusinessDay())
                return d;
        }
    }

    Date.prototype.adjustPreviousBusinessDay = function () {
        let d = this;
        if (!d.isBusinessDay())
            d = d.previousBusinessDay();
    }

    Date.prototype.isLastBusinessDayOfMonth = function () {
        return (this.getMonth() != this.nextBusinessDay().getMonth());
    }

    Date.prototype.lastBusinessDayOfMonth = function () {
        let d = this.lastDayOfMonth();
        if (d.isBusinessDay())
            return d;
        return d.previousBusinessDay();
    }
}());

if (typeof DayCount !== 'undefined') {
	DayCount.printMsg = function () {
		console.log();
	}
}

if (typeof module === 'undefined')
    module = {};

module.exports = DayCount;
<|endoftext|>