<commit_before>//Calculate the chromosomes margin
jviz.modules.ideogram.prototype.previewMargin = function()
{
  //Get the canvas draw zone
  var draw = this._canvas.draw();

  //Calculate free space
	var free = draw.width - this._genome.chromosomes.length * this._preview.chromosome.width;

	//Get the margin
	this._preview.margin = free / (this._genome.chromosomes.length - 1);
};

//Draw the preview
jviz.modules.ideogram.prototype.previewDraw = function()
{
  //Show loading
  this.loading(true);

  //Clear all layers
  this._canvas.clear();

  //Get the canvas draw zone
  var draw = this._canvas.draw();

  //Calculate the margin
  this.previewMargin();

  //Get the middle layer
  var canvas = this._canvas.layer(this._preview.layer);

  //Clear the canvas
  canvas.Clear();

  //Reset the karyotypes positions
  this._preview.positions = [];

  //Draw all the karyotypes
  for(var i = 0; i < this._genome.chromosomes.length; i++)
  {
    //Get the chromosome
    var chr = this._genome.chromosomes[i];

    //Get the mark for this chromosome
    //var marks = this.GetMarks(ch.id).length;
    var marks = 0;

    //Get the chromosome width
    var width = this._preview.chromosome.width;

    //Get the chromosome height
    var height = draw.height * (chr.length / this._preview.max);

    //Get the chromosome position x
    var posx = draw.margin.left + (i + 0) * this._preview.margin + i * this._preview.chromosome.width;

    //Get the chromosome position y
    var posy = draw.margin.top + draw.height - height;

    //Get the chromosome radius
    var radius = this._preview.chromosome.radius;

    //Draw the chromosome
    canvas.Rect({ x: posx, y: posy, width: width, height: height, radius: radius });

    //Set the chromsome fill color
    canvas.Fill({ color: this._fill.chromosome.color, opacity: this._fill.chromosome.opacity });

    //Save the position
    this._preview.positions.push({ x: posx, y: posy, width: width, height: height });

    //Check for draw the centromere
    if(typeof chr.centromere !== 'undefined')
    {
      //Centromere width
      var cent_width = this._preview.chromosome.width;

      //Centromere start
      var cent_start = draw.height * (chr.centromere[0] / this._preview.max);

      //Centromere end
      var cent_end = draw.height * (chr.centromere[1] / this._preview.max);

      //Centromere height
      var cent_height = Math.abs(cent_end - cent_start);

      //Centromere position x
      var cent_x = posx;

      //Centromere position y
      var cent_y = draw.margin.top + draw.height - cent_start;

      //Clear the centromere region
      canvas.Clear({ x: cent_x, y: cent_y, width: cent_width, height: cent_height });

      //Centromere points
      var cent = [];

      //Add the top point
      cent.push([cent_x, cent_y]);

      //Add the middle point
      cent.push([cent_x + cent_width / 2, cent_y + cent_height / 2]);

      //Add the end point
      cent.push([cent_x, cent_y + cent_height]);

      //Add the end right
      cent.push([cent_x + cent_width, cent_y + cent_height]);

      //Add the middle right
      cent.push([cent_x + cent_width / 2, cent_y + cent_height / 2]);

      //Add the top right
      cent.push([cent_x + cent_width, cent_y]);

      //Draw the lines
      canvas.Line(cent);

      //Add the fill color
      canvas.Fill({ color: this._fill.centromere.color, opacity: this._fill.centromere.opacity });
    }

    //Get the chromosome name
    var text_txt = chr.name;

    //Get the text position x
    var text_x = posx + this._preview.chromosome.width / 2;

    //Get the text position y
    var text_y = draw.margin.top + draw.height + this._preview.text.margin;

    //Get the text color
    var text_color = this._preview.text.color;

    //Get the text size
    var text_size = this._preview.text.size;

    //Get the text font
    var text_font = this._preview.text.font;

    //Get the text align
    var text_align = this._preview.text.align;

    //Draw the chromosome title
    canvas.Text({ x: text_x, y: text_y, text: text_txt, color: text_color, size: text_size, font: text_font, align: text_align });

    //Get the regions for this chromosome
    var regions = (typeof this._regions.list[chr.name] === 'undefined') ? [] : this._regions.list[chr.name];

    //Read all the regions
    for(var j = 0; j < regions.length; j++)
    {
      //Get the region
      var re = regions[j];

      //Region start
      var re_start = draw.height * (re.start / this._preview.max);

      //Region end
      var re_end = draw.height * (re.end / this._preview.max);

      //Region width
      var re_width = this._preview.chromosome.width;

      //Region height
      var re_height = Math.max(Math.abs(re_end - re_start), 1);

      //Region position x
      var re_x = posx;

      //Region position y
      var re_y = draw.margin.top + draw.height - re_start;

      //Draw the region
      canvas.Rect({ x: re_x, y: re_y, width: re_width, height: re_height });

      //Region fill
      canvas.Fill({ color: this._chromosome.regions.fill, opacity: this._chromosome.regions.opacity });
    }

    //Check the number of marks
    if(marks === 0){ continue; }

    //Get the mark rectangle position x
    var mark_x = posx + this._preview.width / 2 - this._marks.karyotypes.width / 2;

    //Get the mark rectange position y
    var mark_y = posy - this._marks.karyotypes.margin;

    //Get the mark rectange radius
    var mark_radius = this._marks.karyotypes.radius;

    //Get the mark width
    var mark_width = this._marks.karyotypes.width;

    //Get the mark rectangle height
    var mark_height = this._marks.karyotypes.height;

    //Draw the rectangle
    canvas.Rect({ x: mark_x, y: mark_y, width: mark_width, height: mark_height, radius: mark_radius });

    //Set the rectangle color
    canvas.Fill({ color: this._marks.fill });

    //Update the text position x
    this._marks.text.x = posx + this._preview.chromosome.width / 2;

    //Update the text position y
    this._marks.text.y = mark_y + this._marks.karyotypes.text;

    //Update the text
    this._marks.text.text = marks.toString();

    //Draw the text
    canvas.Text(this._marks.text);

    //Update the mark position x
    mark_x = posx + this._preview.width / 2;

    //Update the mark position y
    mark_y = mark_y + this._marks.karyotypes.height - this._marks.karyotypes.triangle;

    //Initialize the triangle array
    var tri = [];

    //Add the first point
    tri.push([ mark_x - this._marks.triangle, mark_y ]);

    //Add the middle point
    tri.push([ mark_x, mark_y + this._marks.triangle ]);

    //Add the first point
    tri.push([ mark_x + this._marks.triangle, mark_y ]);

    //Add the line
    canvas.Line(tri);

    //Add the fill color
    canvas.Fill(this._marks.fill);
  }

  //Reset the karyotypes hover
  this._preview.hover.index = -1;

  //Set loading as false
  this.loading(false);

  //Add the foot info
  this.foot(this._preview.foot.default);
};

//Get the chromosome
jviz.modules.ideogram.prototype.previewFindChromosome = function(x, y)
{
  //Get the actual draw
  var draw = this._canvas.draw();

  //Check for click on the margin left
  if(x < draw.margin.left + 0 * this._preview.margin){ return -1; }

  //Check for click on the margin right
  if(draw.margin.left + draw.width - 0 * this._preview.margin < x){return -1; }

  //Check for click on the margin top
  if(y < draw.margin.top){ return -1; }

  //Check for click on the margin bottom
  if(draw.margin.top + draw.height < y){ return -1; }

  //Read all the chromosomes positions
  for(var i = 0; i < this._preview.positions.length; i++)
  {
    //Get the position
    var pos = this._preview.positions[i];

    //Check the left position x
    if(x < pos.x){ return -1; }

    //Check the right position x
    if(pos.x + pos.width < x){ continue; }

    //Return the chromosome index
    return i;
  }

  //Default, return -1
  return -1;
};

//Clicked on a chromosome
jviz.modules.ideogram.prototype.previewClick = function(x, y)
{
  //Get the chromosome index
  var index = this.previewFindChromosome(x, y);

  //Check for undefined chromosome
  if(index === -1){ return; }

  //Get the chromosome info
  var chr = this._genome.chromosomes[index];

  //Emit the event
  var result = this.emit('click:chromosome', chr.name, index);

  //Check for undefined result
  if(result === false){ return; }

  //Open this chromosome
  this.chromosome(index);
};

//Draw the karyotypes hover
jviz.modules.ideogram.prototype.previewMove = function(x, y)
{
  //Get the hover chromosome
  var index = this.previewFindChromosome(x, y);

  //Check the index
  if(index === this._preview.hover.index){ return; }

  //Update the index
  this._preview.hover.index = index;

  //Get the canvas
  var canvas = this._canvas.layer(1);

  //Clear the canvas
  canvas.Clear();

  //Check for no chromosome
  if(index === -1)
  {
    //Reset the foot content
    this.foot(this._foot.default);

    //Remove the pointer cursor
    jviz.cursor.remove('pointer');

    //Exit
    return;
  }

  //Get the chromosome position
  var chr = this._preview.positions[index];

  //Calculate the hover position x
  var rect_x = chr.x - this._preview.hover.margin.left;

  //Calculate the hover position y
  var rect_y = chr.y - this._preview.hover.margin.top;

  //Calculate the hover width
  var rect_width = chr.width + this._preview.hover.margin.left + this._preview.hover.margin.right;

  //Calculate the hover height
  var rect_height = chr.height + this._preview.hover.margin.top + this._preview.hover.margin.bottom;

  //Get the hover radius
  var rect_radius = this._preview.hover.radius;

  //Draw
  canvas.Rect({ x: rect_x, y: rect_y, width: rect_width, height: rect_height, radius: rect_radius });

  //Set the fill color
  canvas.Fill({ color: this._preview.hover.color, opacity: this._preview.hover.opacity });

  //Get the chromosome name
  var chr_name = this._genome.chromosomes[index].name;

  //Get the regions on chromosome
  var chr_regions = (typeof this._regions.list[chr_name] !== 'undefined') ? this._regions.list[chr_name].length : 0;

  //Update the foot content
  this.foot(this._foot.chromosome.replace('{chromosome}', chr_name).replace('{regions}', chr_regions));

  //Add the pointer cursor
  jviz.cursor.set('pointer');
};

//Preview mouse leave
jviz.modules.ideogram.prototype.previewLeave = function()
{
  //Update the index
  this._preview.hover.index = -1;

  //Clear the canvas layer
  this._canvas.layer(1).Clear();
};
<commit_msg>js/preview.js: fix<commit_after>//Calculate the chromosomes margin
jviz.modules.ideogram.prototype.previewMargin = function()
{
  //Get the canvas draw zone
  var draw = this._canvas.draw();

  //Calculate free space
	var free = draw.width - this._genome.chromosomes.length * this._preview.chromosome.width;

	//Get the margin
	this._preview.margin = free / (this._genome.chromosomes.length - 1);
};

//Draw the preview
jviz.modules.ideogram.prototype.previewDraw = function()
{
  //Show loading
  this.loading(true);

  //Clear all layers
  this._canvas.clear();

  //Get the canvas draw zone
  var draw = this._canvas.draw();

  //Calculate the margin
  this.previewMargin();

  //Get the middle layer
  var canvas = this._canvas.layer(this._preview.layer);

  //Clear the canvas
  canvas.Clear();

  //Reset the karyotypes positions
  this._preview.positions = [];

  //Draw all the karyotypes
  for(var i = 0; i < this._genome.chromosomes.length; i++)
  {
    //Get the chromosome
    var chr = this._genome.chromosomes[i];

    //Get the mark for this chromosome
    //var marks = this.GetMarks(ch.id).length;
    var marks = 0;

    //Get the chromosome width
    var width = this._preview.chromosome.width;

    //Get the chromosome height
    var height = draw.height * (chr.length / this._preview.max);

    //Get the chromosome position x
    var posx = draw.margin.left + (i + 0) * this._preview.margin + i * this._preview.chromosome.width;

    //Get the chromosome position y
    var posy = draw.margin.top + draw.height - height;

    //Get the chromosome radius
    var radius = this._preview.chromosome.radius;

    //Draw the chromosome
    canvas.Rect({ x: posx, y: posy, width: width, height: height, radius: radius });

    //Set the chromsome fill color
    canvas.Fill({ color: this._fill.chromosome.color, opacity: this._fill.chromosome.opacity });

    //Save the position
    this._preview.positions.push({ x: posx, y: posy, width: width, height: height });

    //Check for draw the centromere
    if(typeof chr.centromere !== 'undefined')
    {
      //Centromere width
      var cent_width = this._preview.chromosome.width;

      //Centromere start
      var cent_start = draw.height * (chr.centromere[0] / this._preview.max);

      //Centromere end
      var cent_end = draw.height * (chr.centromere[1] / this._preview.max);

      //Centromere height
      var cent_height = Math.abs(cent_end - cent_start);

      //Centromere position x
      var cent_x = posx;

      //Centromere position y
      var cent_y = draw.margin.top + draw.height - cent_start;

      //Clear the centromere region
      canvas.Clear({ x: cent_x, y: cent_y, width: cent_width, height: cent_height });

      //Centromere points
      var cent = [];

      //Add the top point
      cent.push([cent_x, cent_y]);

      //Add the middle point
      cent.push([cent_x + cent_width / 2, cent_y + cent_height / 2]);

      //Add the end point
      cent.push([cent_x, cent_y + cent_height]);

      //Add the end right
      cent.push([cent_x + cent_width, cent_y + cent_height]);

      //Add the middle right
      cent.push([cent_x + cent_width / 2, cent_y + cent_height / 2]);

      //Add the top right
      cent.push([cent_x + cent_width, cent_y]);

      //Draw the lines
      canvas.Line(cent);

      //Add the fill color
      canvas.Fill({ color: this._fill.centromere.color, opacity: this._fill.centromere.opacity });
    }

    //Get the chromosome name
    var text_txt = chr.name;

    //Get the text position x
    var text_x = posx + this._preview.chromosome.width / 2;

    //Get the text position y
    var text_y = draw.margin.top + draw.height + this._preview.text.margin;

    //Get the text color
    var text_color = this._preview.text.color;

    //Get the text size
    var text_size = this._preview.text.size;

    //Get the text font
    var text_font = this._preview.text.font;

    //Get the text align
    var text_align = this._preview.text.align;

    //Draw the chromosome title
    canvas.Text({ x: text_x, y: text_y, text: text_txt, color: text_color, size: text_size, font: text_font, align: text_align });

    //Get the regions for this chromosome
    var regions = (typeof this._regions.list[chr.name] === 'undefined') ? [] : this._regions.list[chr.name];

    //Read all the regions
    for(var j = 0; j < regions.length; j++)
    {
      //Get the region
      var re = regions[j];

      //Region start
      var re_start = draw.height * (re.start / this._preview.max);

      //Region end
      var re_end = draw.height * (re.end / this._preview.max);

      //Region width
      var re_width = this._preview.chromosome.width;

      //Region height
      var re_height = Math.max(Math.abs(re_end - re_start), 1);

      //Region position x
      var re_x = posx;

      //Region position y
      var re_y = draw.margin.top + draw.height - re_start;

      //Draw the region
      canvas.Rect({ x: re_x, y: re_y, width: re_width, height: re_height });

      //Region fill
      canvas.Fill({ color: this._chromosome.regions.fill, opacity: this._chromosome.regions.opacity });
    }

    //Check the number of marks
    if(marks === 0){ continue; }

    //Get the mark rectangle position x
    var mark_x = posx + this._preview.width / 2 - this._marks.karyotypes.width / 2;

    //Get the mark rectange position y
    var mark_y = posy - this._marks.karyotypes.margin;

    //Get the mark rectange radius
    var mark_radius = this._marks.karyotypes.radius;

    //Get the mark width
    var mark_width = this._marks.karyotypes.width;

    //Get the mark rectangle height
    var mark_height = this._marks.karyotypes.height;

    //Draw the rectangle
    canvas.Rect({ x: mark_x, y: mark_y, width: mark_width, height: mark_height, radius: mark_radius });

    //Set the rectangle color
    canvas.Fill({ color: this._marks.fill });

    //Update the text position x
    this._marks.text.x = posx + this._preview.chromosome.width / 2;

    //Update the text position y
    this._marks.text.y = mark_y + this._marks.karyotypes.text;

    //Update the text
    this._marks.text.text = marks.toString();

    //Draw the text
    canvas.Text(this._marks.text);

    //Update the mark position x
    mark_x = posx + this._preview.width / 2;

    //Update the mark position y
    mark_y = mark_y + this._marks.karyotypes.height - this._marks.karyotypes.triangle;

    //Initialize the triangle array
    var tri = [];

    //Add the first point
    tri.push([ mark_x - this._marks.triangle, mark_y ]);

    //Add the middle point
    tri.push([ mark_x, mark_y + this._marks.triangle ]);

    //Add the first point
    tri.push([ mark_x + this._marks.triangle, mark_y ]);

    //Add the line
    canvas.Line(tri);

    //Add the fill color
    canvas.Fill(this._marks.fill);
  }

  //Reset the karyotypes hover
  this._preview.hover.index = -1;

  //Set loading as false
  this.loading(false);

  //Add the foot info
  this.foot(this._foot.default);
};

//Get the chromosome
jviz.modules.ideogram.prototype.previewFindChromosome = function(x, y)
{
  //Get the actual draw
  var draw = this._canvas.draw();

  //Check for click on the margin left
  if(x < draw.margin.left + 0 * this._preview.margin){ return -1; }

  //Check for click on the margin right
  if(draw.margin.left + draw.width - 0 * this._preview.margin < x){return -1; }

  //Check for click on the margin top
  if(y < draw.margin.top){ return -1; }

  //Check for click on the margin bottom
  if(draw.margin.top + draw.height < y){ return -1; }

  //Read all the chromosomes positions
  for(var i = 0; i < this._preview.positions.length; i++)
  {
    //Get the position
    var pos = this._preview.positions[i];

    //Check the left position x
    if(x < pos.x){ return -1; }

    //Check the right position x
    if(pos.x + pos.width < x){ continue; }

    //Return the chromosome index
    return i;
  }

  //Default, return -1
  return -1;
};

//Clicked on a chromosome
jviz.modules.ideogram.prototype.previewClick = function(x, y)
{
  //Get the chromosome index
  var index = this.previewFindChromosome(x, y);

  //Check for undefined chromosome
  if(index === -1){ return; }

  //Get the chromosome info
  var chr = this._genome.chromosomes[index];

  //Emit the event
  var result = this.emit('click:chromosome', chr.name, index);

  //Check for undefined result
  if(result === false){ return; }

  //Open this chromosome
  this.chromosome(index);
};

//Draw the karyotypes hover
jviz.modules.ideogram.prototype.previewMove = function(x, y)
{
  //Get the hover chromosome
  var index = this.previewFindChromosome(x, y);

  //Check the index
  if(index === this._preview.hover.index){ return; }

  //Update the index
  this._preview.hover.index = index;

  //Get the canvas
  var canvas = this._canvas.layer(1);

  //Clear the canvas
  canvas.Clear();

  //Check for no chromosome
  if(index === -1)
  {
    //Reset the foot content
    this.foot(this._foot.default);

    //Remove the pointer cursor
    jviz.cursor.remove('pointer');

    //Exit
    return;
  }

  //Get the chromosome position
  var chr = this._preview.positions[index];

  //Calculate the hover position x
  var rect_x = chr.x - this._preview.hover.margin.left;

  //Calculate the hover position y
  var rect_y = chr.y - this._preview.hover.margin.top;

  //Calculate the hover width
  var rect_width = chr.width + this._preview.hover.margin.left + this._preview.hover.margin.right;

  //Calculate the hover height
  var rect_height = chr.height + this._preview.hover.margin.top + this._preview.hover.margin.bottom;

  //Get the hover radius
  var rect_radius = this._preview.hover.radius;

  //Draw
  canvas.Rect({ x: rect_x, y: rect_y, width: rect_width, height: rect_height, radius: rect_radius });

  //Set the fill color
  canvas.Fill({ color: this._preview.hover.color, opacity: this._preview.hover.opacity });

  //Get the chromosome name
  var chr_name = this._genome.chromosomes[index].name;

  //Get the regions on chromosome
  var chr_regions = (typeof this._regions.list[chr_name] !== 'undefined') ? this._regions.list[chr_name].length : 0;

  //Update the foot content
  this.foot(this._foot.chromosome.replace('{chromosome}', chr_name).replace('{regions}', chr_regions));

  //Add the pointer cursor
  jviz.cursor.set('pointer');
};

//Preview mouse leave
jviz.modules.ideogram.prototype.previewLeave = function()
{
  //Update the index
  this._preview.hover.index = -1;

  //Clear the canvas layer
  this._canvas.layer(1).Clear();
};
<|endoftext|>


<commit_before>import React, { PureComponent } from 'react';
import PropTypes from 'prop-types';
import { Button, Spinner } from '@blueprintjs/core';
import {
  getSecondsFromPhase,
  hasReachedEnd,
  hasReachedLastRound,
  spinnerIntent,
  twoDigits
} from '../../../utils/countdown-timer.util';
import {
  getAllSounds
} from '../../../utils/sounds.util';

export default class CountdownTimer extends PureComponent {

  componentWillUnmount() {
    this.pause();
  }

  tick() {
    const {
      audioSelection,
      audioDisabled,
      currentPhase,
      currentRound,
      minutes,
      seconds,
      totalRounds,
      goToNextPhase,
      setMinutes,
      setSeconds,
      sounds
    } = this.props;

    const audio = sounds[audioSelection];

    if (seconds > 0) {
      setSeconds(seconds - 1);
      if (!audioDisabled) audio.play();
    } else if (minutes > 0) {
      setMinutes(minutes - 1);
      setSeconds(59);
      if (!audioDisabled) audio.play();
    } else {
      sounds[sounds.length - 1].play();
      if (hasReachedEnd(currentPhase, currentRound, minutes, seconds, totalRounds)) this.pause();
      goToNextPhase();
    }
  }

  pause() {
    const { pause: _pause } = this.props;
    clearInterval(this.ticker);
    _pause();
  }

  resume() {
    const {
      currentPhase,
      currentRound,
      minutes,
      seconds,
      totalRounds,
      resume: _resume,
    } = this.props;

    if (hasReachedEnd(currentPhase, currentRound, minutes, seconds, totalRounds)) return;

    this.ticker = setInterval(() => this.tick(), 1000);
    _resume();
  }

  onMediaControlClick() {
    const { isPlaying } = this.props;
    if (isPlaying) this.pause();
    else this.resume();
  }

  onSliderChange(value) {
    const { setMinutes, setSeconds } = this.props;
    setMinutes(value);
    setSeconds(0);
  }

  render() {
    const {
      currentPhase,
      currentRound,
      focusLength: fl,
      isPlaying,
      longBreakLength: lbl,
      minutes,
      seconds,
      shortBreakLength: sbl,
      totalRounds,
      goToNextPhase,
      openGeneralAlert,
      resetTimer
    } = this.props;

    const secsFromPhase = getSecondsFromPhase(minutes, seconds, fl, lbl, sbl, currentPhase);

    return (

            {twoDigits(minutes)}
            :
            {twoDigits(seconds)}

          <Spinner
            intent={spinnerIntent(currentPhase)}
            value={(secsFromPhase - ((minutes * 60) + seconds)) / secsFromPhase}
          />

          <Button
            iconName="redo"
            onClick={() => {
              openGeneralAlert('Are you sure you want to redo the current phase?', resetTimer);
            }}
            className="pt-large"
          />
          <Button
            active={isPlaying}
            iconName={isPlaying ? 'pause' : 'play'}
            onClick={() => this.onMediaControlClick()}
            className="pt-large mx-3"
          />
          <Button
            iconName="chevron-forward"
            disabled={hasReachedLastRound(currentPhase, currentRound, totalRounds)}
            onClick={goToNextPhase}
            className="pt-large"
          />

    );
  }
}

CountdownTimer.defaultProps = {
  sounds: getAllSounds()
};

CountdownTimer.propTypes = {
  audioDisabled: PropTypes.bool.isRequired,
  /*eslint-disable*/
  audioSelection: PropTypes.number.isRequired,
  /*eslint-enable*/
  currentRound: PropTypes.number.isRequired,
  currentPhase: PropTypes.number.isRequired,
  focusLength: PropTypes.number.isRequired,
  minutes: PropTypes.number.isRequired,
  isPlaying: PropTypes.bool.isRequired,
  longBreakLength: PropTypes.number.isRequired,
  seconds: PropTypes.number.isRequired,
  shortBreakLength: PropTypes.number.isRequired,
  totalRounds: PropTypes.number.isRequired,
  goToNextPhase: PropTypes.func.isRequired,
  openGeneralAlert: PropTypes.func.isRequired,
  pause: PropTypes.func.isRequired,
  resetTimer: PropTypes.func.isRequired,
  resume: PropTypes.func.isRequired,
  setMinutes: PropTypes.func.isRequired,
  setSeconds: PropTypes.func.isRequired,
  /*eslint-disable*/
  sounds: PropTypes.any
  /*eslint-enable*/
};
<commit_msg>feat: Add pause/play keybinding shortcuts<commit_after>import React, { PureComponent } from 'react';
import PropTypes from 'prop-types';
import { Button, Spinner } from '@blueprintjs/core';
import {
  getSecondsFromPhase,
  hasReachedEnd,
  hasReachedLastRound,
  spinnerIntent,
  twoDigits
} from '../../../utils/countdown-timer.util';
import {
  getAllSounds
} from '../../../utils/sounds.util';

export default class CountdownTimer extends PureComponent {
  constructor() {
    super();
    this.onMediaControlClick = this.onMediaControlClick.bind(this);
  }

  componentWillMount() {
    window.addEventListener('keyup', this.onMediaControlClick);
  }

  componentWillUnmount() {
    this.pause();
    window.removeEventListener('keyup', this.onMediaControlClick);
  }

  tick() {
    const {
      audioSelection,
      audioDisabled,
      currentPhase,
      currentRound,
      minutes,
      seconds,
      totalRounds,
      goToNextPhase,
      setMinutes,
      setSeconds,
      sounds
    } = this.props;

    const audio = sounds[audioSelection];

    if (seconds > 0) {
      setSeconds(seconds - 1);
      if (!audioDisabled) audio.play();
    } else if (minutes > 0) {
      setMinutes(minutes - 1);
      setSeconds(59);
      if (!audioDisabled) audio.play();
    } else {
      sounds[sounds.length - 1].play();
      if (hasReachedEnd(currentPhase, currentRound, minutes, seconds, totalRounds)) this.pause();
      goToNextPhase();
    }
  }

  pause() {
    const { pause: _pause } = this.props;
    clearInterval(this.ticker);
    _pause();
  }

  resume() {
    const {
      currentPhase,
      currentRound,
      minutes,
      seconds,
      totalRounds,
      resume: _resume,
    } = this.props;

    if (hasReachedEnd(currentPhase, currentRound, minutes, seconds, totalRounds)) return;

    this.ticker = setInterval(() => this.tick(), 1000);
    _resume();
  }

  onMediaControlClick() {
    const { isPlaying } = this.props;
    if (isPlaying) this.pause();
    else this.resume();
  }

  onSliderChange(value) {
    const { setMinutes, setSeconds } = this.props;
    setMinutes(value);
    setSeconds(0);
  }

  render() {
    const {
      currentPhase,
      currentRound,
      focusLength: fl,
      isPlaying,
      longBreakLength: lbl,
      minutes,
      seconds,
      shortBreakLength: sbl,
      totalRounds,
      goToNextPhase,
      openGeneralAlert,
      resetTimer
    } = this.props;

    const secsFromPhase = getSecondsFromPhase(minutes, seconds, fl, lbl, sbl, currentPhase);

    return (

            {twoDigits(minutes)}
            :
            {twoDigits(seconds)}

          <Spinner
            intent={spinnerIntent(currentPhase)}
            value={(secsFromPhase - ((minutes * 60) + seconds)) / secsFromPhase}
          />

          <Button
            iconName="redo"
            onClick={() => {
              openGeneralAlert('Are you sure you want to redo the current phase?', resetTimer);
            }}
            className="pt-large"
          />
          <Button
            active={isPlaying}
            iconName={isPlaying ? 'pause' : 'play'}
            onClick={this.onMediaControlClick}
            className="pt-large mx-3"
          />
          <Button
            iconName="chevron-forward"
            disabled={hasReachedLastRound(currentPhase, currentRound, totalRounds)}
            onClick={goToNextPhase}
            className="pt-large"
          />

    );
  }
}

CountdownTimer.defaultProps = {
  sounds: getAllSounds()
};

CountdownTimer.propTypes = {
  audioDisabled: PropTypes.bool.isRequired,
  /*eslint-disable*/
  audioSelection: PropTypes.number.isRequired,
  /*eslint-enable*/
  currentRound: PropTypes.number.isRequired,
  currentPhase: PropTypes.number.isRequired,
  focusLength: PropTypes.number.isRequired,
  minutes: PropTypes.number.isRequired,
  isPlaying: PropTypes.bool.isRequired,
  longBreakLength: PropTypes.number.isRequired,
  seconds: PropTypes.number.isRequired,
  shortBreakLength: PropTypes.number.isRequired,
  totalRounds: PropTypes.number.isRequired,
  goToNextPhase: PropTypes.func.isRequired,
  openGeneralAlert: PropTypes.func.isRequired,
  pause: PropTypes.func.isRequired,
  resetTimer: PropTypes.func.isRequired,
  resume: PropTypes.func.isRequired,
  setMinutes: PropTypes.func.isRequired,
  setSeconds: PropTypes.func.isRequired,
  /*eslint-disable*/
  sounds: PropTypes.any
  /*eslint-enable*/
};
<|endoftext|>


<commit_before>'use strict'

/**
 * Dependencies
 * @ignore
 */

/**
 * Module Dependencies
 * @ignore
 */
const Events = require('../events')
const SocketManager = require('../socket')

/**
 * Tag Manager
 * @class
 */
class TagManager {

  constructor () {
  }

}

/**
 * Export
 * @ignore
 */
module.exports = new TagManager()
<commit_msg>refactor(TagManager): to be incorporated into player manager<commit_after><|endoftext|>


<commit_before>/*   RSence
 *   Copyright 2006 Riassence Inc.
 *   http://riassence.com/
 *
 *   You should have received a copy of the GNU General Public License along
 *   with this software package. If not, contact licensing@riassence.com
 */

/*** = Description
  ** Main container of global operations on +HView+ and
  ** +HApplication+ -derived classes.
  **
  ** HSystem is used to keep +HApplication+ and +HView+ instances
  ** globally managed. The managed classes themself calls +HSystem+ methods,
  ** so there is no real need to access +HSystem+ directly from user-level code.
  **
***/
var//RSence.Foundation
HSystem = {

/** When the focus behaviour is 1, clicking on any subview brings
  * the window to front, if attached to a HWindow instance.
  * If the behaviour is 0, only direct clicks on the HWindow controls
  * brings the window to front.
  *
  **/
  windowFocusMode: 1,

/** Singleton class; has no constructor **/
  // constructor: null,

/** An array of HApplication instances, index is the appId **/
  apps: [],

/** An array (in the same order as apps): holds priority values **/
  appPriorities: [],

/** An array (in the same order as apps): holds busy status **/
  busyApps: [],

/** This array holds free app id:s **/
  freeAppIds: [],

/** The default HSystem ticker interval. Unit is milliseconds. **/
  defaultInterval: 10,

/** The default HApplication priority. Unit is "On the n:th tick: poll". **/
  defaultPriority: 20,

/** The z-index of root-level +HView+ instances. All the array operations
  * are done by the inner logic of +HApplication+ and +HView+ instances.
  **/
  viewsZOrder: [],

/** This is the internal "clock" counter. Gets updated on every tick. **/
  ticks: 0,

/** Time in milliseconds for the timeout of a poll to finish before
  * being classified as stuck and thus forcibly terminated.
  **/
  maxAppRunTime: 5000,

/** Calls applications, uses the prority as a prioritizer.
  **/
  scheduler: function(){

    // Loop through all applications:
    for( var _appId=0; _appId<this.apps.length; _appId++ ){
      // Check, if the application exists:
      if( this.apps[ _appId ] ){
        // Check, if the application is busy:
        if( !this.busyApps[ _appId ] ){
          // Check, if the tick count matches the priority of the app:
          if( (this.ticks % this.appPriorities[ _appId ]) === 0 ){
            // Set the app busy, the app itself should "unbusy" itself, when the idle call is done.
            // That happens in <HApplication._startIdle>

            // If the app is not busy, then make a idle call:
            if(HSystem.apps[_appId]){
              HSystem.apps[_appId]._startIdle();
            }
          }
        }
      }
    }

    if(this._updateZIndexOfChildrenBuffer.length!==0){
      this._flushUpdateZIndexOfChilden();
    }

  },

  _updateFlexibleRects: function(){
    var
    _view,
    i = 0;
    for( ; i < this.views.length; i++ ){
      _view = this.views[i];
      if(_view && (_view.flexRight || _view.flexBottom)){
        _view.rect._updateFlexibleDimensions();
      }
    }
  },

/** Calls the scheduler and then calls itself after a timeout to keep
  * the loop going on.
  **/
  ticker: function(){
    // Increment the tick counter:
    this.ticks++;
    this.scheduler();
    this._tickTimeout = setTimeout( function(){HSystem.ticker();},this.defaultInterval);
  },

/** = Description
  * Adds the structures needed for a new +HApplication+ instance.
  *
  * Called from inside the +HApplication+ constructor.
  * Binds an app and gives it a unique id.
  *
  * = Parameters
  * +_app+::       The reference to the +HApplication+ instance object.
  * +_priority+::  The app priority.
  *
  * = Returns
  * The app id.
  *
  **/
  addApp: function(_app, _priority){
    var _appId;
    if(this.freeAppIds.length !== 0){
      _appId = this.freeAppIds.unshift();
      this.apps[_appId] = _app;
    } else {
      this.apps.push(_app);
      _appId = this.apps.length-1;
    }

    // sets self as parent
    _app.parent  = this;
    _app.parents = [this];

    _app.appId = _appId;

    this.startApp(_appId, _priority);

    return _appId;
  },

/** = Description
  * Starts polling an app instance (and its components).
  *
  * = Parameters
  * +_appId+::      The unique id of the app.
  * +_priority+::   The app priority.
  *
  **/
  startApp: function(_appId,_priority){
    if(_priority===undefined){
      _priority = this.defaultInterval;
    }
    this.appPriorities[ _appId ] = _priority;
    this.busyApps[_appId] = false;
  },

/** = Description
  * Stops polling an app instance (and its components).
  *
  * = Parameters
  * +_appId+::   The id of the app.
  *
  **/
  stopApp: function(_appId){
    this.busyApps[_appId] = true;
  },

/** = Description
  * Changes the priority of the app. Calls +stopApp+ and +startApp+.
  *
  * = Parameters
  * +_appId+::     The id of the app.
  * +_priority+::  The app priority.
  *
  **/
  reniceApp: function(_appId,_priority){
    this.appPriorities[ _appId ] = _priority;
  },

/** = Description
  * Stops polling and deletes an app instance (and its components).
  *
  * = Parameters
  * +_appId+::    The unique id of the app.
  * +_forced+::   (Optional) The doesn't wait for the last poll to finish.
  *
  **/
  killApp: function(_appId, _forced){
    if( !_forced ){
      var _startedWaiting = new Date().getTime();
      while( this.busyApps[ _appId ] === true ) {
        /* Waiting for the app to finish its idle loop... */
        if (new Date().getTime() > _startedWaiting + this.maxAppRunTime) {
          break;
        }
      }
    }
    this.busyApps[_appId] = true;

    this.apps[ _appId ].destroyAllViews();
    this.apps[ _appId ] = null;

    this.freeAppIds.push( _appId );
  },

/** All +HView+ instances that are defined **/
  views: [],

/** List of free +viwes+ indexes **/
  _freeViewIds: [],

/** = Description
  * Adds a view and assigns it an id.
  *
  * = Parameters
  * +_view+::   The +HView+ instance.
  *
  * = Returns
  * The new view id.
  *
  **/
  addView: function(_view){
    var _newId;
    if(this._freeViewIds.length===0){
      _newId = this.views.length;
      this.views.push(_view);
    }
    else {
      _newId = this._freeViewIds.pop();
      this.views[_newId] = _view;
    }
    return _newId;
  },

/** = Description
  * Removes a view and recycles its id.
  *
  * = Parameters
  * +_viewId+::  The view id to delete.
  *
  **/
  delView: function(_viewId){
    this.views[_viewId] = null;
    this._freeViewIds.push(_viewId);
  },

/** The view id of the active window. 0 means none. **/
  activeWindowId: 0,

/** = Description
  * Focuses the window given and blurs the previous one.
  *
  * = Parameters
  * +_view+::   The +HView+ instance, this is almost always a
  *             +HWindow+ instance.
  *
  **/
  windowFocus: function(_view){
    if(!_view){
      this.activeWindowId=0;
      return;
    }
    var _activeWindowId = this.activeWindowId,
        _views = this.views,
        _viewId = _view.viewId;
    if(_views[_activeWindowId]){
      if (_views[_activeWindowId]["windowBlur"]) {
        _views[_activeWindowId].windowBlur();
      }
    }
    this.activeWindowId=_viewId;
    _view.bringToFront();
    _view.windowFocus();
  },

/** optimization of zindex buffer, see +HView+ **/
  _updateZIndexOfChildrenBuffer: [],

/** Updates the z-indexes of the children of the given +_viewId+. **/
  updateZIndexOfChildren: function(_viewId) {
    if(this._updateZIndexOfChildrenBuffer.indexOf(_viewId)===-1){
      this._updateZIndexOfChildrenBuffer.push(_viewId);
    }
  },

/** Flushes the z-indexes. This is a fairly expensive operation,
  * thas's why the info is buffered.
  **/
  _flushUpdateZIndexOfChilden: function() {

    var j=0, // buffer index

        // reference to the HSystem namespace
        _this = HSystem,

        // reference to the buffer
        _buffer = this._updateZIndexOfChildrenBuffer,

        // the length of the buffer
        _bufLen = _buffer.length;

    // loop buffer length times to get the items
    for ( ; j < _bufLen; j++ ) {

      // get and remove view the view id from the z-index flush status buffer:
      var _viewId = _buffer.shift(),

          // reference to the view's z-index array or the system root-level views if _viewId is 0
          _views = ((_viewId === null)?(_this.viewsZOrder):(_this.views[ _viewId ].viewsZOrder)),

          // the length of the view's z-index array
          _viewLen = _views.length,

          // reference to the setStyle method of the element manager
          _setStyl = ELEM.setStyle,

          // reference to HSystem.views (collection of all views, by index)
          _sysViews = _this.views,

      // assign variables for use inside the inner loop:

          // the viewId of the view to be updated
          _subViewId,

          // the view itself with the viewId above
          _view,

          // the elemId property, used as a [] -lookup in the loop
          _elemIdStr = 'elemId',

          // the css property name
          _zIdxStr = 'z-index',

          // the loop index
          i=0,

          // the element id of the view
          _elemId;

      // end of var declarations

      // loop through all subviews and update the indexes:
      for ( ; i < _viewLen; i++ ) {

        // get the viewId to be updated based on the z-index array
        _subViewId = _views[ i ];

        // reference to the view itself
        _view = _sysViews[ _subViewId ];

        // the element id of the view
        _elemId = _view[ _elemIdStr ];

        // do the element manager call itself to update the dom property
        _setStyl( _elemId, _zIdxStr, i );
      }
    }
  }
};

// });

// Starts the ticking, when the document is loaded:
LOAD(
  function(){
    HSystem.ticker();
  }
);
<commit_msg>If a view's parent is an app, force reordering of all top-level zIndexes.<commit_after>/*   RSence
 *   Copyright 2006 Riassence Inc.
 *   http://riassence.com/
 *
 *   You should have received a copy of the GNU General Public License along
 *   with this software package. If not, contact licensing@riassence.com
 */

/*** = Description
  ** Main container of global operations on +HView+ and
  ** +HApplication+ -derived classes.
  **
  ** HSystem is used to keep +HApplication+ and +HView+ instances
  ** globally managed. The managed classes themself calls +HSystem+ methods,
  ** so there is no real need to access +HSystem+ directly from user-level code.
  **
***/
var//RSence.Foundation
HSystem = {

/** When the focus behaviour is 1, clicking on any subview brings
  * the window to front, if attached to a HWindow instance.
  * If the behaviour is 0, only direct clicks on the HWindow controls
  * brings the window to front.
  *
  **/
  windowFocusMode: 1,

/** Singleton class; has no constructor **/
  // constructor: null,

/** An array of HApplication instances, index is the appId **/
  apps: [],

/** An array (in the same order as apps): holds priority values **/
  appPriorities: [],

/** An array (in the same order as apps): holds busy status **/
  busyApps: [],

/** This array holds free app id:s **/
  freeAppIds: [],

/** The default HSystem ticker interval. Unit is milliseconds. **/
  defaultInterval: 10,

/** The default HApplication priority. Unit is "On the n:th tick: poll". **/
  defaultPriority: 20,

/** The z-index of root-level +HView+ instances. All the array operations
  * are done by the inner logic of +HApplication+ and +HView+ instances.
  **/
  viewsZOrder: [],

/** This is the internal "clock" counter. Gets updated on every tick. **/
  ticks: 0,

/** Time in milliseconds for the timeout of a poll to finish before
  * being classified as stuck and thus forcibly terminated.
  **/
  maxAppRunTime: 5000,

/** Calls applications, uses the prority as a prioritizer.
  **/
  scheduler: function(){

    // Loop through all applications:
    for( var _appId=0; _appId<this.apps.length; _appId++ ){
      // Check, if the application exists:
      if( this.apps[ _appId ] ){
        // Check, if the application is busy:
        if( !this.busyApps[ _appId ] ){
          // Check, if the tick count matches the priority of the app:
          if( (this.ticks % this.appPriorities[ _appId ]) === 0 ){
            // Set the app busy, the app itself should "unbusy" itself, when the idle call is done.
            // That happens in <HApplication._startIdle>

            // If the app is not busy, then make a idle call:
            if(HSystem.apps[_appId]){
              HSystem.apps[_appId]._startIdle();
            }
          }
        }
      }
    }

    if(this._updateZIndexOfChildrenBuffer.length!==0){
      this._flushUpdateZIndexOfChilden();
    }

  },

  _updateFlexibleRects: function(){
    var
    _view,
    i = 0;
    for( ; i < this.views.length; i++ ){
      _view = this.views[i];
      if(_view && (_view.flexRight || _view.flexBottom)){
        _view.rect._updateFlexibleDimensions();
      }
    }
  },

/** Calls the scheduler and then calls itself after a timeout to keep
  * the loop going on.
  **/
  ticker: function(){
    // Increment the tick counter:
    this.ticks++;
    this.scheduler();
    this._tickTimeout = setTimeout( function(){HSystem.ticker();},this.defaultInterval);
  },

/** = Description
  * Adds the structures needed for a new +HApplication+ instance.
  *
  * Called from inside the +HApplication+ constructor.
  * Binds an app and gives it a unique id.
  *
  * = Parameters
  * +_app+::       The reference to the +HApplication+ instance object.
  * +_priority+::  The app priority.
  *
  * = Returns
  * The app id.
  *
  **/
  addApp: function(_app, _priority){
    var _appId;
    if(this.freeAppIds.length !== 0){
      _appId = this.freeAppIds.unshift();
      this.apps[_appId] = _app;
    } else {
      this.apps.push(_app);
      _appId = this.apps.length-1;
    }

    // sets self as parent
    _app.parent  = this;
    _app.parents = [this];

    _app.appId = _appId;

    this.startApp(_appId, _priority);

    return _appId;
  },

/** = Description
  * Starts polling an app instance (and its components).
  *
  * = Parameters
  * +_appId+::      The unique id of the app.
  * +_priority+::   The app priority.
  *
  **/
  startApp: function(_appId,_priority){
    if(_priority===undefined){
      _priority = this.defaultInterval;
    }
    this.appPriorities[ _appId ] = _priority;
    this.busyApps[_appId] = false;
  },

/** = Description
  * Stops polling an app instance (and its components).
  *
  * = Parameters
  * +_appId+::   The id of the app.
  *
  **/
  stopApp: function(_appId){
    this.busyApps[_appId] = true;
  },

/** = Description
  * Changes the priority of the app. Calls +stopApp+ and +startApp+.
  *
  * = Parameters
  * +_appId+::     The id of the app.
  * +_priority+::  The app priority.
  *
  **/
  reniceApp: function(_appId,_priority){
    this.appPriorities[ _appId ] = _priority;
  },

/** = Description
  * Stops polling and deletes an app instance (and its components).
  *
  * = Parameters
  * +_appId+::    The unique id of the app.
  * +_forced+::   (Optional) The doesn't wait for the last poll to finish.
  *
  **/
  killApp: function(_appId, _forced){
    if( !_forced ){
      var _startedWaiting = new Date().getTime();
      while( this.busyApps[ _appId ] === true ) {
        /* Waiting for the app to finish its idle loop... */
        if (new Date().getTime() > _startedWaiting + this.maxAppRunTime) {
          break;
        }
      }
    }
    this.busyApps[_appId] = true;

    this.apps[ _appId ].destroyAllViews();
    this.apps[ _appId ] = null;

    this.freeAppIds.push( _appId );
  },

/** All +HView+ instances that are defined **/
  views: [],

/** List of free +viwes+ indexes **/
  _freeViewIds: [],

/** = Description
  * Adds a view and assigns it an id.
  *
  * = Parameters
  * +_view+::   The +HView+ instance.
  *
  * = Returns
  * The new view id.
  *
  **/
  addView: function(_view){
    var _newId;
    if(this._freeViewIds.length===0){
      _newId = this.views.length;
      this.views.push(_view);
    }
    else {
      _newId = this._freeViewIds.pop();
      this.views[_newId] = _view;
    }
    return _newId;
  },

/** = Description
  * Removes a view and recycles its id.
  *
  * = Parameters
  * +_viewId+::  The view id to delete.
  *
  **/
  delView: function(_viewId){
    this.views[_viewId] = null;
    this._freeViewIds.push(_viewId);
  },

/** The view id of the active window. 0 means none. **/
  activeWindowId: 0,

/** = Description
  * Focuses the window given and blurs the previous one.
  *
  * = Parameters
  * +_view+::   The +HView+ instance, this is almost always a
  *             +HWindow+ instance.
  *
  **/
  windowFocus: function(_view){
    if(!_view){
      this.activeWindowId=0;
      return;
    }
    var _activeWindowId = this.activeWindowId,
        _views = this.views,
        _viewId = _view.viewId;
    if(_views[_activeWindowId]){
      if (_views[_activeWindowId]["windowBlur"]) {
        _views[_activeWindowId].windowBlur();
      }
    }
    this.activeWindowId=_viewId;
    _view.bringToFront();
    _view.windowFocus();
  },

/** optimization of zindex buffer, see +HView+ **/
  _updateZIndexOfChildrenBuffer: [],

/** Updates the z-indexes of the children of the given +_viewId+. **/
  updateZIndexOfChildren: function(_viewId) {
    if(this._updateZIndexOfChildrenBuffer.indexOf(_viewId)===-1){
      this._updateZIndexOfChildrenBuffer.push(_viewId);
    }
    if((_viewId !== undefined && _viewId !== null) && (this.views[_viewId].app === this.views[_viewId].parent)){
      (this._updateZIndexOfChildrenBuffer.indexOf(null)===-1) && this._updateZIndexOfChildrenBuffer.push(null);
    }
  },

/** Flushes the z-indexes. This is a fairly expensive operation,
  * thas's why the info is buffered.
  **/
  _flushUpdateZIndexOfChilden: function() {

    var j=0, // buffer index

        // reference to the HSystem namespace
        _this = HSystem,

        // reference to the buffer
        _buffer = _this._updateZIndexOfChildrenBuffer,

        // the length of the buffer
        _bufLen = _buffer.length;

    // loop buffer length times to get the items
    for ( ; j < _bufLen; j++ ) {

      // get and remove view the view id from the z-index flush status buffer:
      var
      _viewId = _buffer.shift(),

      // reference to the view's z-index array or the system root-level views if _viewId is null
      _views = ((_viewId === null)?(_this.viewsZOrder):(_this.views[ _viewId ].viewsZOrder)),

      // the length of the view's z-index array
      _viewLen = _views.length,

      // reference to the setStyle method of the element manager
      _setStyl = ELEM.setStyle,

      // reference to HSystem.views (collection of all views, by index)
      _sysViews = _this.views,

      // assign variables for use inside the inner loop:

      // the viewId of the view to be updated
      _subViewId,

      // the view itself with the viewId above
      _view,

      // the elemId property, used as a [] -lookup in the loop
      _elemIdStr = 'elemId',

      // the css property name
      _zIdxStr = 'z-index',

      // the loop index
      i=0,

      // the element id of the view
      _elemId;

      if(_viewId === null){
        console.log('null: ', _view);
      }
      // end of var declarations

      // loop through all subviews and update the indexes:
      for ( ; i < _viewLen; i++ ) {

        // get the viewId to be updated based on the z-index array
        _subViewId = _views[ i ];

        // reference to the view itself
        _view = _sysViews[ _subViewId ];

        // the element id of the view
        _elemId = _view[ _elemIdStr ];

        // do the element manager call itself to update the dom property
        _setStyl( _elemId, _zIdxStr, i );
      }
    }
  }
};

// });

// Starts the ticking, when the document is loaded:
LOAD(
  function(){
    HSystem.ticker();
  }
);
<|endoftext|>


<commit_before>import {badRequest, notFound} from 'boom'
import Joi from 'joi'
import Logger from '@modulus/logger'
import Slug from 'slug'

import Post from '../models/blog/post'

let logger = Logger('handlers/post')

export default {

  /////////// Post.create \\\\\\\\\\
  create: {
    validate: {
      payload: {
        title: Joi.string().required(),
        image: Joi.string(),
        caption: Joi.string(),
        content: Joi.string().required(),
        tags: Joi.array()
      }
    },
    handler: function (request, reply) {
      let {caption, content, image, tags, title} = request.payload

      let newPost =  {
        title: title,
        slug: Slug(title, { lower: true }),
        image: image,
        caption: caption,
        content: content,
        tags: tags
      }

      new Post(newPost).save((err, created) => {
        if (err) {
          logger.error(`Post.create error: ${err.message}`)
          return reply(badRequest(err.message))
        }

        logger.debug(`Post.create saved ${JSON.stringify(created)}`)
        reply(created)
      })
    }
  },

  ////////// Post.get \\\\\\\\\\
  get: {
    validate: {
      params: {
        slug: Joi.string().required()
      }
    },
    handler: function (request, reply) {
      Post.findOne({ slug: request.params.slug }, (err, post) => {
        if (err) {
          logger.error(`Job.findOne error: ${err.message}`)
          return reply(badRequest(err.message))
        }

        logger.debug(`Post.findOne found ${JSON.stringify(post)}`)
        reply(post)
      })
    }
  },

  ////////// Post.getAll \\\\\\\\\\
  getAll: {
    handler: function (request, reply) {
      Post.find({}, (err, posts) => {
        if (err) {
          logger.error(`Post.find error: ${err.message}`)
          return reply(badRequest(err.message))
        }

        logger.debug(`Post.find found ${JSON.stringify(posts)}`)
        reply(posts)
      })
    }
  }
}
<commit_msg>Add delete post handler<commit_after>import {badRequest, notFound} from 'boom'
import Joi from 'joi'
import Logger from '@modulus/logger'
import Slug from 'slug'

import Post from '../models/blog/post'

let logger = Logger('handlers/post')

export default {

  /////////// Post.create \\\\\\\\\\
  create: {
    validate: {
      payload: {
        title: Joi.string().required(),
        image: Joi.string(),
        caption: Joi.string(),
        content: Joi.string().required(),
        tags: Joi.array()
      }
    },
    handler: function (request, reply) {
      let {caption, content, image, tags, title} = request.payload

      let newPost =  {
        title: title,
        slug: Slug(title, { lower: true }),
        image: image,
        caption: caption,
        content: content,
        tags: tags
      }

      new Post(newPost).save((err, created) => {
        if (err) {
          logger.error(`Post.create error: ${err.message}`)
          return reply(badRequest(err.message))
        }

        logger.debug(`Post.create saved ${JSON.stringify(created)}`)
        reply(created)
      })
    }
  },

  ////////// Post.get \\\\\\\\\\
  get: {
    validate: {
      params: {
        slug: Joi.string().required()
      }
    },
    handler: function (request, reply) {
      Post.findOne({ slug: request.params.slug }, (err, post) => {
        if (err) {
          logger.error(`Job.findOne error: ${err.message}`)
          return reply(badRequest(err.message))
        }

        logger.debug(`Post.findOne found ${JSON.stringify(post)}`)
        reply(post)
      })
    }
  },

  ////////// Post.getAll \\\\\\\\\\
  getAll: {
    handler: function (request, reply) {
      Post.find({}, (err, posts) => {
        if (err) {
          logger.error(`Post.find error: ${err.message}`)
          return reply(badRequest(err.message))
        }

        logger.debug(`Post.find found ${JSON.stringify(posts)}`)
        reply(posts)
      })
    }
  },

  ////////// Post.remove \\\\\\\\\\
  remove: {
    validate: {
      params: {
        slug: Joi.string().required()
      }
    },
    handler: function (request, reply) {
      Post.remove({ id: request.params.id }, (err) => {
        if (err) {
          logger.error(`Post.remove error: ${err.message}`)
          return reply(badRequest(err.message))
        }

        logger.debug(`Post.remove removed ${request.params.id}`)
        reply()
      })
    }
  }
}
<|endoftext|>


<commit_before>/**
 * This is a JavaScript file which backs the Spine architecture diagram.
 *
 * Please see `/docs/concepts/index.md` for usage.
 */

$(
    /**
     * This function is executed upon page load.
     *
     * Binds the handlers to the events in this HTML page.
     */
    function () {

        /**
         * CSS classes used as selectors to manipulate the elements of SVG diagram.
         */

        const endUserClass = "end-user";
        const boxCaptionClass = "box-caption";
        const arrowCaptionClass = "arrow-caption";
        const titleCaptionClass = "title-caption";
        const arrowClass = "arrow";
        const pathOnlyClass = "path-only";

        /**
         * CSS classes of the HTML elements on the page.
         * @type {string}
         */
        let architectureLinkClass = "architecture-link";
        let noSelectClass = "noselect";

        let useFacingLink = $("#display-user-facing-components");
        let allComponentLink = $("#display-all-components");
        let selectedElementColor = "#8d28e0";
        let selectedCaptionColor = "#fafafa";

        const originFillAttr = "origin-fill";
        const originStrokeAttr = "origin-stroke";

        const fillAttr = "fill";
        const strokeAttr = "stroke";
        const fillOpacityAttr = "fill-opacity";
        const strokeOpacityAttr = "stroke-opacity";
        const pointerEvents = "pointer-events";

        const textTag = "text";
        const rectTag = "rect";
        const pathTag = "path";

        function setupLookAndFeel() {

            // Back up the original fill color and color of elements to use in `mouseleave` later.
            let contents = $(".diagram-content").find("*");
            for (let index = 0; index < contents.length; index++) {
                const item = $(contents[index]);
                const elementName = item[0].nodeName.toLowerCase();
                if (textTag === elementName) {

                    if (hasClass(item, boxCaptionClass)
                        || hasClass(item, arrowCaptionClass)
                        || hasClass(item, titleCaptionClass)) {
                        item.attr(originFillAttr, item.attr(fillAttr));

                        // Make all TEXTs non-selectable.
                        item.addClass(noSelectClass);
                    }
                }
                if (rectTag === elementName || pathTag === elementName) {
                    item.attr(originFillAttr, item.attr(fillAttr));
                    item.attr(originStrokeAttr, item.attr(strokeAttr))
                }
            }
        }

        /**
         * Changes opacity of the elements, not marked as "end-user".
         *
         * The opacity value is expected to be [0; 1] range.
         *
         * @param textOpacity the opacity to apply to text elements
         * @param elementOpacity the opacity to apply "rect" and "path" elements
         */
        function fade(textOpacity, elementOpacity) {
            let contents = $(".diagram-content").find("*");
            for (let index = 0; index < contents.length; index++) {
                const item = $(contents[index]);
                if (hasClass(item, endUserClass)) {
                    continue;
                }
                const elementName = item[0].nodeName.toLowerCase();

                if (textTag === elementName) {

                    if (hasClass(item, boxCaptionClass)
                        || hasClass(item, arrowCaptionClass)
                        || hasClass(item, titleCaptionClass)) {

                        item.attr(fillOpacityAttr, textOpacity);
                    }
                }
                if (rectTag === elementName) {
                    item.attr(fillOpacityAttr, elementOpacity);
                }
                if (pathTag === elementName) {
                    item.attr(fillOpacityAttr, elementOpacity);

                    item.attr(strokeOpacityAttr, elementOpacity);
                }
            }
        }

        /**
         * A custom implementation of `jQuery.hasClass()` suitable for SVG elements.
         *
         * In the jQuery 1.11.2 currently used, SVG elements are not supported
         * by `jQuery.hasClass()`.
         *
         * @param element an element wrapped in jQuery.
         * @param className a class name to detect
         * @return `true` if such a class name is declared for this element, `false` otherwise.
         */
        function hasClass(element, className) {
            const firstChild = element[0];
            for (let classIndex = 0; classIndex < firstChild.classList.length; classIndex++) {
                if (className === firstChild.classList[classIndex]) {
                    return true;
                }
            }
            return false;
        }

        /**
         * Adds a link behavior to an element.
         *
         * @param linkElement the jQuery object wrapping the DOM element
         * @param onClickCallback the callback to set upon 'click' event
         */
        function enableLink(linkElement, onClickCallback) {
            linkElement
                .addClass(architectureLinkClass)
                .click(function () {
                    onClickCallback()
                });
        }

        /**
         * Disables a link behaviour of an element.
         *
         * @param linkElement the jQuery object wrapping the DOM element
         */
        function disableLink(linkElement) {
            linkElement
                .removeClass(architectureLinkClass)
                .unbind("click");
        }

        function makeClickable(selector, url) {

            $(".g-caption" + selector)
                .css("cursor", "pointer")
                .attr("pointer-events", "all")
                .mouseover(function () {
                    let matched = $(selector);

                    for (let index = 0; index < matched.length; index++) {
                        const item = $(matched[index]);
                        const elementName = item[0].nodeName.toLowerCase();
                        if(textTag === elementName) {
                            item.attr(fillAttr, selectedCaptionColor);
                        }
                        if (rectTag === elementName || pathTag === elementName) {
                            item.attr(fillAttr, selectedElementColor);
                        }
                        if(hasClass(item, arrowClass)) {
                            item.attr(strokeAttr, selectedElementColor);
                        }
                        if(hasClass(item, pathOnlyClass)) {
                            item.attr(fillAttr, "none");
                        }
                    }
                })
                .mouseout(function () {
                    let matched = $(selector);
                    for (let index = 0; index < matched.length; index++) {
                        const item = $(matched[index]);
                        const elementName = item[0].nodeName.toLowerCase();
                        if (textTag === elementName
                            || rectTag === elementName
                            || pathTag === elementName) {
                            let originFillValue = item.attr(originFillAttr);
                            item.attr(fillAttr, originFillValue);
                        }

                        if(hasClass(item, arrowClass)) {
                            let originStrokeValue = item.attr(originStrokeAttr);
                            item.attr(strokeAttr, originStrokeValue);
                        }
                    }

                })
                .click(function () {
                    document.location.href = url;
                });

            $(".g-caption-bounded-context" + selector)
                .css("cursor", "pointer")
                .attr("pointer-events", "all")
                .mouseover(function () {
                    let matched = $(selector);

                    for (let index = 0; index < matched.length; index++) {
                        const item = $(matched[index]);
                        const elementName = item[0].nodeName.toLowerCase();
                        if(textTag === elementName) {
                            item.attr(fillAttr, selectedRepoCaptionColor);
                        }
                        if (rectTag === elementName || pathTag === elementName) {
                            item.attr(pointerEvents, "none");
                            item.attr(fillAttr, selectedRepoColor);
                        }
                        if(hasClass(item, arrowClass)) {
                            item.attr(strokeAttr, selectedRepoColor);
                        }
                    }
                })
                .mouseout(function () {
                    let matched = $(selector);
                    for (let index = 0; index < matched.length; index++) {
                        const item = $(matched[index]);
                        const elementName = item[0].nodeName.toLowerCase();
                        if (textTag === elementName
                            || rectTag === elementName
                            || pathTag === elementName) {
                            let originFillValue = item.attr(originFillAttr);
                            item.attr(fillAttr, originFillValue);
                        }

                        if(hasClass(item, arrowClass)) {
                            let originStrokeValue = item.attr(originStrokeAttr);
                            item.attr(strokeAttr, originStrokeValue);
                        }
                    }

                })
                .click(function () {
                    document.location.href = url;
                });

            $(".g-arrow" + selector)
                .css("cursor", "pointer")
                .attr("pointer-events", "all")
                .mouseover(function () {
                    let matched = $(selector);

                    for (let index = 0; index < matched.length; index++) {
                        const item = $(matched[index]);
                        const elementName = item[0].nodeName.toLowerCase();
                        if (textTag === elementName) {
                            item.attr(fillAttr, selectedElementColor);
                        }
                        if(hasClass(item, arrowClass)) {
                            item.attr(fillAttr, selectedElementColor);
                        }
                    }
                })
                .mouseout(function () {
                    let matched = $(selector);
                    for (let index = 0; index < matched.length; index++) {
                        const item = $(matched[index]);
                        const elementName = item[0].nodeName.toLowerCase();
                        if (textTag === elementName) {
                            let originFillValue = item.attr(originFillAttr);
                            item.attr(fillAttr, originFillValue);
                        }
                        if(hasClass(item, arrowClass)) {
                            let originFillValue = item.attr(originFillAttr);
                            item.attr(fillAttr, originFillValue);
                        }
                    }

                })
                .click(function () {
                    document.location.href = url;
                });

        }

        /**
         * Displays the user-facing components and fades out the rest.
         */
        function displayUserFacing() {
            fade("0.65", "0.2");
            enableLink(allComponentLink, displayAll);
            disableLink(useFacingLink);
        }

        /**
         * Displays all the Spine components and removes the fading.
         */
        function displayAll() {
            fade("1", "1");

            enableLink(useFacingLink, displayUserFacing);
            disableLink(allComponentLink);
        }

        setupLookAndFeel();
        displayAll();

        // Link items to the corresponding pages.

        // Boxes:
        makeClickable(".aggregate", "/docs/concepts/aggregate.html");
        makeClickable(".bounded-context", "/docs/concepts/bounded-context.html");
        makeClickable(".pm", "/docs/concepts/process-manager.html");
        makeClickable(".projection", "/docs/concepts/projection.html");
        makeClickable(".aggregate-repo", "/docs/concepts/repository.html");
        makeClickable(".pm-repo", "/docs/concepts/repository.html");
        makeClickable(".projection-repo", "/docs/concepts/repository.html");
        makeClickable(".command-bus", "/docs/concepts/command-bus.html");
        makeClickable(".event-bus", "/docs/concepts/event-bus.html");
        makeClickable(".aggregate-mirror", "/docs/concepts/aggregate-mirror.html");
        makeClickable(".command-store", "/docs/concepts/command-store.html");
        makeClickable(".event-store", "/docs/concepts/event-store.html");
        makeClickable(".command-service", "/docs/concepts/command-service.html");
        makeClickable(".query-service", "/docs/concepts/query-service.html");
        makeClickable(".subscription-service", "/docs/concepts/subscription-service.html");
        makeClickable(".stand", "/docs/concepts/stand.html");

        // Arrows:
        makeClickable(".ui-command-service", "/docs/concepts/command.html");
        makeClickable(".command-service-ui", "/docs/concepts/acknowledgement.html");
        makeClickable(".event-bus-aggregate-repo", "/docs/concepts/event.html");
        makeClickable(".integration-events", "/docs/concepts/integration-event.html");
    }
);
<commit_msg>Add `bounded-context` hover color<commit_after>/**
 * This is a JavaScript file which backs the Spine architecture diagram.
 *
 * Please see `/docs/concepts/index.md` for usage.
 */

$(
    /**
     * This function is executed upon page load.
     *
     * Binds the handlers to the events in this HTML page.
     */
    function () {

        /**
         * CSS classes used as selectors to manipulate the elements of SVG diagram.
         */

        const endUserClass = "end-user";
        const boxCaptionClass = "box-caption";
        const arrowCaptionClass = "arrow-caption";
        const titleCaptionClass = "title-caption";
        const arrowClass = "arrow";
        const pathOnlyClass = "path-only";

        /**
         * CSS classes of the HTML elements on the page.
         * @type {string}
         */
        let architectureLinkClass = "architecture-link";
        let noSelectClass = "noselect";

        let useFacingLink = $("#display-user-facing-components");
        let allComponentLink = $("#display-all-components");
        let selectedElementColor = "#8d28e0";
        let selectedCaptionColor = "#fafafa";
        let selectedBodyBgColor = "#e7ecfa";
        let selectedBodyBgCaptionColor = "#505050";

        const originFillAttr = "origin-fill";
        const originStrokeAttr = "origin-stroke";

        const fillAttr = "fill";
        const strokeAttr = "stroke";
        const fillOpacityAttr = "fill-opacity";
        const strokeOpacityAttr = "stroke-opacity";
        const pointerEvents = "pointer-events";

        const textTag = "text";
        const rectTag = "rect";
        const pathTag = "path";

        function setupLookAndFeel() {

            // Back up the original fill color and color of elements to use in `mouseleave` later.
            let contents = $(".diagram-content").find("*");
            for (let index = 0; index < contents.length; index++) {
                const item = $(contents[index]);
                const elementName = item[0].nodeName.toLowerCase();
                if (textTag === elementName) {

                    if (hasClass(item, boxCaptionClass)
                        || hasClass(item, arrowCaptionClass)
                        || hasClass(item, titleCaptionClass)) {
                        item.attr(originFillAttr, item.attr(fillAttr));

                        // Make all TEXTs non-selectable.
                        item.addClass(noSelectClass);
                    }
                }
                if (rectTag === elementName || pathTag === elementName) {
                    item.attr(originFillAttr, item.attr(fillAttr));
                    item.attr(originStrokeAttr, item.attr(strokeAttr))
                }
            }
        }

        /**
         * Changes opacity of the elements, not marked as "end-user".
         *
         * The opacity value is expected to be [0; 1] range.
         *
         * @param textOpacity the opacity to apply to text elements
         * @param elementOpacity the opacity to apply "rect" and "path" elements
         */
        function fade(textOpacity, elementOpacity) {
            let contents = $(".diagram-content").find("*");
            for (let index = 0; index < contents.length; index++) {
                const item = $(contents[index]);
                if (hasClass(item, endUserClass)) {
                    continue;
                }
                const elementName = item[0].nodeName.toLowerCase();

                if (textTag === elementName) {

                    if (hasClass(item, boxCaptionClass)
                        || hasClass(item, arrowCaptionClass)
                        || hasClass(item, titleCaptionClass)) {

                        item.attr(fillOpacityAttr, textOpacity);
                    }
                }
                if (rectTag === elementName) {
                    item.attr(fillOpacityAttr, elementOpacity);
                }
                if (pathTag === elementName) {
                    item.attr(fillOpacityAttr, elementOpacity);

                    item.attr(strokeOpacityAttr, elementOpacity);
                }
            }
        }

        /**
         * A custom implementation of `jQuery.hasClass()` suitable for SVG elements.
         *
         * In the jQuery 1.11.2 currently used, SVG elements are not supported
         * by `jQuery.hasClass()`.
         *
         * @param element an element wrapped in jQuery.
         * @param className a class name to detect
         * @return `true` if such a class name is declared for this element, `false` otherwise.
         */
        function hasClass(element, className) {
            const firstChild = element[0];
            for (let classIndex = 0; classIndex < firstChild.classList.length; classIndex++) {
                if (className === firstChild.classList[classIndex]) {
                    return true;
                }
            }
            return false;
        }

        /**
         * Adds a link behavior to an element.
         *
         * @param linkElement the jQuery object wrapping the DOM element
         * @param onClickCallback the callback to set upon 'click' event
         */
        function enableLink(linkElement, onClickCallback) {
            linkElement
                .addClass(architectureLinkClass)
                .click(function () {
                    onClickCallback()
                });
        }

        /**
         * Disables a link behaviour of an element.
         *
         * @param linkElement the jQuery object wrapping the DOM element
         */
        function disableLink(linkElement) {
            linkElement
                .removeClass(architectureLinkClass)
                .unbind("click");
        }

        function makeClickable(selector, url) {

            $(".g-caption" + selector)
                .css("cursor", "pointer")
                .attr("pointer-events", "all")
                .mouseover(function () {
                    let matched = $(selector);

                    for (let index = 0; index < matched.length; index++) {
                        const item = $(matched[index]);
                        const elementName = item[0].nodeName.toLowerCase();
                        if(textTag === elementName) {
                            item.attr(fillAttr, selectedCaptionColor);
                        }
                        if (rectTag === elementName || pathTag === elementName) {
                            item.attr(fillAttr, selectedElementColor);
                        }
                        if(hasClass(item, arrowClass)) {
                            item.attr(strokeAttr, selectedElementColor);
                        }
                        if(hasClass(item, pathOnlyClass)) {
                            item.attr(fillAttr, "none");
                        }
                    }
                })
                .mouseout(function () {
                    let matched = $(selector);
                    for (let index = 0; index < matched.length; index++) {
                        const item = $(matched[index]);
                        const elementName = item[0].nodeName.toLowerCase();
                        if (textTag === elementName
                            || rectTag === elementName
                            || pathTag === elementName) {
                            let originFillValue = item.attr(originFillAttr);
                            item.attr(fillAttr, originFillValue);
                        }

                        if(hasClass(item, arrowClass)) {
                            let originStrokeValue = item.attr(originStrokeAttr);
                            item.attr(strokeAttr, originStrokeValue);
                        }
                    }

                })
                .click(function () {
                    document.location.href = url;
                });

            $(".g-caption-bounded-context" + selector)
                .css("cursor", "pointer")
                .attr("pointer-events", "all")
                .mouseover(function () {
                    let matched = $(selector);

                    for (let index = 0; index < matched.length; index++) {
                        const item = $(matched[index]);
                        const elementName = item[0].nodeName.toLowerCase();
                        if(textTag === elementName) {
                            item.attr(fillAttr, selectedBodyBgCaptionColor);
                        }
                        if (rectTag === elementName || pathTag === elementName) {
                            item.attr(pointerEvents, "none");
                            item.attr(fillAttr, selectedBodyBgColor);
                        }
                        if(hasClass(item, arrowClass)) {
                            item.attr(strokeAttr, selectedBodyBgColor);
                        }
                    }
                })
                .mouseout(function () {
                    let matched = $(selector);
                    for (let index = 0; index < matched.length; index++) {
                        const item = $(matched[index]);
                        const elementName = item[0].nodeName.toLowerCase();
                        if (textTag === elementName
                            || rectTag === elementName
                            || pathTag === elementName) {
                            let originFillValue = item.attr(originFillAttr);
                            item.attr(fillAttr, originFillValue);
                        }

                        if(hasClass(item, arrowClass)) {
                            let originStrokeValue = item.attr(originStrokeAttr);
                            item.attr(strokeAttr, originStrokeValue);
                        }
                    }

                })
                .click(function () {
                    document.location.href = url;
                });

            $(".g-arrow" + selector)
                .css("cursor", "pointer")
                .attr("pointer-events", "all")
                .mouseover(function () {
                    let matched = $(selector);

                    for (let index = 0; index < matched.length; index++) {
                        const item = $(matched[index]);
                        const elementName = item[0].nodeName.toLowerCase();
                        if (textTag === elementName) {
                            item.attr(fillAttr, selectedElementColor);
                        }
                        if(hasClass(item, arrowClass)) {
                            item.attr(fillAttr, selectedElementColor);
                        }
                    }
                })
                .mouseout(function () {
                    let matched = $(selector);
                    for (let index = 0; index < matched.length; index++) {
                        const item = $(matched[index]);
                        const elementName = item[0].nodeName.toLowerCase();
                        if (textTag === elementName) {
                            let originFillValue = item.attr(originFillAttr);
                            item.attr(fillAttr, originFillValue);
                        }
                        if(hasClass(item, arrowClass)) {
                            let originFillValue = item.attr(originFillAttr);
                            item.attr(fillAttr, originFillValue);
                        }
                    }

                })
                .click(function () {
                    document.location.href = url;
                });

        }

        /**
         * Displays the user-facing components and fades out the rest.
         */
        function displayUserFacing() {
            fade("0.65", "0.2");
            enableLink(allComponentLink, displayAll);
            disableLink(useFacingLink);
        }

        /**
         * Displays all the Spine components and removes the fading.
         */
        function displayAll() {
            fade("1", "1");

            enableLink(useFacingLink, displayUserFacing);
            disableLink(allComponentLink);
        }

        setupLookAndFeel();
        displayAll();

        // Link items to the corresponding pages.

        // Boxes:
        makeClickable(".aggregate", "/docs/concepts/aggregate.html");
        makeClickable(".bounded-context", "/docs/concepts/bounded-context.html");
        makeClickable(".pm", "/docs/concepts/process-manager.html");
        makeClickable(".projection", "/docs/concepts/projection.html");
        makeClickable(".aggregate-repo", "/docs/concepts/repository.html");
        makeClickable(".pm-repo", "/docs/concepts/repository.html");
        makeClickable(".projection-repo", "/docs/concepts/repository.html");
        makeClickable(".command-bus", "/docs/concepts/command-bus.html");
        makeClickable(".event-bus", "/docs/concepts/event-bus.html");
        makeClickable(".aggregate-mirror", "/docs/concepts/aggregate-mirror.html");
        makeClickable(".command-store", "/docs/concepts/command-store.html");
        makeClickable(".event-store", "/docs/concepts/event-store.html");
        makeClickable(".command-service", "/docs/concepts/command-service.html");
        makeClickable(".query-service", "/docs/concepts/query-service.html");
        makeClickable(".subscription-service", "/docs/concepts/subscription-service.html");
        makeClickable(".stand", "/docs/concepts/stand.html");

        // Arrows:

        makeClickable(".ui-command-service", "/docs/concepts/command.html");
        makeClickable(".command-service-ui", "/docs/concepts/acknowledgement.html");
        makeClickable(".event-bus-aggregate-repo", "/docs/concepts/event.html");
        makeClickable(".integration-events", "/docs/concepts/integration-event.html");
    }
);
<|endoftext|>


<commit_before>import { freeze as f } from './creation'
import { doNew } from './creation-utils'

/*
  Array Methods
 */
export function forEach (callback, a) {
  return f(doNew(a || this).forEach(callback))
}
export function map (callback, a) {
  return f(doNew(a || this).map(callback))
}
export function filter (callback, a) {
  return f(doNew(a || this).filter(callback))
}
export function reduce (callback, init, a) {
  return f(doNew(a || this).reduce(callback, init))
}
export function push (value, a) {
  const rawArray = doNew(a || this)
  rawArray.push(value)
  return f(rawArray)
}
export function pop (value, a) {
  const rawArray = doNew(a || this)
  rawArray.pop(value)
  return f(rawArray)
}
export function shift (value, a) {
  const rawArray = doNew(a || this)
  rawArray.shift(value)
  return f(rawArray)
}
export function unshift (value, a) {
  const rawArray = doNew(a || this)
  rawArray.unshift(value)
  return f(rawArray)
}
export function first (a) {
  return (a || this)[0]
}
export function last (a) {
  const aa = a || this
  return aa[aa.length - 1]
}
// it can only be used as method
export function splice () {
  const rawArray = doNew(this)
  rawArray.splice.apply(rawArray, arguments)
  return f(rawArray)
}
export function insertAt (position, value, a) {
  return f(a || this).splice(position, 0, value)
}
export function deleteAt (position, a) {
  return f(a || this).splice(position, 1)
}
export function sort (comparator, a) {
  const rawArray = doNew(a || this)
  rawArray.sort(comparator)
  return f(rawArray)
}
export function reverse (a) {
  const rawArray = doNew(a || this)
  rawArray.reverse()
  return f(rawArray)
}
export function join (separator, a) {
  const rawArray = doNew(a || this)
  return rawArray.join(separator)
}
// it can only be used as method
export function concat () {
  const rawArray = doNew(this)
  return f(rawArray.concat.apply(rawArray, arguments))
}
export function slice (begin, end, a) {
  const rawArray = doNew(a || this)
  return f(rawArray.slice(begin, end))
}
export function indexOf (value, a) {
  const aa = doNew(a || this)
  return aa.indexOf(value)
}
export function findIndex (callback, a) {
  const aa = doNew(a || this)
  return aa.findIndex(callback)
}
export function includes (callback, fromIndex, a) {
  const aa = typeof fromIndex === 'number' ? a : fromIndex
  const fromI = typeof fromIndex === 'number' && fromIndex
  const aaa = doNew(aa || this)
  return aaa.includes(callback, fromI)
}
<commit_msg>feat add find method to arrays<commit_after>import { freeze as f } from './creation'
import { doNew } from './creation-utils'

/*
  Array Methods
 */
export function forEach (callback, a) {
  return f(doNew(a || this).forEach(callback))
}
export function map (callback, a) {
  return f(doNew(a || this).map(callback))
}
export function filter (callback, a) {
  return f(doNew(a || this).filter(callback))
}
export function reduce (callback, init, a) {
  return f(doNew(a || this).reduce(callback, init))
}
export function push (value, a) {
  const rawArray = doNew(a || this)
  rawArray.push(value)
  return f(rawArray)
}
export function pop (value, a) {
  const rawArray = doNew(a || this)
  rawArray.pop(value)
  return f(rawArray)
}
export function shift (value, a) {
  const rawArray = doNew(a || this)
  rawArray.shift(value)
  return f(rawArray)
}
export function unshift (value, a) {
  const rawArray = doNew(a || this)
  rawArray.unshift(value)
  return f(rawArray)
}
export function first (a) {
  return (a || this)[0]
}
export function last (a) {
  const aa = a || this
  return aa[aa.length - 1]
}
// it can only be used as method
export function splice () {
  const rawArray = doNew(this)
  rawArray.splice.apply(rawArray, arguments)
  return f(rawArray)
}
export function insertAt (position, value, a) {
  return f(a || this).splice(position, 0, value)
}
export function deleteAt (position, a) {
  return f(a || this).splice(position, 1)
}
export function sort (comparator, a) {
  const rawArray = doNew(a || this)
  rawArray.sort(comparator)
  return f(rawArray)
}
export function reverse (a) {
  const rawArray = doNew(a || this)
  rawArray.reverse()
  return f(rawArray)
}
export function join (separator, a) {
  const rawArray = doNew(a || this)
  return rawArray.join(separator)
}
// it can only be used as method
export function concat () {
  const rawArray = doNew(this)
  return f(rawArray.concat.apply(rawArray, arguments))
}
export function slice (begin, end, a) {
  const rawArray = doNew(a || this)
  return f(rawArray.slice(begin, end))
}
export function indexOf (value, a) {
  const aa = doNew(a || this)
  return aa.indexOf(value)
}
export function find (callback, a) {
  const aa = doNew(a || this)
  return aa.find(callback)
}
export function findIndex (callback, a) {
  const aa = doNew(a || this)
  return aa.findIndex(callback)
}
export function includes (callback, fromIndex, a) {
  const aa = typeof fromIndex === 'number' ? a : fromIndex
  const fromI = typeof fromIndex === 'number' && fromIndex
  const aaa = doNew(aa || this)
  return aaa.includes(callback, fromI)
}
<|endoftext|>