<commit_before>// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.

// A bit simpler than readable streams.
// Implement an async ._write(chunk, cb), and it'll handle all
// the drain event emission and buffering.

module.exports = Writable;
Writable.WritableState = WritableState;

var util = require('util');
var assert = require('assert');
var Stream = require('stream');

util.inherits(Writable, Stream);

function WriteReq(stream, len, chunk, encoding, cb) {
  var _this = this;
  this.stream = stream;
  this.len = len;
  this.chunk = chunk;
  this.encoding = encoding;
  this.cb = cb;
}

WriteReq.prototype.doWrite = function() {
  var state,
    _this = this;
  state = this.stream._writableState;
  state.writing += 1;
  this.sync = true;
  return this.stream._write(this.chunk, this.encoding, function(er) {
    var finished;
    state.writing -= 1;
    state.length -= _this.len;
    if (er) {
      //return _this.onWriteError(er);
      onwriteError(_this.stream, state, _this.sync, er, _this.cb);
    } else {
      finished = finishMaybe(_this.stream, state);
      if (!finished && !state.bufferProcessing && state.buffer.length) {
        clearBuffer(_this.stream, state);
      }
      if (_this.sync) {
        return process.nextTick(function() {
          afterWrite(_this.stream, state, finished, _this.cb);
        });
      } else {
        afterWrite(_this.stream, state, finished, _this.cb);
      }
    }
  });
};

function WritableState(options, stream) {
  options = options || {};

  // the point at which write() starts returning false
  // Note: 0 is a valid value, means that we always return false if
  // the entire buffer is not flushed immediately on write()
  var hwm = options.highWaterMark;
  this.highWaterMark = (hwm || hwm === 0) ? hwm : 16 * 1024;

  // object stream flag to indicate whether or not this stream
  // contains buffers or objects.
  this.objectMode = !!options.objectMode;

  // cast to ints.
  this.highWaterMark = ~~this.highWaterMark;

  this.needDrain = false;
  // at the start of calling end()
  this.ending = false;
  // when end() has been called, and returned
  this.ended = false;
  // when 'finish' is emitted
  this.finished = false;

  // should we decode strings into buffers before passing to _write?
  // this is here so that some node-core streams can optimize string
  // handling at a lower level.
  var noDecode = options.decodeStrings === false;
  this.decodeStrings = !noDecode;

  // not an actual buffer we keep track of, but a measurement
  // of how much we're waiting to get pushed to some underlying
  // socket or file.
  this.length = 0;

  // keep track of how many writes are outstanding
  this.maxWrites = (options != null ? options.maxWrites : void 0) || 1;
  this.writing = 0;

  // a flag to be able to tell if the onwrite cb is called immediately,
  // or on a later tick.  We set this to true at first, becuase any
  // actions that shouldn't happen until "later" should generally also
  // not happen before the first write call.
  this.sync = true;

  // a flag to know if we're processing previously buffered items, which
  // may call the _write() callback in the same tick, so that we don't
  // end up in an overlapped onwrite situation.
  this.bufferProcessing = false;

  // the callback that's passed to _write(chunk,cb)
  this.onwrite = function(er) {
    onwrite(stream, er);
  };

  // the callback that the user supplies to write(chunk,encoding,cb)
  this.writecb = null;

  // the amount that is being written when _write is called.
  this.writelen = 0;

  this.buffer = [];
}

function Writable(options) {
  // Writable ctor is applied to Duplexes, though they're not
  // instanceof Writable, they're instanceof Readable.
  if (!(this instanceof Writable) && !(this instanceof Stream.Duplex))
    return new Writable(options);

  this._writableState = new WritableState(options, this);

  // legacy.
  this.writable = true;

  Stream.call(this);
}

// Otherwise people can pipe Writable streams, which is just wrong.
Writable.prototype.pipe = function() {
  this.emit('error', new Error('Cannot pipe. Not readable.'));
};

function writeAfterEnd(stream, state, cb) {
  var er = new Error('write after end');
  // TODO: defer error events consistently everywhere, not just the cb
  stream.emit('error', er);
  process.nextTick(function() {
    cb(er);
  });
}

// If we get something that is not a buffer, string, null, or undefined,
// and we're not in objectMode, then that's an error.
// Otherwise stream chunks are all considered to be of length=1, and the
// watermarks determine how many objects to keep in the buffer, rather than
// how many bytes or characters.
function validChunk(stream, state, chunk, cb) {
  var valid = true;
  if (!Buffer.isBuffer(chunk) &&
      'string' !== typeof chunk &&
      chunk !== null &&
      chunk !== undefined &&
      !state.objectMode) {
    var er = new TypeError('Invalid non-string/buffer chunk');
    stream.emit('error', er);
    process.nextTick(function() {
      cb(er);
    });
    valid = false;
  }
  return valid;
}

Writable.prototype.write = function(chunk, encoding, cb) {
  var state = this._writableState;
  var ret = false;

  if (typeof encoding === 'function') {
    cb = encoding;
    encoding = null;
  }
  if (!encoding)
    encoding = 'utf8';

  if (typeof cb !== 'function')
    cb = function() {};

  if (state.ended)
    writeAfterEnd(this, state, cb);
  else if (validChunk(this, state, chunk, cb))
    ret = writeOrBuffer(this, state, chunk, encoding, cb);

  return ret;
};

function decodeChunk(state, chunk, encoding) {
  if (!state.objectMode &&
      state.decodeStrings !== false &&
      typeof chunk === 'string') {
    chunk = new Buffer(chunk, encoding);
  }
  return chunk;
}

// Only queue the write if maxWrites has been exceeded
function writeOrBuffer(stream, state, chunk, encoding, cb) {
  chunk = decodeChunk(state, chunk, encoding);
  var len = state.objectMode ? 1 : chunk.length;

  state.length += len;

  var ret = state.length < state.highWaterMark;
  state.needDrain = !ret;

  var writeReq = new WriteReq(stream, len, chunk, encoding, cb);
  if (state.writing >= state.maxWrites) {
    state.buffer.push(writeReq);
  } else {
    writeReq.doWrite();
  }

  return ret;
}

function onwriteError(stream, state, sync, er, cb) {
  if (sync)
    process.nextTick(function() {
      cb(er);
    });
  else
    cb(er);

  stream.emit('error', er);
}

function afterWrite(stream, state, finished, cb) {
  if (!finished)
    onwriteDrain(stream, state);
  cb();
}

// Must force callback to be called on nextTick, so that we don't
// emit 'drain' before the write() consumer gets the 'false' return
// value, and has a chance to attach a 'drain' listener.
function onwriteDrain(stream, state) {
  if (state.length === 0 && state.needDrain) {
    state.needDrain = false;
    stream.emit('drain');
  }
}

// if there's something in the buffer waiting, then process it
function clearBuffer(stream, state) {
  state.bufferProcessing = true;

  for (var c = 0; c < state.buffer.length; c++) {
    var writing_before = state.writing;
    state.buffer[c].doWrite();
    if (writing_before + 1 === state.writing && state.writing >= state.maxWrites) {
      c++;
      break;
    }
    c++;
  }

  state.bufferProcessing = false;
  if (c < state.buffer.length)
    state.buffer = state.buffer.slice(c);
  else
    state.buffer.length = 0;
}

Writable.prototype._write = function(chunk, encoding, cb) {
  cb(new Error('not implemented'));
};

Writable.prototype.end = function(chunk, encoding, cb) {
  var state = this._writableState;

  if (typeof chunk === 'function') {
    cb = chunk;
    chunk = null;
    encoding = null;
  } else if (typeof encoding === 'function') {
    cb = encoding;
    encoding = null;
  }

  if (typeof chunk !== 'undefined' && chunk !== null)
    this.write(chunk, encoding);

  // ignore unnecessary end() calls.
  if (!state.ending && !state.finished)
    endWritable(this, state, cb);
};

function finishMaybe(stream, state) {
  if (state.ending && state.length === 0 && !state.finished) {
    state.finished = true;
    stream.emit('finish');
  }
  return state.finished;
}

function endWritable(stream, state, cb) {
  state.ending = true;
  finishMaybe(stream, state);
  if (cb) {
    if (state.finished)
      process.nextTick(cb);
    else
      stream.once('finish', cb);
  }
  state.ended = true;
}
<commit_msg>further reducing diff<commit_after>// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.

// A bit simpler than readable streams.
// Implement an async ._write(chunk, cb), and it'll handle all
// the drain event emission and buffering.

module.exports = Writable;
Writable.WritableState = WritableState;

var util = require('util');
var assert = require('assert');
var Stream = require('stream');

util.inherits(Writable, Stream);

function WriteReq(stream, len, chunk, encoding, cb) {
  var _this = this;
  this.stream = stream;
  this.len = len;
  this.chunk = chunk;
  this.encoding = encoding;
  this.cb = cb;
}

WriteReq.prototype.doWrite = function() {
  var state = this.stream._writableState;
  state.writing += 1;
  this.sync = true;
  var stream = this.stream;
  var _this = this;
  this.stream._write(this.chunk, this.encoding, function(er) {
    onwrite(stream, _this, er);
  });
  this.sync = false;
};

function WritableState(options, stream) {
  options = options || {};

  // the point at which write() starts returning false
  // Note: 0 is a valid value, means that we always return false if
  // the entire buffer is not flushed immediately on write()
  var hwm = options.highWaterMark;
  this.highWaterMark = (hwm || hwm === 0) ? hwm : 16 * 1024;

  // object stream flag to indicate whether or not this stream
  // contains buffers or objects.
  this.objectMode = !!options.objectMode;

  // cast to ints.
  this.highWaterMark = ~~this.highWaterMark;

  this.needDrain = false;
  // at the start of calling end()
  this.ending = false;
  // when end() has been called, and returned
  this.ended = false;
  // when 'finish' is emitted
  this.finished = false;

  // should we decode strings into buffers before passing to _write?
  // this is here so that some node-core streams can optimize string
  // handling at a lower level.
  var noDecode = options.decodeStrings === false;
  this.decodeStrings = !noDecode;

  // not an actual buffer we keep track of, but a measurement
  // of how much we're waiting to get pushed to some underlying
  // socket or file.
  this.length = 0;

  // keep track of how many writes are outstanding
  this.maxWrites = (options != null ? options.maxWrites : void 0) || 1;
  this.writing = 0;

  // a flag to be able to tell if the onwrite cb is called immediately,
  // or on a later tick.  We set this to true at first, becuase any
  // actions that shouldn't happen until "later" should generally also
  // not happen before the first write call.
  this.sync = true;

  // a flag to know if we're processing previously buffered items, which
  // may call the _write() callback in the same tick, so that we don't
  // end up in an overlapped onwrite situation.
  this.bufferProcessing = false;

  // the callback that's passed to _write(chunk,cb)
  this.onwrite = function(er) {
    onwrite(stream, er);
  };

  // the callback that the user supplies to write(chunk,encoding,cb)
  this.writecb = null;

  // the amount that is being written when _write is called.
  this.writelen = 0;

  this.buffer = [];
}

function Writable(options) {
  // Writable ctor is applied to Duplexes, though they're not
  // instanceof Writable, they're instanceof Readable.
  if (!(this instanceof Writable) && !(this instanceof Stream.Duplex))
    return new Writable(options);

  this._writableState = new WritableState(options, this);

  // legacy.
  this.writable = true;

  Stream.call(this);
}

// Otherwise people can pipe Writable streams, which is just wrong.
Writable.prototype.pipe = function() {
  this.emit('error', new Error('Cannot pipe. Not readable.'));
};

function writeAfterEnd(stream, state, cb) {
  var er = new Error('write after end');
  // TODO: defer error events consistently everywhere, not just the cb
  stream.emit('error', er);
  process.nextTick(function() {
    cb(er);
  });
}

// If we get something that is not a buffer, string, null, or undefined,
// and we're not in objectMode, then that's an error.
// Otherwise stream chunks are all considered to be of length=1, and the
// watermarks determine how many objects to keep in the buffer, rather than
// how many bytes or characters.
function validChunk(stream, state, chunk, cb) {
  var valid = true;
  if (!Buffer.isBuffer(chunk) &&
      'string' !== typeof chunk &&
      chunk !== null &&
      chunk !== undefined &&
      !state.objectMode) {
    var er = new TypeError('Invalid non-string/buffer chunk');
    stream.emit('error', er);
    process.nextTick(function() {
      cb(er);
    });
    valid = false;
  }
  return valid;
}

Writable.prototype.write = function(chunk, encoding, cb) {
  var state = this._writableState;
  var ret = false;

  if (typeof encoding === 'function') {
    cb = encoding;
    encoding = null;
  }
  if (!encoding)
    encoding = 'utf8';

  if (typeof cb !== 'function')
    cb = function() {};

  if (state.ended)
    writeAfterEnd(this, state, cb);
  else if (validChunk(this, state, chunk, cb))
    ret = writeOrBuffer(this, state, chunk, encoding, cb);

  return ret;
};

function decodeChunk(state, chunk, encoding) {
  if (!state.objectMode &&
      state.decodeStrings !== false &&
      typeof chunk === 'string') {
    chunk = new Buffer(chunk, encoding);
  }
  return chunk;
}

// Only queue the write if maxWrites has been exceeded
function writeOrBuffer(stream, state, chunk, encoding, cb) {
  chunk = decodeChunk(state, chunk, encoding);
  var len = state.objectMode ? 1 : chunk.length;

  state.length += len;

  var ret = state.length < state.highWaterMark;
  state.needDrain = !ret;

  var writeReq = new WriteReq(stream, len, chunk, encoding, cb);
  if (state.writing >= state.maxWrites) {
    state.buffer.push(writeReq);
  } else {
    writeReq.doWrite();
  }

  return ret;
}

function onwriteError(stream, state, sync, er, cb) {
  if (sync)
    process.nextTick(function() {
      cb(er);
    });
  else
    cb(er);

  stream.emit('error', er);
}

function onwriteStateUpdate(state, writereq) {
  state.writing -= 1;
  state.length -= writereq.len;
}

function onwrite(stream, writereq, er) {
  var state = stream._writableState;
  var sync = writereq.sync;
  var cb = writereq.cb;

  onwriteStateUpdate(state, writereq);

  if (er)
    onwriteError(stream, state, sync, er, cb);
  else {
    var finished = finishMaybe(stream, state);

    if (!finished && !state.bufferProcessing && state.buffer.length)
      clearBuffer(stream, state);

    if (sync) {
      process.nextTick(function() {
        afterWrite(stream, state, finished, cb);
      });
    } else {
      afterWrite(stream, state, finished, cb);
    }
  }
}

function afterWrite(stream, state, finished, cb) {
  if (!finished)
    onwriteDrain(stream, state);
  cb();
}

// Must force callback to be called on nextTick, so that we don't
// emit 'drain' before the write() consumer gets the 'false' return
// value, and has a chance to attach a 'drain' listener.
function onwriteDrain(stream, state) {
  if (state.length === 0 && state.needDrain) {
    state.needDrain = false;
    stream.emit('drain');
  }
}

// if there's something in the buffer waiting, then process it
function clearBuffer(stream, state) {
  state.bufferProcessing = true;

  for (var c = 0; c < state.buffer.length; c++) {
    var writing_before = state.writing;
    state.buffer[c].doWrite();
    if (writing_before + 1 === state.writing && state.writing >= state.maxWrites) {
      c++;
      break;
    }
    c++;
  }

  state.bufferProcessing = false;
  if (c < state.buffer.length)
    state.buffer = state.buffer.slice(c);
  else
    state.buffer.length = 0;
}

Writable.prototype._write = function(chunk, encoding, cb) {
  cb(new Error('not implemented'));
};

Writable.prototype.end = function(chunk, encoding, cb) {
  var state = this._writableState;

  if (typeof chunk === 'function') {
    cb = chunk;
    chunk = null;
    encoding = null;
  } else if (typeof encoding === 'function') {
    cb = encoding;
    encoding = null;
  }

  if (typeof chunk !== 'undefined' && chunk !== null)
    this.write(chunk, encoding);

  // ignore unnecessary end() calls.
  if (!state.ending && !state.finished)
    endWritable(this, state, cb);
};

function finishMaybe(stream, state) {
  if (state.ending && state.length === 0 && !state.finished) {
    state.finished = true;
    stream.emit('finish');
  }
  return state.finished;
}

function endWritable(stream, state, cb) {
  state.ending = true;
  finishMaybe(stream, state);
  if (cb) {
    if (state.finished)
      process.nextTick(cb);
    else
      stream.once('finish', cb);
  }
  state.ended = true;
}
<|endoftext|>


<commit_before>import React from 'react';
import moment from 'moment';
import { weeks } from './utils';

const DayPicker = React.createClass({

  propTypes: {

    initialMonth: React.PropTypes.object, // default is current month
    modifiers: React.PropTypes.object,

    onDayTouchTap: React.PropTypes.func, // requires react-tap-event-plugin enabled
    onDayMouseEnter: React.PropTypes.func,
    onDayMouseLeave: React.PropTypes.func

  },

  getDefaultProps() {
    return { initialMonth: moment() };
  },

  componentWillReceiveProps(nextProps) {
    this.setState({ month: nextProps.initialMonth });
  },

  getInitialState() {
    return { month: this.props.initialMonth.clone() };
  },

  handleDayTouchTap(day, modifiers, e) {
    this.props.onDayTouchTap && this.props.onDayTouchTap(day, modifiers, e);
  },

  handleDayMouseEnter(day, modifiers, e) {
    this.props.onDayMouseEnter && this.props.onDayMouseEnter(day, modifiers, e);
  },

  handleDayMouseLeave(day, modifiers, e) {
    this.props.onDayMouseLeave && this.props.onDayMouseLeave(day, modifiers, e);
  },

  handleNextTouchTap(e) {
    this.setState({ month: this.state.month.add(1, 'month') });
  },

  handlePrevTouchTap(e) {
    this.setState({ month: this.state.month.subtract(1, 'month') });
  },

  getModifiersForDay(day) {
    var dayModifiers = [];
    if (this.props.modifiers) {
      const modifiers = this.props.modifiers;
      for (let modifier in modifiers) {
        var func = modifiers[modifier];
        if (func(day)) dayModifiers.push(modifier);
      }
    }
    return dayModifiers;
  },

  render() {
    return (

          { this.renderNavButton('left') }
          { this.state.month.format('MMMM YYYY') }
          { this.renderNavButton('right') }

          { this.renderWeekHeader() }

          { this.renderWeeks() }

    );
  },

  renderNavButton(position) {
    const className = `daypicker__nav daypicker__nav--${position}`;
    const handler = position === 'left' ?  this.handlePrevTouchTap :  this.handleNextTouchTap;

    return ;
  },

  renderWeeks() {
    return weeks(this.state.month).map((week, i) => {
      return (

          { this.renderDays(week) }

      );
    });
  },

  renderWeekHeader() {
    var header = [];
    for (let i = 0; i < 7; i++) {
      header.push(

          { moment().weekday(i).format('dd') }

      )
    }
    return header;
  },

  renderDays(week) {
    const firstDay = week[0];
    const lastDay = week[week.length-1];

    var days = week.map(day => this.renderDay(day));

    // days belonging to the previous month
    for (let i = 0; i < firstDay.weekday(); i++) {
      var prevDay = firstDay.clone().subtract(i+1, 'day');
      days.unshift(this.renderDay(prevDay, true));
    }

    // days belonging to the next month
    for (let j = lastDay.weekday() + 1, count = 1; j < 7; j++, count++) {
      var nextDay = lastDay.clone().add(count, 'day');
      days.push(this.renderDay(nextDay, true));
    }

    return days;
  },

  renderDay(day, otherMonth) {
    const modifiers = this.getModifiersForDay(day);

    var className = 'daypicker__day';
    if (otherMonth) className += ' daypicker__day--other-month';
    className += modifiers.map((mod) => { return ' daypicker__day--' + mod }).join('');

    return (

        { day.format('D') }

    );
  }

});

export default DayPicker;<commit_msg>Add dayClick event<commit_after>import React from 'react';
import moment from 'moment';
import { weeks } from './utils';

const DayPicker = React.createClass({

  propTypes: {

    initialMonth: React.PropTypes.object, // default is current month
    modifiers: React.PropTypes.object,

    onDayClick: React.PropTypes.func,
    onDayTouchTap: React.PropTypes.func, // requires react-tap-event-plugin enabled
    onDayMouseEnter: React.PropTypes.func,
    onDayMouseLeave: React.PropTypes.func

  },

  getDefaultProps() {
    return { initialMonth: moment() };
  },

  componentWillReceiveProps(nextProps) {
    this.setState({ month: nextProps.initialMonth });
  },

  getInitialState() {
    return { month: this.props.initialMonth.clone() };
  },

  handleDayTouchTap(day, modifiers, e) {
    this.props.onDayTouchTap && this.props.onDayTouchTap(day, modifiers, e);
  },

  handleDayClick(day, modifiers, e) {
    this.props.onDayClick && this.props.onDayClick(day, modifiers, e);
  },

  handleDayMouseEnter(day, modifiers, e) {
    this.props.onDayMouseEnter && this.props.onDayMouseEnter(day, modifiers, e);
  },

  handleDayMouseLeave(day, modifiers, e) {
    this.props.onDayMouseLeave && this.props.onDayMouseLeave(day, modifiers, e);
  },

  handleNextTouchTap(e) {
    this.setState({ month: this.state.month.add(1, 'month') });
  },

  handlePrevTouchTap(e) {
    this.setState({ month: this.state.month.subtract(1, 'month') });
  },

  getModifiersForDay(day) {
    var dayModifiers = [];
    if (this.props.modifiers) {
      const modifiers = this.props.modifiers;
      for (let modifier in modifiers) {
        var func = modifiers[modifier];
        if (func(day)) dayModifiers.push(modifier);
      }
    }
    return dayModifiers;
  },

  render() {
    return (

          { this.renderNavButton('left') }
          { this.state.month.format('MMMM YYYY') }
          { this.renderNavButton('right') }

          { this.renderWeekHeader() }

          { this.renderWeeks() }

    );
  },

  renderNavButton(position) {
    const className = `daypicker__nav daypicker__nav--${position}`;
    const handler = position === 'left' ?  this.handlePrevTouchTap :  this.handleNextTouchTap;

    return ;
  },

  renderWeeks() {
    return weeks(this.state.month).map((week, i) => {
      return (

          { this.renderDays(week) }

      );
    });
  },

  renderWeekHeader() {
    var header = [];
    for (let i = 0; i < 7; i++) {
      header.push(

          { moment().weekday(i).format('dd') }

      )
    }
    return header;
  },

  renderDays(week) {
    const firstDay = week[0];
    const lastDay = week[week.length-1];

    var days = week.map(day => this.renderDay(day));

    // days belonging to the previous month
    for (let i = 0; i < firstDay.weekday(); i++) {
      var prevDay = firstDay.clone().subtract(i+1, 'day');
      days.unshift(this.renderDay(prevDay, true));
    }

    // days belonging to the next month
    for (let j = lastDay.weekday() + 1, count = 1; j < 7; j++, count++) {
      var nextDay = lastDay.clone().add(count, 'day');
      days.push(this.renderDay(nextDay, true));
    }

    return days;
  },

  renderDay(day, otherMonth) {
    const modifiers = this.getModifiersForDay(day);

    var className = 'daypicker__day';
    if (otherMonth) className += ' daypicker__day--other-month';
    className += modifiers.map((mod) => { return ' daypicker__day--' + mod }).join('');

    return (

        onClick={this.handleDayClick.bind(this, day, modifiers)}>
        { day.format('D') }

    );
  }

});

export default DayPicker;<|endoftext|>


<commit_before>/**
ZLocator
**/

module.exports = zlocator;

var path = require('path');
var EE = require('events').EventEmitter;
var inherits = require('inherits');

var Promise = require('bluebird');
var Locator = require('locator');
var LocatorHandlebars = require('locator-handlebars');
var LocatorYUI = require('locator-yui');

var clean = require('./options').clean;

function zlocator(options, cb) {
    return new ZLocator(options, cb).promise;
}

zlocator.ZLocator = ZLocator;
inherits(ZLocator, EE);
function ZLocator(options, cb) {
    EE.call(this);
    this.options = clean(options || {});
    this.promise = this.getLocator().then(this.parseBundle).nodeify(cb);
}

ZLocator.prototype.getLocator = function () {
    var locator = new Locator({
        applicationDirectory: this.options.applicationDirectory,
        buildDirectory: this.options.buildDirectory
    });

    return Promise.resolve(locator).bind(this)
        .then(this.plugHandlebars)
        .then(this.plugYUI);
};

ZLocator.prototype._hbsNameParser = function () {
    var templateDirectory = this.options.templateDirectory;
    return function hbsNameParser(sourcePath) {
        // return path.basename(sourcePath, path.extname(sourcePath));
        return path.join(
            path.dirname(
                path.relative(templateDirectory, sourcePath)
            ),
            path.basename(sourcePath, path.extname(sourcePath))
        ).split(path.sep).join('-');
    };
};

ZLocator.prototype.plugHandlebars = function (locator) {
    var loch = new LocatorHandlebars({
        format: 'yui'
    });

    loch.describe.extensions.push('mustache');
    loch.nameParser = this._hbsNameParser();

    return locator.plug(loch);
};

ZLocator.prototype.plugYUI = function (locator) {
    var locy = new LocatorYUI({
        coverage: true,
        shifterOptions: {
            quiet: this.options.quiet
        }
    });

    return locator.plug(locy);
};

ZLocator.prototype.parseBundle = function (locator) {
    return locator.parseBundle(this.options.cwd, {
        bundleBuildDirectoryParser: function (bundle) {
            // return bundle.name + '-' + bundle.version; // default
            return bundle.name;
        }
    });
};
<commit_msg>pass a template prefix to zlocator handlebars<commit_after>/**
ZLocator
**/

module.exports = zlocator;

var path = require('path');
var EE = require('events').EventEmitter;
var inherits = require('inherits');

var Promise = require('bluebird');
var Locator = require('locator');
var LocatorHandlebars = require('locator-handlebars');
var LocatorYUI = require('locator-yui');

var clean = require('./options').clean;

function zlocator(options, cb) {
    return new ZLocator(options, cb).promise;
}

zlocator.ZLocator = ZLocator;
inherits(ZLocator, EE);
function ZLocator(options, cb) {
    EE.call(this);
    this.options = clean(options || {});
    this.promise = this.getLocator().then(this.parseBundle).nodeify(cb);
}

ZLocator.prototype.getLocator = function () {
    var locator = new Locator({
        applicationDirectory: this.options.applicationDirectory,
        buildDirectory: this.options.buildDirectory
    });

    return Promise.resolve(locator).bind(this)
        .then(this.plugHandlebars)
        .then(this.plugYUI);
};

ZLocator.prototype._hbsNameParser = function () {
    var templateDirectory = this.options.templateDirectory;
    return function hbsNameParser(sourcePath) {
        // return path.basename(sourcePath, path.extname(sourcePath));
        return path.join(
            path.dirname(
                path.relative(templateDirectory, sourcePath)
            ),
            path.basename(sourcePath, path.extname(sourcePath))
        ).split(path.sep).join('-');
    };
};

ZLocator.prototype.plugHandlebars = function (locator) {
    var loch = new LocatorHandlebars({
        prefix: 'z-tmpl',
        format: 'yui'
    });

    loch.describe.extensions.push('mustache');
    loch.nameParser = this._hbsNameParser();

    return locator.plug(loch);
};

ZLocator.prototype.plugYUI = function (locator) {
    var locy = new LocatorYUI({
        coverage: true,
        shifterOptions: {
            quiet: this.options.quiet
        }
    });

    return locator.plug(locy);
};

ZLocator.prototype.parseBundle = function (locator) {
    return locator.parseBundle(this.options.cwd, {
        bundleBuildDirectoryParser: function (bundle) {
            // return bundle.name + '-' + bundle.version; // default
            return bundle.name;
        }
    });
};
<|endoftext|>


<commit_before>/**
 * Representation of "Lists"
 * @module List
 * @author Haris Skiadas <skiadas@hanover.edu>
 * Barb Wahl <wahl@hanover.edu>
 * Bill Altermatt <altermattw@hanover.edu>
 */
(function(define) {'use strict';
define(function(require) {

   var Variable, utils;

   utils = require('./utils');
   Variable = require('./variable');

   /**
    * Lists are essentially objects that can be accessed by array indexing as well.
    * One can remove a "property" from a list, which results in the other properties
    * shifting place.
    *
    * Indexing starts at 1.
    *
    * List Properties:
    * - Array of values.
    * - Object that holds names as keys and array indices as values.
    *
    * To create a list:
    * - object
    * - array of unnamed values
    * - with no argument, create empty list
    */
   function List(values) {
      if (!(this instanceof List)) { return new List(values); }
      if (Array.isArray(values)) {
         this.values = [utils.missing].concat(values);
         this._names = this.values.map(function() { return utils.missing; });
      } else {
         // Given an object. Need to populate array based on it
         this._names = [utils.missing].concat(Object.keys(values || {}));
         this.values = this._names.map(function(key) {
            return utils.optionMap(key, function(key) { return values[key]; });
         });
      }
   }

   List.prototype = Object.create({});

   /* eslint-disable complexity */
   /**
    * this.names();
    * this.names(i);
    * this.names(i, newName);  // newName is a string or null (or evals to missing)
    * this.names(newNames);    // Array or Variable of strings/nulls
    * this.names(null);        // resets names
    */
   List.prototype.names = function names(i, newNames) {
      if (arguments.length === 0) {
         return utils.allMissing(this._names) ? utils.missing
                                              : Variable.string(this._names.slice(1));
      }
      if (arguments.length > 1) {
         this._names[i] = newNames;
      } else { // one argument, `i`
         if (utils.isMissing(i)) {
            this._names = this.values.map(function() { return utils.missing; });
            return this;
         }
         if (i instanceof Variable) { i = i.asString().toArray(); }
         if (!Array.isArray(i)) { return this._names[i]; }
         if (i.length !== this.length()) {
            throw new Error('Incompatible names length');
         }
         this._names = [utils.missing].concat(i);
      }
      return this;
   };
   /* eslint-enable */

   List.prototype.length = function length() {
      return this.values.length - 1;
   };

   /**
    * Given a name, returns the index of the corresponding column
    * or utils.missing if there isn't one.
    * Can also handle a number, or an array of mixed values
    */
   List.prototype.getIndexOf = function getIndexOf(name) {
      var names;
      names = this._names;
      function tester(n) {
         if (typeof n === 'number') { return n; }
         n = names.indexOf(n);
         return n === -1 ? utils.missing : n;
      }
      return Array.isArray(name) ? name.map(tester) : tester(name);
   };
   /**
    * i can be:
    * - index
    * - string name
    * - null/missing (return the array of values)
    */
   List.prototype.get = function get(i) {
      if (utils.isMissing(i)) { return this.values.slice(1); }
      return this.values[this.getIndexOf(i)];
   };

   /**
    * i can be:
    * - index:  If i > length of list, create new item at index i and fill the
    *           gap with missing
    * - string (name):  If i is not already a name in the list, append new item
    *                   with name `i`.  Else, update existing item with new value.
    * - object of name-value pairs (update existing, append new)
    * - array of values (append new)
    * val can be any sort of thing.
    * omit `val` if `i` is an object or array.
    */
   List.prototype.set = function set(i, val) {
      if (utils.isMissing(i)) { return this; }
      if (typeof i === 'number' || typeof i === 'string') {
         return this._set(i, val);
      }
      if (Array.isArray(i)) {
         i.forEach(function(v) {
            this._set(this.length() + 1, v);
         }.bind(this));
      } else {
         // i is an object
         Object.keys(i).forEach(function(key) {
            this._set(key, i[key]);
         }.bind(this));
      }
      return this;
   };

   // for setting exactly one value
   // `i` is a positive int or a name string
   // val is a thing
   List.prototype._set = function _set(i, val) {
      var name;
      if (utils.isMissing(i)) { return this; }
      if (typeof i === 'number') {
         i = Math.floor(i);
         if (i < 1) { throw new Error('cannot set at negative index: ' + i); }
         this.values[i] = val;
      } else {
         name = i;
         i = this._names.indexOf(name);
         if (i === -1) { // append
            i = this.length() + 1;
            this._names[i] = name;
         }
         this.values[i] = val;
      }
      return this;
   };

   /**
    * Delete the item in the `i` position (i integer or string)
    */
   List.prototype.delete = function _delete(i) {
    if (utils.isMissing(i)) { return this; }
    i = this.getIndexOf(i);
    if (i >= 1) {
      this.values.splice(i, 1);
      this._names.splice(i, 1);
    }
    return this;
   };

   /**
   * Takes a function `f(val, i, name)` and applies it to each value in this
   * list.  For any values with no associated name, `name` will be supplied as
   * `undefined`.
   */
   List.prototype.each = function each(f) {
      var i;
      for (i = 1; i <= this.length(); i += 1) {
         f(this.values[i], i, this._names[i]);
      }
      return this;
   };

   /**
    * Takes a function `f(acc, val, i, name)` and accumulates a return value.
    * For any values with no associated name, `name` will be supplied as
    * `undefined`.
    */
   List.prototype.reduce = function reduce(f, initial) {
      var i, acc;
      acc = initial;
      for (i = 1; i <= this.length(); i += 1) {
         acc = f(acc, this.values[i], i, this._names[i]);
      }
      return acc;
   };

   /**
    * Takes a function `f(val, i, name)` and applies it to each value in this
    * list to create a new list.  For any values with no associated name,
    * `name` will be supplied as `undefined`.
    */
   List.prototype.map = function map(f) {
      var arr;
      arr = [];
      this.each(function(val, i, name) {
         arr.push(f(val, i, name));
      });
      return (new List(arr)).names(
         utils.optionMap(this.names(), function(nms) { return nms.toArray(); })
      );
   };

   /**
    * Clones a list. Calls clone on any top-level values in the list that have
    * a clone method.
    */
   List.prototype.clone = function clone() {
      return this.map(function(val) { return val.clone ? val.clone() : val; });
   };

   /**
    * Returns a new Variable without changing this List.
    * Works for values which are among the following (mixed ok):
    * - single value
    * - array
    * - Vector
    * - Variable
    * - List
    * Names are generated for the new Variable.  The general idea is
    * to preserve any names in this list and/or in the values of this
    * list in some reasonble way, wherever they exist.
    * - If variable with names, and list entry also named, join the names
    * - If variable with names, and list entry not named, use variable name
    * - If variable without names, and list entry named, provide lname.1, ...
    */
   List.prototype.toVariable = function toVariable() {
      var resolvedEntries;
      resolvedEntries = this.get().map(function(val, i) {
         if (val instanceof List) { return val.toVariable(); }
         if (val instanceof Variable) { return val.clone(); }
         val = Variable.oneDimToVariable(val);
         return val instanceof Variable ? val : new Variable([val]);
      });
      resolvedEntries.forEach(function(val, i) {
         val.names(joinNames(this.names(i + 1),
                             val.names(),
                             val.length()));
      }.bind(this));
      return Variable.concat.apply(null, resolvedEntries);
   };

   /**
    * Unnests a number of levels out of a nested list, starting at the
    * top level. This operation changes the list in _in place_.
    * `levels` is the number of levels it will attempt to unnest.
    * Level 0 indicates no change. Default is 1.
    * Level Infinity indicates complete unnesting.
    */
   List.prototype.unnest = function unnest(levels) {
      var i;
      if (arguments.length === 0) { levels = 1; }
      if (levels === 0) { return this; }
      if (levels > 1) {
         this.each(function(e) {
            if (e instanceof List) { e.unnest(levels - 1); }
         });
      }
      for (i = this.length(); i > 0; i -= 1) {
         if (this.values[i] instanceof List) {
            [].splice.apply(this._names,
               [i, 1].concat(
                  joinNames(this._names[i],
                            this.values[i].names(),
                            this.values[i].length()
                  )
               )
            );
            [].splice.apply(this.values,
               [i, 1].concat(this.values[i].get())
            );
         }
      }
      return this;
   };

   /* Helper methods */
   function joinNames(itemName, valueNames, length) {
      if (utils.isMissing(itemName)) {
         return Variable.ensureArray(valueNames);
      }
      if (utils.isMissing(valueNames)) {
         if (length === 1) { return [itemName]; }
         valueNames = Variable.Vector.seq(length);
      }
      return Variable.ensureArray(valueNames)
                     .map(function(s) { return itemName + '.' + s; });
   }

   return List;

});

}(typeof define === 'function' && define.amd ? define : function(factory) {
   'use strict';
   module.exports = factory(require);
}));
<commit_msg>Update documentation for list.js<commit_after>/**
 * Representation of "Lists"
 * @module List
 * @author Haris Skiadas <skiadas@hanover.edu>
 * Barb Wahl <wahl@hanover.edu>
 * Bill Altermatt <altermattw@hanover.edu>
 */
(function(define) {'use strict';
define(function(require) {

   var Variable, utils;

   utils = require('./utils');
   Variable = require('./variable');

   /**
    * A list is a collection of Javascript entities that can be accessed by index
    * or by name. One can remove an item from a list, which results in the other
    * items shifting place. One can also insert at the end of a list, or alter the
    * contents of the list.
    *
    * Indexing starts at 1.
    *
    * We can create a list by providing:
    * - an object containing the items to be placed in the list along with their names
    * - an array of items to be placed in the list, without names
    * - no arguments, resulting in an empty list
    */
   function List(values) {
      if (!(this instanceof List)) { return new List(values); }
      if (Array.isArray(values)) {
         this.values = [utils.missing].concat(values);
         this._names = this.values.map(function() { return utils.missing; });
      } else {
         // Given an object. Need to populate array based on it
         this._names = [utils.missing].concat(Object.keys(values || {}));
         this.values = this._names.map(function(key) {
            return utils.optionMap(key, function(key) { return values[key]; });
         });
      }
   }

   List.prototype = Object.create({});

   /* eslint-disable complexity */
   /**
    * Get or set the item names.
    *
    * - When called with no arguments, return a string `Variable` of all the names,
    * with `utils.missing` in place of any missing names. If no names exist,
    * returns `utils.missing`.
    * - When called with a single numeric argument `i`, return the name at the
    * given index.
    * - When called with a single array or `Variable` argument, set the names of the
    * list using the array/variable's elements.
    * - When called with a single `null` or `utils.missing` argument, set the names
    * to `utils.missing`.
    * - When called with two arguments `i`, `newName`, set the name of the `i`-th item
    * to `newName`.
    *
    *     var l = new List({ a: [1, 2], b: 3 });
    *     l.names();           // Variable(['a', 'b'])
    *     l.names(2);          // 'b'
    *     l.names(2, 'c');     // `l` is now { a: [1,2], c: 3 }
    *     l.names(['d', 'e']); // `l` is now { d: [1,2], e: 3 }
    *     l.names(null);       // `l` now has no names
    */
   List.prototype.names = function names(i, newNames) {
      if (arguments.length === 0) {
         return utils.allMissing(this._names) ? utils.missing
                                              : Variable.string(this._names.slice(1));
      }
      if (arguments.length > 1) {
         this._names[i] = newNames;
      } else { // one argument, `i`
         if (utils.isMissing(i)) {
            this._names = this.values.map(function() { return utils.missing; });
            return this;
         }
         if (i instanceof Variable) { i = i.asString().toArray(); }
         if (!Array.isArray(i)) { return this._names[i]; }
         if (i.length !== this.length()) {
            throw new Error('Incompatible names length');
         }
         this._names = [utils.missing].concat(i);
      }
      return this;
   };
   /* eslint-enable */

   /**
    * Return the length of the list (number of items)
    */
   List.prototype.length = function length() {
      return this.values.length - 1;
   };

   /**
    * Given a name, return the index of the item with that name
    * or utils.missing if there isn't one.
    * You may also instead pass a single number, or an array of names
    * and numbers, in which case an array of indices is returned.
    * Mostly meant as an internal method.
    */
   List.prototype.getIndexOf = function getIndexOf(name) {
      var names;
      names = this._names;
      function tester(n) {
         if (typeof n === 'number') { return n; }
         n = names.indexOf(n);
         return n === -1 ? utils.missing : n;
      }
      return Array.isArray(name) ? name.map(tester) : tester(name);
   };

   /**
    * Return a list item by index. The index `i` can be:
    * - a positive number
    * - a string name
    * - `null` or `utils.missing`; in this case, an array of all the items
    * is returned.
    */
   List.prototype.get = function get(i) {
      if (utils.isMissing(i)) { return this.values.slice(1); }
      return this.values[this.getIndexOf(i)];
   };

   /**
    * Called with two arguments `i`, `val`. Set the list item at a given index `i`.
    * `i` can be:
    * - a positive number. If `i` is greater than the length of the list,
    * create a new item at index `i` and fill the resulting gap with `utils.missing`.
    * - a string name:  If the name `i` is not already a name in the list, append a
    * new item with name `i`. Otherwise, update the existing item with the new value.
    * - an object of name-value pairs, causing a series of updates or appends, one for
    * each pair.
    * - an array of values, causing a series of appends of these (unnamed) items.
    *
    * `val` can be any Javascript entity. If `i` is an object or array, then `val` is
    * omitted.
    */
   List.prototype.set = function set(i, val) {
      if (utils.isMissing(i)) { return this; }
      if (typeof i === 'number' || typeof i === 'string') {
         return this._set(i, val);
      }
      if (Array.isArray(i)) {
         i.forEach(function(v) {
            this._set(this.length() + 1, v);
         }.bind(this));
      } else {
         // i is an object
         Object.keys(i).forEach(function(key) {
            this._set(key, i[key]);
         }.bind(this));
      }
      return this;
   };

   /**
    * Internal method used to set one item value. Requires two arguments,
    * an integer or string name `i` and a value `val`.
    */
   List.prototype._set = function _set(i, val) {
      var name;
      if (utils.isMissing(i)) { return this; }
      if (typeof i === 'number') {
         i = Math.floor(i);
         if (i < 1) { throw new Error('cannot set at negative index: ' + i); }
         this.values[i] = val;
      } else {
         name = i;
         i = this._names.indexOf(name);
         if (i === -1) { // append
            i = this.length() + 1;
            this._names[i] = name;
         }
         this.values[i] = val;
      }
      return this;
   };

   /**
    * Delete the item at index/name `i`. `i` may be a positive integer or string name.
    */
   List.prototype.delete = function _delete(i) {
    if (utils.isMissing(i)) { return this; }
    i = this.getIndexOf(i);
    if (i >= 1) {
      this.values.splice(i, 1);
      this._names.splice(i, 1);
    }
    return this;
   };

   /**
   * Apply the function `f(val, i, name)` to each item in the list.  For any
   * items with no associated name, `name` will be `utils.missing`.
   */
   List.prototype.each = function each(f) {
      var i;
      for (i = 1; i <= this.length(); i += 1) {
         f(this.values[i], i, this._names[i]);
      }
      return this;
   };

   /**
    * Apply the function `f(acc, val, i, name)` to each item in the list,
    * accumulating the result to be returned.
    *
    * For any values with no associated name, `name` will be supplied as
    * `utils.missing`.
    *
    * Similar to Javascript's `Array.prototype.reduce`.
    */
   List.prototype.reduce = function reduce(f, initial) {
      var i, acc;
      acc = initial;
      for (i = 1; i <= this.length(); i += 1) {
         acc = f(acc, this.values[i], i, this._names[i]);
      }
      return acc;
   };

   /**
    * Create a new list from the results of applying the function `f(val, i, name)`
    * to the items of the original list. For any values with no associated name,
    * `name` will be supplied as `utils.missing`.
    */
   List.prototype.map = function map(f) {
      var arr;
      arr = [];
      this.each(function(val, i, name) {
         arr.push(f(val, i, name));
      });
      return (new List(arr)).names(
         utils.optionMap(this.names(), function(nms) { return nms.toArray(); })
      );
   };

   /**
    * Clone the list. This method will attempt to make a deep clone by calling `clone`
    * on any top-level items in the list that have a clone method.
    */
   List.prototype.clone = function clone() {
      return this.map(function(val) { return val.clone ? val.clone() : val; });
   };

   /**
    * Return a `Variable` by concatenating the values from the list's items.
    * Works with items of any of the following types:
    * - single value
    * - Array, `Vector`, `Variable`
    * - `List`
    *
    * Names are generated for the new Variable base on the items' names in the list
    * as well as their names (if any) as PanthR objects. The idea is to preserve any
    * names in the list and/or in the values of the list in some reasonable way,
    * wherever they exist.
    * - If the item is a variable with names, and it is a named list item, join the names
    * - If the item is a variable with names, and it is an unnamed list item,
    * use the variable names
    * - If the item is a variable without names, and it is a named list item, provide
    * names of the form `itemName.1, itemName.2, ...`
    */
   List.prototype.toVariable = function toVariable() {
      var resolvedEntries;
      resolvedEntries = this.get().map(function(val, i) {
         if (val instanceof List) { return val.toVariable(); }
         if (val instanceof Variable) { return val.clone(); }
         val = Variable.oneDimToVariable(val);
         return val instanceof Variable ? val : new Variable([val]);
      });
      resolvedEntries.forEach(function(val, i) {
         val.names(joinNames(this.names(i + 1),
                             val.names(),
                             val.length()));
      }.bind(this));
      return Variable.concat.apply(null, resolvedEntries);
   };

   /**
    * Unnest a number of levels out of a nested list, starting at the
    * top level. `levels` is the number of levels it will attempt to unnest.
    * Level 0 indicates no change. Default is 1.
    * Level `Infinity` indicates complete unnesting.
    *
    * This method will only attempt to resolve nesting formed via `List` constructs,
    * and will not recurse into Javascript Objects or Arrays.
    *
    * BEWARE: This operation changes the list(s) _in place_.
    */
   List.prototype.unnest = function unnest(levels) {
      var i;
      if (arguments.length === 0) { levels = 1; }
      if (levels === 0) { return this; }
      if (levels > 1) {
         this.each(function(e) {
            if (e instanceof List) { e.unnest(levels - 1); }
         });
      }
      for (i = this.length(); i > 0; i -= 1) {
         if (this.values[i] instanceof List) {
            [].splice.apply(this._names,
               [i, 1].concat(
                  joinNames(this._names[i],
                            this.values[i].names(),
                            this.values[i].length()
                  )
               )
            );
            [].splice.apply(this.values,
               [i, 1].concat(this.values[i].get())
            );
         }
      }
      return this;
   };

   /* Helper methods */
   function joinNames(itemName, valueNames, length) {
      if (utils.isMissing(itemName)) {
         return Variable.ensureArray(valueNames);
      }
      if (utils.isMissing(valueNames)) {
         if (length === 1) { return [itemName]; }
         valueNames = Variable.Vector.seq(length);
      }
      return Variable.ensureArray(valueNames)
                     .map(function(s) { return itemName + '.' + s; });
   }

   return List;

});

}(typeof define === 'function' && define.amd ? define : function(factory) {
   'use strict';
   module.exports = factory(require);
}));
<|endoftext|>


<commit_before>// (C) Copyright 2014-2015 Hewlett Packard Enterprise Development LP

var React = require('react');
var Link = require('react-router').Link;
var Split = require('grommet/components/Split');
var Sidebar = require('grommet/components/Sidebar');
var Header = require('grommet/components/Header');
var Title = require('grommet/components/Title');
var Box = require('grommet/components/Box');
var Menu = require('grommet/components/Menu');
var Button = require('grommet/components/Button');
var CloseIcon = require('grommet/components/icons/base/Close');
var GrommetLogo = require('grommet/components/icons/Grommet');
var DocsMenu = require('./DocsMenu');
var DOM = require('grommet/utils/DOM');

var DocsSplit = React.createClass({

  propTypes: {
    contents: React.PropTypes.arrayOf(React.PropTypes.object),
    onChange: React.PropTypes.func,
    title: React.PropTypes.node.isRequired
  },

  contextTypes: {
    routePrefix: React.PropTypes.string.isRequired,
    rootPath: React.PropTypes.string.isRequired
  },

  getInitialState: function () {
    return {showMenu: true, responsive: 'multiple'};
  },

  componentDidMount: function () {
    this._scrollToAnchor();
  },

  componentDidUpdate: function () {
    this._scrollToAnchor();
  },

  _scrollToAnchor: function () {
    if (this.refs.doc) {
      var doc = this.refs.doc;
      var hash = window.location.hash.slice(1);
      if (hash) {
        var anchor = document.querySelectorAll('[id=' + hash + ']')[0];
        var scrollParent = DOM.findScrollParents(anchor)[0];
        scrollParent.scrollTop = anchor.offsetTop;
      } else {
        doc.scrollTop = 0;
      }
    }
  },

  _onResponsive: function (responsive) {
    this.setState({responsive: responsive});
    if ('multiple' === responsive) {
      this.setState({showMenu: true});
    }
    if ('single' === responsive) {
      this.setState({showMenu: false});
    }
    if (this.props.onChange) {
      this.props.onChange();
    }
  },

  _onMenuOpen: function () {
    this.setState({showMenu: true});
  },

  _onMenuClick: function () {
    if ('single' === this.state.responsive) {
      this.setState({showMenu: false});
    }
    // allow time for hash to change
    setTimeout(this._scrollToAnchor, 1);
    if (this.props.onChange) {
      this.props.onChange();
    }
  },

  _renderTitle: function () {
    return (
      <Title responsive={false}>
        <Link to={this.context.rootPath}>
          <Box align="center" direction="row">
            <GrommetLogo />
          </Box>
        </Link>
      </Title>
    );
  },

  _renderMenu: function () {
    var title = this._renderTitle();
    var closer;
    if ('single' === this.state.responsive) {
      closer = (
        <Button icon={<CloseIcon />} onClick={this._onMenuClick} />
      );
    }
    return (
      <Sidebar size="small" primary={true} separator="right">

          {title}
          {closer}

        <DocsMenu direction="column"
          title={this.props.title} contents={this.props.contents}
          onClick={this._onMenuClick} />
      </Sidebar>
    );
  },

  _renderDoc: function () {
    var header;
    if ('single' === this.state.responsive) {
      var title = this._renderTitle();
      header = (

          {title}
          <Menu direction="row" responsive={false}>
            Contents
          </Menu>

      );
    }
    return (

        {header}
        {this.props.children}

    );
  },

  render: function() {
    var left;
    var right;
    if (this.state.showMenu) {
      left = this._renderMenu();
      if ('multiple' === this.state.responsive) {
        right = this._renderDoc();
      }
    } else {
      left = this._renderDoc();
    }

    return (
      <Split flex="right" fixed={true} onResponsive={this._onResponsive}>
        {left}
        {right}
      </Split>
    );
  }
});

module.exports = DocsSplit;
<commit_msg>Fixed duplicated skip to main content.<commit_after>// (C) Copyright 2014-2015 Hewlett Packard Enterprise Development LP

var React = require('react');
var Link = require('react-router').Link;
var Split = require('grommet/components/Split');
var Sidebar = require('grommet/components/Sidebar');
var Header = require('grommet/components/Header');
var Title = require('grommet/components/Title');
var Box = require('grommet/components/Box');
var Menu = require('grommet/components/Menu');
var Button = require('grommet/components/Button');
var CloseIcon = require('grommet/components/icons/base/Close');
var GrommetLogo = require('grommet/components/icons/Grommet');
var DocsMenu = require('./DocsMenu');
var DOM = require('grommet/utils/DOM');

var DocsSplit = React.createClass({

  propTypes: {
    contents: React.PropTypes.arrayOf(React.PropTypes.object),
    onChange: React.PropTypes.func,
    title: React.PropTypes.node.isRequired
  },

  contextTypes: {
    routePrefix: React.PropTypes.string.isRequired,
    rootPath: React.PropTypes.string.isRequired
  },

  getInitialState: function () {
    return {showMenu: true, responsive: 'multiple'};
  },

  componentDidMount: function () {
    this._scrollToAnchor();
  },

  componentDidUpdate: function () {
    this._scrollToAnchor();
  },

  _scrollToAnchor: function () {
    if (this.refs.doc) {
      var doc = this.refs.doc;
      var hash = window.location.hash.slice(1);
      if (hash) {
        var anchor = document.querySelectorAll('[id=' + hash + ']')[0];
        var scrollParent = DOM.findScrollParents(anchor)[0];
        scrollParent.scrollTop = anchor.offsetTop;
      } else {
        doc.scrollTop = 0;
      }
    }
  },

  _onResponsive: function (responsive) {
    this.setState({responsive: responsive});
    if ('multiple' === responsive) {
      this.setState({showMenu: true});
    }
    if ('single' === responsive) {
      this.setState({showMenu: false});
    }
    if (this.props.onChange) {
      this.props.onChange();
    }
  },

  _onMenuOpen: function () {
    this.setState({showMenu: true});
  },

  _onMenuClick: function () {
    if ('single' === this.state.responsive) {
      this.setState({showMenu: false});
    }
    // allow time for hash to change
    setTimeout(this._scrollToAnchor, 1);
    if (this.props.onChange) {
      this.props.onChange();
    }
  },

  _renderTitle: function () {
    return (
      <Title responsive={false}>
        <Link to={this.context.rootPath}>
          <Box align="center" direction="row">
            <GrommetLogo />
          </Box>
        </Link>
      </Title>
    );
  },

  _renderMenu: function () {
    var title = this._renderTitle();
    var closer;
    if ('single' === this.state.responsive) {
      closer = (
        <Button icon={<CloseIcon />} onClick={this._onMenuClick} />
      );
    }
    return (
      <Sidebar size="small" separator="right">

          {title}
          {closer}

        <DocsMenu direction="column"
          title={this.props.title} contents={this.props.contents}
          onClick={this._onMenuClick} />
      </Sidebar>
    );
  },

  _renderDoc: function () {
    var header;
    if ('single' === this.state.responsive) {
      var title = this._renderTitle();
      header = (

          {title}
          <Menu direction="row" responsive={false}>
            Contents
          </Menu>

      );
    }
    return (

        {header}
        {this.props.children}

    );
  },

  render: function() {
    var left;
    var right;
    if (this.state.showMenu) {
      left = this._renderMenu();
      if ('multiple' === this.state.responsive) {
        right = this._renderDoc();
      }
    } else {
      left = this._renderDoc();
    }

    return (
      <Split flex="right" fixed={true} onResponsive={this._onResponsive}>
        {left}
        {right}
      </Split>
    );
  }
});

module.exports = DocsSplit;
<|endoftext|>


<commit_before>var mAIMovable;
var mAIChara;
var mAIEnemyCharas;
var mAISkill;
var mAISkillList;
var mAICard;
var mAICardMark;
var mAICardNum;
var mAIPrioritys;

function AIConstructor(){
	mAIMovable=mMovable.concat();
	mAICard=mCard.concat();
	mAICardMark=new Array();
	mAICardNum=new Array();
	mAISkillList=mSkillList.concat();
	mAISkill=new Object();
	if(mDelayChara[1]=="T"){
		mAIChara = mTrueTeam[mDelayChara[2]];
		mAIEnemyCharas = mFalseTeam.concat();
	}
	else{
		mAIChara = mFalseTeam[mDelayChara[2]];
		mAIEnemyCharas = mTrueTeam.concat();
	}
	mAIPrioritys=new Array();
}

function com(aPlayerNum){//
	switch(aPlayerNum){
		case 1:
			AI_1();
			break;
		default:
	}
}

function AI_1(){//最大火力のマスを選択する簡単なAI
	AIConstructor();
	for(var i=0;i<mAIMovable.length;i++){
		var tX = mAIMovable[i][0];
		var tY = mAIMovable[i][1];
		mAICardNum=mAICard[tX+tY*8][0]
		mAICardMark=mAICard[tX+tY*8][1]

		//デッキの確認
		var tSkill;
		if(mAICardMark=="joker")		tSkill=mAIChara.deck[13];
		else if(mAICardMark=="suka")	tSkill=mAIChara.deck[14];
		else							tSkill=mAIChara.deck[mAICardNum];
		for(var j=0;j<mAISkillList.length;j++){
			if(mAISkillList[j].NUMBER==tSkill){
				mAISkill=mAISkillList[j];
				break;
			}
		}
		var tPriority = 0;

		let tRange=calcRange(mAISkill.RANGE,{x:tX,y:tY});
		if(mAICardMark=="joker"||mAICardMark=="suka"){
		}
		else if(mAIChara.MP>mAISkill.MAGIC){
		var tDamegeCharas = new Array();
			for(let i=0;i<tRange.length;i++){
				for(var j=0;j<mAIEnemyCharas.length;j++){
					if(tRange[i][0]==mAIEnemyCharas[j].x&&tRange[i][1]==mAIEnemyCharas[j].y){
						var tDamage = calcDamage(mAIChara.ATK,mAIEnemyCharas[j].DEF,mAISkill.POWER);

						if(mAICardMark==mAIChara.TYPE)	tDamage = Math.floor(tDamage*1.5);
						if(mAIEnemyCharas.HP<tDamage)	tPriority = Infinity;//倒せるなら決めに行く

						tPriority+=tDamage;
					}
				}
			}
		}

		if(mAISkill.M_ATTACK!=0&&mAIChara.MP>mAISkill.MAGIC){
			var tDamage = calcDamage(mAIChara.ATK,mAIChara.DEF,mAISkill.M_ATTACK);

			if(mAICardMark==mAIChara.TYPE)	tDamage = Math.floor(tDamage*1.5);
			if(mAIChara.originalHP>mAIChara.HP-tDamage)	tPriority-=tDamage;//過剰回復防止
			if(mAIChara.HP-tDamage<0)	tPriority = -Infinity;//自滅回避
		}

		tPriority*=100;
		for(var m=0;m<mAIEnemyCharas.length;m++){//敵から遠くにはいかない
			tPriority -= Math.abs(tX-mAIEnemyCharas[m].x);
			tPriority -= Math.abs(tY-mAIEnemyCharas[m].y);
		}
		mAIPrioritys.push(tPriority);
	}

	var tSelected=0;//優先度最大を選択
	var tMax = -Infinity;
	for(var i=0;i<mAIPrioritys.length;i++){
		if(mAIPrioritys[i]>tMax){
			tSelected=i;
			tMax=mAIPrioritys[i];
		}
	}

	//移動を実行
	// move(mAIMovable[tSelected][0],mAIMovable[tSelected][1]);
}

function calcSupportPriority(){
	return;
}<commit_msg>サポート行動を加味したAIの実装<commit_after>var mAIMovable;
var mAIChara;
var mAICharaTeam;
var mAIEnemyTeam;
var mAISkill;
var mAISkillList;
var mAICard;
var mAICardMark;
var mAICardNum;
var mAIPrioritys;
var mReversCards=4;//裏向いてる数

function AIConstructor(){
	mAIMovable=mMovable.concat();
	mAICard=mCard.concat();
	mAICardMark=new Array();
	mAICardNum=new Array();
	mAISkillList=mSkillList.concat();
	mAISkill=new Object();
	if(mDelayChara[1]=="T"){
		mAIChara = mTrueTeam[mDelayChara[2]];
		mAICharaTeam = mTrueTeam.concat();
		mAIEnemyTeam = mFalseTeam.concat();
	}
	else{
		mAIChara = mFalseTeam[mDelayChara[2]];
		mAICharaTeam = mFalseTeam.concat();
		mAIEnemyTeam = mTrueTeam.concat();
	}
	mAIPrioritys=new Array();
}

function com(aPlayerNum){//
	switch(aPlayerNum){
		case 1:
			AI_1();
			break;
		default:
	}
}

function AI_1(){//最大火力のマスを選択する簡単なAI
	AIConstructor();
	for(var i=0;i<mAIMovable.length;i++){
		var tX = mAIMovable[i][0];
		var tY = mAIMovable[i][1];
		mAICardNum=mAICard[tX+tY*8][0]
		mAICardMark=mAICard[tX+tY*8][1]

		//デッキの確認
		var tSkill;
		if(mAICardMark=="joker")		tSkill=mAIChara.deck[13];
		else if(mAICardMark=="suka")	tSkill=mAIChara.deck[14];
		else							tSkill=mAIChara.deck[mAICardNum];
		for(var j=0;j<mAISkillList.length;j++){
			if(mAISkillList[j].NUMBER==tSkill){
				mAISkill=mAISkillList[j];
				break;
			}
		}
		var tPriority = 0;

		let tRange=calcRange(mAISkill.RANGE,{x:tX,y:tY});
		if(mAICardMark=="joker"||mAICardMark=="suka"/*||カードが裏向き*/){
			var tJokerSkill;
			for(var j=0;j<mAISkillList.length;j++){
				if(mAISkillList[j].NUMBER==mAIChara.deck[13]){
					tJokerSkill=mAISkillList[j];
					break;
				}
			}
			if(mAIChara.MP>tJokerSkill.MAGIC){
				tPriority += tJokerSkill.POWER*mAIEnemyTeam.length;//今のところジョーカーは攻撃なら敵全体なので
				tPriority += calcSupportPriority(tJokerSkill);
				tPriority /= mReversCards;//期待値
				//if(mAICardMark=="suka"&&表向いてたら){
					// tPriority = -Infinity;
				// }
			}
		}
		else if(mAIChara.MP>mAISkill.MAGIC){
			for(let i=0;i<tRange.length;i++){
				var tDamegeCharas = new Array();
				for(var j=0;j<mAIEnemyTeam.length;j++){
					if(tRange[i][0]==mAIEnemyTeam[j].x&&tRange[i][1]==mAIEnemyTeam[j].y){
						var tDamage = calcDamage(mAIChara.ATK,mAIEnemyTeam[j].DEF,mAISkill.POWER);

						if(mAICardMark==mAIChara.TYPE)	tDamage = Math.floor(tDamage*1.5);
						if(mAIEnemyTeam[j].HP<tDamage)	tPriority = Infinity;//倒せるなら決めに行く

						tPriority+=tDamage;
						tPriority-=SupportPriorityPoint(mAISkill.SUPPORT_Af_Enemy);
						tPriority-=SupportPriorityPoint(mAISkill.SUPPORT_Be_Enemy);
					}
				}
			}

			if(mAISkill.M_ATTACK!=0){
				var tDamage = calcDamage(mAIChara.ATK,mAIChara.DEF,mAISkill.M_ATTACK);

				if(mAICardMark==mAIChara.TYPE)	tDamage = Math.floor(tDamage*1.5);
				if(mAIChara.originalHP>mAIChara.HP-tDamage)	tPriority -= Infinity;//過剰回復防止
				if(mAIChara.HP<tDamage)	tPriority = -Infinity;//自滅回避
				if(tDamage<0) tDamage *= (mAIChara.originalHP/mAIChara.HP)/2//半分で等倍　少ないと優先度が上がる
				tPriority+=tDamage;
			}

			if(mAISkill.F_ATTACK==true){
				for(let i=0;i<tRange.length;i++){
					tDamegeCharas = new Array();
					for(var j=0;j<mAICharaTeam.length;j++){
						if(tRange[i][0]==mAICharaTeam[j].x&&tRange[i][1]==mAICharaTeam[j].y){
							var tDamage = calcDamage(mAIChara.ATK,mAICharaTeam[j].DEF,mAISkill.POWER);

							if(mAICardMark==mAIChara.TYPE)	tDamage = Math.floor(tDamage*1.5);
							if(mAICharaTeam[j].HP<tDamage)	tPriority = -Infinity;//味方が死ぬのはアウト
							if(mAICharaTeam[j].HP-tDamage>mAICharaTeam[j].originalHP)	tPriority = -Infinity;//過剰回復防止
							if(tDamage<0) tDamage *= (mAICharaTeam[j].originalHP/mAICharaTeam[j].HP)/2//半分で等倍　少ないと優先度が上がる

							tPriority-=tDamage;
							tPriority+=SupportPriorityPoint(mAISkill.SUPPORT_Af_Enemy);
							tPriority+=SupportPriorityPoint(mAISkill.SUPPORT_Be_Enemy);
						}
					}
				}
			}
			tPriority += SupportPriorityPoint(mAISkill.SUPPORT_Af_Myself);
			tPriority += SupportPriorityPoint(mAISkill.SUPPORT_Be_Myself);
		}

		tPriority*=100;
		for(var m=0;m<mAIEnemyTeam.length;m++){//敵から遠くにはいかない
			tPriority -= Math.abs(tX-mAIEnemyTeam[m].x);
			tPriority -= Math.abs(tY-mAIEnemyTeam[m].y);
		}
		mAIPrioritys.push(tPriority);
	}

	var tSelected=0;//優先度最大を選択
	var tMax = -Infinity;
	for(var i=0;i<mAIPrioritys.length;i++){
		if(mAIPrioritys[i]>tMax){
			tSelected=i;
			tMax=mAIPrioritys[i];
		}
	}

	//移動を実行
	move(mAIMovable[tSelected][0],mAIMovable[tSelected][1]);
}

function calcSupportPriority(aSkill){//作者のさじ加減
	var tPriority = 0;
	tPriority += SupportPriorityPoint(aSkill.SUPPORT_Be_Myself);
	tPriority += SupportPriorityPoint(aSkill.SUPPORT_Af_Myself);
	tPriority -= SupportPriorityPoint(aSkill.SUPPORT_Be_Enemy);
	tPriority -= SupportPriorityPoint(aSkill.SUPPORT_Af_Enemy);
	return tPriority;
}

function SupportPriorityPoint(aSupportNum){
	var tAddPriority = 0;
	for (var i = 0; i < aSupportNum.length; i++) {
		var tPriority = 0;
		switch(aSupportNum[i][0]){
			case "resetStatus"://ステーテスを初期値に戻す
				tPriority -= 1;
			case "shuffle"://シャッフルする
			case "revers"://裏カードを表に向ける
			case "type"://タイプ変更
				tPriority += 0;
				break;
			case "delay"://delay
				tPriority += 0.1 * aSupportNum[i][1];
				if(aSupportNum[i][1]) tPriority = 0;
				break;
			case "mov"://mov変化 +2
				tPriority += 0.5;
			case "spd"://spd変化 +1.5
				tPriority += 0.5;
			case "mp"://MP +1
			case "atk"://at変化
				tPriority += 0.5;
			case "originalHP":
			case "originalMP":
			case "def"://def変化 +0.5
				tPriority +=　0.5;
				if(aSupportNum[i][2]!=undefined&&mAIChara.TYPE==mAICardMark) tPriority += aSupportNum[i][2];
				break;
			case "transform"://変身する
				if(aSupportNum[i][1]==0||aSupportNum[i][1]==1||aSupportNum[i][1]==2) tPriority+=10;
				else if(aSupportNum[i][1]==3)	tPriority += ((mAIChara.originalMP - mAIChara.MP)/2)-mAIChara.originalMP/4;
				else if(aSupportNum[i][1]==4)	tPriority += mAIChara.MP/2-mAIChara.originalMP/4;
				break;
			default:
				tPriority +=0;
		}
		tAddPriority += tPriority;
	}

	tAddPriority = calcDamage(mAIChara.ATK,mAIChara.DEF,tAddPriority);
	return tAddPriority;
}<|endoftext|>


<commit_before>/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.
 */

'use strict';

KylinApp.controller('ModelSchemaCtrl', function ($scope, QueryService, UserService, ProjectService, $q, AuthenticationService, $filter, ModelService, MetaModel, CubeDescModel, CubeList, TableModel, ProjectModel, $log, SweetAlert, modelsManager) {

  $scope.modelsManager = modelsManager;
  $scope.projectModel = ProjectModel;
  $scope.projects = [];
  $scope.newDimension = null;
  $scope.newMeasure = null;

  $scope.forms = {};

  $scope.wizardSteps = [
    {title: 'Model Info', src: 'partials/modelDesigner/model_info.html', isComplete: false, form: 'model_info_form'},
    {title: 'Data Model', src: 'partials/modelDesigner/data_model.html', isComplete: false, form: 'data_model_form'},
    {
      title: 'Dimensions',
      src: 'partials/modelDesigner/model_dimensions.html',
      isComplete: false,
      form: 'model_dimensions_form'
    },
    {
      title: 'Measures',
      src: 'partials/modelDesigner/model_measures.html',
      isComplete: false,
      form: 'model_measure_form'
    },
    {
      title: 'Settings',
      src: 'partials/modelDesigner/conditions_settings.html',
      isComplete: false,
      form: 'model_setting_form'
    }
  ];

  $scope.curStep = $scope.wizardSteps[0];

  // ~ init
  if (!$scope.state) {
    $scope.state = {mode: "view"};
  }
  //init modelsManager
  if ($scope.state.mode == "edit") {
    var defer = $q.defer();
    var queryParam = {};
    if (!$scope.projectModel.isSelectedProjectValid()) {
      return;
    }
    queryParam.projectName = $scope.projectModel.selectedProject;
    modelsManager.list(queryParam).then(function (resp) {
      defer.resolve(resp);
      modelsManager.loading = false;
      return defer.promise;
    });
  }

  $scope.$watch('model', function (newValue, oldValue) {
    if (!newValue) {
      return;
    }
    if ($scope.modelMode == "editExistModel" && newValue && !newValue.project) {
      initProject();
    }

  });

  // ~ public methods
  $scope.filterProj = function (project) {
    return $scope.userService.hasRole('ROLE_ADMIN') || $scope.hasPermission(project, $scope.permissions.ADMINISTRATION.mask);
  };

  $scope.removeElement = function (arr, element) {
    var index = arr.indexOf(element);
    if (index > -1) {
      arr.splice(index, 1);
    }
  };

  $scope.open = function ($event) {
    $event.preventDefault();
    $event.stopPropagation();

    $scope.opened = true;
  };

  $scope.preView = function () {
    var stepIndex = $scope.wizardSteps.indexOf($scope.curStep);
    if (stepIndex >= 1) {
      $scope.curStep.isComplete = false;
      $scope.curStep = $scope.wizardSteps[stepIndex - 1];
    }
  };

  $scope.nextView = function () {
    var stepIndex = $scope.wizardSteps.indexOf($scope.curStep);

    if (stepIndex < ($scope.wizardSteps.length - 1)) {
      $scope.curStep.isComplete = true;
      $scope.curStep = $scope.wizardSteps[stepIndex + 1];

      AuthenticationService.ping(function (data) {
        UserService.setCurUser(data);
      });
    }
  };

  $scope.checkForm = function () {
    if (!$scope.curStep.form) {
      return true;
    }
    if ($scope.state.mode === 'view') {
      return true;
    }
    else {
      //form validation
      if ($scope.forms[$scope.curStep.form].$invalid) {
        $scope.forms[$scope.curStep.form].$sbumitted = true;
        return false;
      } else {
        //business rule check
        switch ($scope.curStep.form) {
          case 'data_model_form':
            return $scope.check_data_model();
            break;
          case 'model_info_form':
            return $scope.check_model_info();
            break;
          case 'model_dimensions_form':
            return $scope.check_model_dimensions();
            break;
          case 'model_measure_form':
            return $scope.check_model_measure();
            break;
          case 'model_setting_form':
            return $scope.check_model_setting();
            break;
          default:
            return true;
            break;
        }
      }
    }
  };

  $scope.check_model_info = function () {

    var modelName = $scope.modelsManager.selectedModel.name.toUpperCase();
    var models = $scope.modelsManager.modelNameList;
    if (models.indexOf(modelName) != -1 || models.indexOf(modelName.toLowerCase()) !=-1) {
      SweetAlert.swal('', "Model named [" + modelName + "] already exist!", 'warning');
      return false;
    }
    return true;
  }

  /*
   * lookups can't be null
   */
  $scope.check_data_model = function () {
    var errors = [];
//        if(!modelsManager.selectedModel.lookups.length){
//            errors.push("No lookup table defined");
//        }
    var errorInfo = "";
    angular.forEach(errors, function (item) {
      errorInfo += "\n" + item;
    });
    if (errors.length) {
      SweetAlert.swal('', errorInfo, 'warning');
      return false;
    } else {
      return true;
    }

  }

  /*
   * dimensions validation
   * 1.dimension can't be null
   */
  $scope.check_model_dimensions = function () {

    var errors = [];
    if (!modelsManager.selectedModel.dimensions.length) {
      errors.push("No dimensions defined.");
    }
    angular.forEach(modelsManager.selectedModel.dimensions, function (_dimension) {
      if (!_dimension.columns || !_dimension.columns.length) {
        errors.push("No dimension columns defined for Table[" + _dimension.table + "]");
      }
    });
    var errorInfo = "";
    angular.forEach(errors, function (item) {
      errorInfo += "\n" + item;
    });
    if (errors.length) {
      SweetAlert.swal('Oops...', errorInfo, 'warning');
      return false;
    } else {
      return true;
    }

  };

  /*
   * dimensions validation
   * 1.metric can't be null
   */
  $scope.check_model_measure = function () {

    var errors = [];
    if (!modelsManager.selectedModel.metrics || !modelsManager.selectedModel.metrics.length) {
      errors.push("Please define your metrics.");
    }
    var errorInfo = "";
    angular.forEach(errors, function (item) {
      errorInfo += "\n" + item;
    });
    if (errors.length) {
      SweetAlert.swal('', errorInfo, 'warning');
      return false;
    } else {
      return true;
    }

  };
  $scope.check_model_setting = function () {
    var errors = [];
    if (modelsManager.selectedModel.partition_desc.partition_date_column != null && modelsManager.selectedModel.partition_desc.partition_date_start == null) {
      errors.push("Please indicate start date when partition date column selected.");
    }
    var errorInfo = "";
    angular.forEach(errors, function (item) {
      errorInfo += "\n" + item;
    });
    if (errors.length) {
      SweetAlert.swal('', errorInfo, 'warning');
      return false;
    } else {
      return true;
    }
  }

  $scope.goToStep = function (stepIndex) {
    if ($scope.state.mode == "edit") {
      if (stepIndex + 1 >= $scope.curStep.step) {
        return;
      }
    }
    for (var i = 0; i < $scope.wizardSteps.length; i++) {
      if (i <= stepIndex) {
        $scope.wizardSteps[i].isComplete = true;
      } else {
        $scope.wizardSteps[i].isComplete = false;
      }
    }
    if (stepIndex < ($scope.wizardSteps.length)) {
      $scope.curStep = $scope.wizardSteps[stepIndex];

      AuthenticationService.ping(function (data) {
        UserService.setCurUser(data);
      });
    }
  }

  // ~ private methods
  function initProject() {

  }
});
<commit_msg>KYLIN-919, do not validate model name when edit<commit_after>/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.
 */

'use strict';

KylinApp.controller('ModelSchemaCtrl', function ($scope, QueryService, UserService, ProjectService, $q, AuthenticationService, $filter, ModelService, MetaModel, CubeDescModel, CubeList, TableModel, ProjectModel, $log, SweetAlert, modelsManager) {

  $scope.modelsManager = modelsManager;
  $scope.projectModel = ProjectModel;
  $scope.projects = [];
  $scope.newDimension = null;
  $scope.newMeasure = null;

  $scope.forms = {};

  $scope.wizardSteps = [
    {title: 'Model Info', src: 'partials/modelDesigner/model_info.html', isComplete: false, form: 'model_info_form'},
    {title: 'Data Model', src: 'partials/modelDesigner/data_model.html', isComplete: false, form: 'data_model_form'},
    {
      title: 'Dimensions',
      src: 'partials/modelDesigner/model_dimensions.html',
      isComplete: false,
      form: 'model_dimensions_form'
    },
    {
      title: 'Measures',
      src: 'partials/modelDesigner/model_measures.html',
      isComplete: false,
      form: 'model_measure_form'
    },
    {
      title: 'Settings',
      src: 'partials/modelDesigner/conditions_settings.html',
      isComplete: false,
      form: 'model_setting_form'
    }
  ];

  $scope.curStep = $scope.wizardSteps[0];

  // ~ init
  if (!$scope.state) {
    $scope.state = {mode: "view"};
  }
  //init modelsManager
  if ($scope.state.mode == "edit") {
    var defer = $q.defer();
    var queryParam = {};
    if (!$scope.projectModel.isSelectedProjectValid()) {
      return;
    }
    queryParam.projectName = $scope.projectModel.selectedProject;
    modelsManager.list(queryParam).then(function (resp) {
      defer.resolve(resp);
      modelsManager.loading = false;
      return defer.promise;
    });
  }

  $scope.$watch('model', function (newValue, oldValue) {
    if (!newValue) {
      return;
    }
    if ($scope.modelMode == "editExistModel" && newValue && !newValue.project) {
      initProject();
    }

  });

  // ~ public methods
  $scope.filterProj = function (project) {
    return $scope.userService.hasRole('ROLE_ADMIN') || $scope.hasPermission(project, $scope.permissions.ADMINISTRATION.mask);
  };

  $scope.removeElement = function (arr, element) {
    var index = arr.indexOf(element);
    if (index > -1) {
      arr.splice(index, 1);
    }
  };

  $scope.open = function ($event) {
    $event.preventDefault();
    $event.stopPropagation();

    $scope.opened = true;
  };

  $scope.preView = function () {
    var stepIndex = $scope.wizardSteps.indexOf($scope.curStep);
    if (stepIndex >= 1) {
      $scope.curStep.isComplete = false;
      $scope.curStep = $scope.wizardSteps[stepIndex - 1];
    }
  };

  $scope.nextView = function () {
    var stepIndex = $scope.wizardSteps.indexOf($scope.curStep);

    if (stepIndex < ($scope.wizardSteps.length - 1)) {
      $scope.curStep.isComplete = true;
      $scope.curStep = $scope.wizardSteps[stepIndex + 1];

      AuthenticationService.ping(function (data) {
        UserService.setCurUser(data);
      });
    }
  };

  $scope.checkForm = function () {
    if (!$scope.curStep.form) {
      return true;
    }
    if ($scope.state.mode === 'view') {
      return true;
    }
    else {
      //form validation
      if ($scope.forms[$scope.curStep.form].$invalid) {
        $scope.forms[$scope.curStep.form].$sbumitted = true;
        return false;
      } else {
        //business rule check
        switch ($scope.curStep.form) {
          case 'data_model_form':
            return $scope.check_data_model();
            break;
          case 'model_info_form':
            return $scope.check_model_info();
            break;
          case 'model_dimensions_form':
            return $scope.check_model_dimensions();
            break;
          case 'model_measure_form':
            return $scope.check_model_measure();
            break;
          case 'model_setting_form':
            return $scope.check_model_setting();
            break;
          default:
            return true;
            break;
        }
      }
    }
  };

  $scope.check_model_info = function () {

    var modelName = $scope.modelsManager.selectedModel.name.toUpperCase();
    var models = $scope.modelsManager.modelNameList;
    if ($scope.modelMode=="addNewModel"&&models.indexOf(modelName) != -1 || models.indexOf(modelName.toLowerCase()) !=-1) {
      SweetAlert.swal('', "Model named [" + modelName + "] already exist!", 'warning');
      return false;
    }
    return true;
  }

  /*
   * lookups can't be null
   */
  $scope.check_data_model = function () {
    var errors = [];
//        if(!modelsManager.selectedModel.lookups.length){
//            errors.push("No lookup table defined");
//        }
    var errorInfo = "";
    angular.forEach(errors, function (item) {
      errorInfo += "\n" + item;
    });
    if (errors.length) {
      SweetAlert.swal('', errorInfo, 'warning');
      return false;
    } else {
      return true;
    }

  }

  /*
   * dimensions validation
   * 1.dimension can't be null
   */
  $scope.check_model_dimensions = function () {

    var errors = [];
    if (!modelsManager.selectedModel.dimensions.length) {
      errors.push("No dimensions defined.");
    }
    angular.forEach(modelsManager.selectedModel.dimensions, function (_dimension) {
      if (!_dimension.columns || !_dimension.columns.length) {
        errors.push("No dimension columns defined for Table[" + _dimension.table + "]");
      }
    });
    var errorInfo = "";
    angular.forEach(errors, function (item) {
      errorInfo += "\n" + item;
    });
    if (errors.length) {
      SweetAlert.swal('Oops...', errorInfo, 'warning');
      return false;
    } else {
      return true;
    }

  };

  /*
   * dimensions validation
   * 1.metric can't be null
   */
  $scope.check_model_measure = function () {

    var errors = [];
    if (!modelsManager.selectedModel.metrics || !modelsManager.selectedModel.metrics.length) {
      errors.push("Please define your metrics.");
    }
    var errorInfo = "";
    angular.forEach(errors, function (item) {
      errorInfo += "\n" + item;
    });
    if (errors.length) {
      SweetAlert.swal('', errorInfo, 'warning');
      return false;
    } else {
      return true;
    }

  };
  $scope.check_model_setting = function () {
    var errors = [];
    if (modelsManager.selectedModel.partition_desc.partition_date_column != null && modelsManager.selectedModel.partition_desc.partition_date_start == null) {
      errors.push("Please indicate start date when partition date column selected.");
    }
    var errorInfo = "";
    angular.forEach(errors, function (item) {
      errorInfo += "\n" + item;
    });
    if (errors.length) {
      SweetAlert.swal('', errorInfo, 'warning');
      return false;
    } else {
      return true;
    }
  }

  $scope.goToStep = function (stepIndex) {
    if ($scope.state.mode == "edit") {
      if (stepIndex + 1 >= $scope.curStep.step) {
        return;
      }
    }
    for (var i = 0; i < $scope.wizardSteps.length; i++) {
      if (i <= stepIndex) {
        $scope.wizardSteps[i].isComplete = true;
      } else {
        $scope.wizardSteps[i].isComplete = false;
      }
    }
    if (stepIndex < ($scope.wizardSteps.length)) {
      $scope.curStep = $scope.wizardSteps[stepIndex];

      AuthenticationService.ping(function (data) {
        UserService.setCurUser(data);
      });
    }
  }

  // ~ private methods
  function initProject() {

  }
});
<|endoftext|>


<commit_before>import React, { useState, useEffect, useContext } from 'react';
import PropTypes from 'prop-types';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import moment from 'moment';

import { formatBytes } from './utils';
import { SettingsContext } from './store';

const Information = (props) => {
  let {
    bytesReceived: bytesReceived,
    totalBytes: totalBytes,
    estimatedEndTime: estimatedEndTime,
    id: id,
    state: state,
    filename: filename,
    url: url,
    paused: paused,
  } = props.item;
  const {
    onOpenClick: onOpenClick,
    onCancelClick: onCancelClick,
    onPauseClick: onPauseClick,
    onResumeClick: onResumeClick,
  } = props;
  const { state } = useContext(SettingsContext);
  const isDarkMode = state.darkMode;
  const theme = isDarkMode === 'true' ? null : 'border-b';
  const buttonClassName =
    'bg-transparent hover:bg-blue-500 text-blue-500 font-semibold hover:text-white py-2 px-4 border border-blue-500 hover:border-transparent rounded';
  let textClassName = isDarkMode === 'true' ? 'text-blue-500' : 'text-gray-700';

  bytesReceived = formatBytes(bytesReceived, 0);
  totalBytes = formatBytes(totalBytes, 0);
  estimatedEndTime = moment(estimatedEndTime);
  const timeNow = moment();
  const minutesLeft = estimatedEndTime.diff(timeNow, 'minutes');
  let statusIcon = null;
  let information = null;

  if (state === 'complete') {
    textClassName = isDarkMode === 'true' ? 'text-blue-300' : 'text-gray-500';
    statusIcon = <FontAwesomeIcon icon="check" className="text-blue-500" />;

    information = (
      <button className={buttonClassName} data-id={id} onClick={onOpenClick}>
        Open
      </button>
    );
  } else if (state === 'interrupted') {
    textClassName = isDarkMode === 'true' ? 'text-blue-300' : 'text-gray-500';
    statusIcon = (
      <FontAwesomeIcon icon="exclamation-triangle" className="text-red-500" />
    );

    information = null;
  } else if (state === 'in_progress') {
    statusIcon = (
      <FontAwesomeIcon icon="spinner" className="text-blue-500" spin />
    );
    let button = (
      <button className={buttonClassName} data-id={id} onClick={onPauseClick}>
        Pause
      </button>
    );

    if (paused) {
      statusIcon = <FontAwesomeIcon icon="pause" className="text-blue-500" />;

      button = (
        <button
          className={buttonClassName}
          data-id={id}
          onClick={onResumeClick}
        >
          Resume
        </button>
      );
    }

    information = (
      <>
        {button}
        <button
          className={buttonClassName}
          data-id={id}
          onClick={onCancelClick}
        >
          Cancel
        </button>
      </>
    );
  }

  return (
    <div
      className={`grid max-content-columns-3 gap-2 p-5 items-center ${theme}`}
    >

{statusIcon}

{filename}

{url}

          {bytesReceived} of {totalBytes} / {minutesLeft} minutes left

{information}

  );
};

Information.propTypes = {
  item: PropTypes.object.isRequired,
  onOpenClick: PropTypes.func.isRequired,
  onCancelClick: PropTypes.func.isRequired,
  onPauseClick: PropTypes.func.isRequired,
  onResumeClick: PropTypes.func.isRequired,
};

export const Downloads = () => {
  const [complete, setComplete] = useState([]);
  const [interrupted, setInterrupted] = useState([]);
  const [inProgress, setInProgress] = useState([]);
  const [data, setData] = useState([]);

  useEffect(() => {
    const mergedData = [...complete, ...interrupted, ...inProgress];
    setData(mergedData);
  }, [complete, interrupted, inProgress]);

  useEffect(() => {
    const intervalComplete = setInterval(() => {
      chrome.downloads.search(
        {
          state: 'complete',
        },
        function (response) {
          if (response.length > 0) {
            setComplete(response);
          }
        }
      );
    }, 0);

    const intervalInterrupted = setInterval(() => {
      chrome.downloads.search(
        {
          state: 'interrupted',
        },
        function (response) {
          if (response.length > 0) {
            setInterrupted(response);
          }
        }
      );
    }, 0);

    const intervalInProgress = setInterval(() => {
      chrome.downloads.search(
        {
          state: 'in_progress',
        },
        function (response) {
          if (response.length > 0) {
            setInProgress(response);
          }
        }
      );
    }, 0);

    return function cleanup() {
      clearInterval(intervalComplete);
      clearInterval(intervalInterrupted);
      clearInterval(intervalInProgress);
    };
  }, []);

  const handleOpenClick = (e) => {
    const id = parseInt(e.currentTarget.dataset.id);
    chrome.downloads.show(id);
  };

  const handleCancelClick = (e) => {
    const id = parseInt(e.currentTarget.dataset.id);
    chrome.downloads.cancel(id);
  };

  const handlePauseClick = (e) => {
    const id = parseInt(e.currentTarget.dataset.id);
    chrome.downloads.pause(id);
  };

  const handleResumeClick = (e) => {
    const id = parseInt(e.currentTarget.dataset.id);
    chrome.downloads.resume(id);
  };

  const items = data.map((item, index) => {
    return (
      <Information
        key={`download-item-${index}`}
        item={item}
        onOpenClick={handleOpenClick}
        onCancelClick={handleCancelClick}
        onPauseClick={handlePauseClick}
        onResumeClick={handleResumeClick}
      />
    );
  });

  return
{items}
;
};
<commit_msg>Fix duplicate state<commit_after>import React, { useState, useEffect, useContext } from 'react';
import PropTypes from 'prop-types';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import moment from 'moment';

import { formatBytes } from './utils';
import { SettingsContext } from './store';

const Information = (props) => {
  let {
    bytesReceived: bytesReceived,
    totalBytes: totalBytes,
    estimatedEndTime: estimatedEndTime,
    id: id,
    state: downloadState,
    filename: filename,
    url: url,
    paused: paused,
  } = props.item;
  const {
    onOpenClick: onOpenClick,
    onCancelClick: onCancelClick,
    onPauseClick: onPauseClick,
    onResumeClick: onResumeClick,
  } = props;
  const { state } = useContext(SettingsContext);
  const isDarkMode = state.darkMode;
  const theme = isDarkMode === 'true' ? null : 'border-b';
  const buttonClassName =
    'bg-transparent hover:bg-blue-500 text-blue-500 font-semibold hover:text-white py-2 px-4 border border-blue-500 hover:border-transparent rounded';
  let textClassName = isDarkMode === 'true' ? 'text-blue-500' : 'text-gray-700';

  bytesReceived = formatBytes(bytesReceived, 0);
  totalBytes = formatBytes(totalBytes, 0);
  estimatedEndTime = moment(estimatedEndTime);
  const timeNow = moment();
  const minutesLeft = estimatedEndTime.diff(timeNow, 'minutes');
  let statusIcon = null;
  let information = null;

  if (downloadState === 'complete') {
    textClassName = isDarkMode === 'true' ? 'text-blue-300' : 'text-gray-500';
    statusIcon = <FontAwesomeIcon icon="check" className="text-blue-500" />;

    information = (
      <button className={buttonClassName} data-id={id} onClick={onOpenClick}>
        Open
      </button>
    );
  } else if (downloadState === 'interrupted') {
    textClassName = isDarkMode === 'true' ? 'text-blue-300' : 'text-gray-500';
    statusIcon = (
      <FontAwesomeIcon icon="exclamation-triangle" className="text-red-500" />
    );

    information = null;
  } else if (downloadState === 'in_progress') {
    statusIcon = (
      <FontAwesomeIcon icon="spinner" className="text-blue-500" spin />
    );
    let button = (
      <button className={buttonClassName} data-id={id} onClick={onPauseClick}>
        Pause
      </button>
    );

    if (paused) {
      statusIcon = <FontAwesomeIcon icon="pause" className="text-blue-500" />;

      button = (
        <button
          className={buttonClassName}
          data-id={id}
          onClick={onResumeClick}
        >
          Resume
        </button>
      );
    }

    information = (
      <>
        {button}
        <button
          className={buttonClassName}
          data-id={id}
          onClick={onCancelClick}
        >
          Cancel
        </button>
      </>
    );
  }

  return (
    <div
      className={`grid max-content-columns-3 gap-2 p-5 items-center ${theme}`}
    >

{statusIcon}

{filename}

{url}

          {bytesReceived} of {totalBytes} / {minutesLeft} minutes left

{information}

  );
};

Information.propTypes = {
  item: PropTypes.object.isRequired,
  onOpenClick: PropTypes.func.isRequired,
  onCancelClick: PropTypes.func.isRequired,
  onPauseClick: PropTypes.func.isRequired,
  onResumeClick: PropTypes.func.isRequired,
};

export const Downloads = () => {
  const [complete, setComplete] = useState([]);
  const [interrupted, setInterrupted] = useState([]);
  const [inProgress, setInProgress] = useState([]);
  const [data, setData] = useState([]);

  useEffect(() => {
    const mergedData = [...complete, ...interrupted, ...inProgress];
    setData(mergedData);
  }, [complete, interrupted, inProgress]);

  useEffect(() => {
    const intervalComplete = setInterval(() => {
      chrome.downloads.search(
        {
          state: 'complete',
        },
        function (response) {
          if (response.length > 0) {
            setComplete(response);
          }
        }
      );
    }, 0);

    const intervalInterrupted = setInterval(() => {
      chrome.downloads.search(
        {
          state: 'interrupted',
        },
        function (response) {
          if (response.length > 0) {
            setInterrupted(response);
          }
        }
      );
    }, 0);

    const intervalInProgress = setInterval(() => {
      chrome.downloads.search(
        {
          state: 'in_progress',
        },
        function (response) {
          if (response.length > 0) {
            setInProgress(response);
          }
        }
      );
    }, 0);

    return function cleanup() {
      clearInterval(intervalComplete);
      clearInterval(intervalInterrupted);
      clearInterval(intervalInProgress);
    };
  }, []);

  const handleOpenClick = (e) => {
    const id = parseInt(e.currentTarget.dataset.id);
    chrome.downloads.show(id);
  };

  const handleCancelClick = (e) => {
    const id = parseInt(e.currentTarget.dataset.id);
    chrome.downloads.cancel(id);
  };

  const handlePauseClick = (e) => {
    const id = parseInt(e.currentTarget.dataset.id);
    chrome.downloads.pause(id);
  };

  const handleResumeClick = (e) => {
    const id = parseInt(e.currentTarget.dataset.id);
    chrome.downloads.resume(id);
  };

  const items = data.map((item, index) => {
    return (
      <Information
        key={`download-item-${index}`}
        item={item}
        onOpenClick={handleOpenClick}
        onCancelClick={handleCancelClick}
        onPauseClick={handlePauseClick}
        onResumeClick={handleResumeClick}
      />
    );
  });

  return
{items}
;
};
<|endoftext|>