<commit_before>'use strict';

import { Phaser } from 'phaser';
import { TrackManager } from './track-manager';

import { Grid } from 'grid';
import { PlayerGridEntity } from 'gridentity';

import { generateEnemy } from './grid-util';

import * as timeUtil from './time-util';

class GameState extends Phaser.State {
  preload() {
    TrackManager.getTrack('track-1', this)
      .then(track => {
        this.track = track;
        // this.playTrack(track);
      });
    this.load.audio('fail-sound', './tracks/fail.m4a');
    this.load.audio('succ-beat-1', './tracks/succ-beat-1.m4a');
    this.load.audio('succ-beat-2', './tracks/succ-beat-2.m4a');
    this.load.audio('succ-beat-3', './tracks/succ-beat-3.m4a');
    this.load.audio('succ-beat-4', './tracks/succ-beat-4.m4a');
    this.load.audio('grid-complete', './tracks/grid-complete.m4a');
    this.load.audio('intro-loop', './tracks/intro.m4a');
    this.load.image('logo', './images/logo.png');
  }

  create() {
    this.scoreAreaWidth = 35;

    this.level = 0;
    this.highScore = parseInt(localStorage.highScore, 10) || 0;

    this.grid = new Grid(3, 2, 75, 10, this.scoreAreaWidth, this.level);
    this.grid.origin = {
      x: this.scoreAreaWidth,
      y: 700 - 190,
    };

    this.game.scale.setGameSize(275 * 2 + this.scoreAreaWidth, 700);
    this.gameSize = Object.assign({}, {
      width: 275,
      height: 700,
    });

    this.player = new PlayerGridEntity(this.game, this.grid, { x: 0, y: 1 }, 0x00FF00);
    this.enemyGenerator = generateEnemy(this.level);
    this.enemies = [];

    this.graphics = this.game.add.graphics(0, 0);
    window.graphics = this.graphics;

    this.succSounds = [
      this.sound.add('succ-beat-1'),
      this.sound.add('succ-beat-2'),
      this.sound.add('succ-beat-3'),
      this.sound.add('succ-beat-4'),
    ];

    this.ulost = false;
    this.isWon = false;

    this.introTrack = this.sound.play('intro-loop', 1, true);
    this.logo = this.add.image(137.5 + this.scoreAreaWidth, 275, 'logo');
    this.logo.anchor = {
      x: 0.5,
      y: 0.5,
    };

    // Add captures so the keys don't scroll the page
    game.input.keyboard.addKeyCapture([
      Phaser.Keyboard.LEFT,
      Phaser.Keyboard.RIGHT,
      Phaser.Keyboard.UP,
      Phaser.Keyboard.DOWN,
    ]);
  }

  update() {
    if (!this.track) return;

    if (this.logo.visible) {
      this.logo.scale.set(1 + (this.getPulse() * 0.01));
    }

    if (this.introTrack.isPlaying) {
      const beat = Math.floor(this.introTrack.currentTime / timeUtil.msPerBeat(this.track.bpm));
      if (beat !== this.currentBeat) {
        if (beat % 2 === 1) {
          this.advance();
        }
        this.currentBeat = beat;
      }
    } else if (this.track.sound.isPlaying) {
      const beat = Math.floor(this.track.sound.currentTime / timeUtil.msPerBeat(this.track.bpm));
      if (beat !== this.currentBeat) {
        if (beat % 2 === 1) {
          this.advance();
        }
        this.currentBeat = beat;
      }
    }

    // Check collisions
    this.enemies.forEach(enemy => {
      if (enemy.collides(this.player, false)) {
        this.youLose();
      }
      if (enemy.collides(this.player, true)) {
        this.passThrough();
      }
    });

    if (this.ulost) {
      return;
    }

    // Check win state
    if ((!this.level && this.player.pos.y === 0 && this.player.pos.x === this.grid.width - 1) ||
        (this.level > 0 && this.player.pos.y === 1 && this.player.pos.x === this.grid.width - 1)) {
      this.handleWin();
    }

    this.player.update();
  }

  inputWithinWindow(bpm = this.track.bpm, beat = this.currentBeat,
                    timestamp = this.track.sound.currentTime || this.introTrack.currentTime) {
    const beatWindow = 75;

    function comp(_beat) {
      const upper = _beat * timeUtil.msPerBeat(bpm) + beatWindow;
      const lower = _beat * timeUtil.msPerBeat(bpm) - beatWindow;
      return (timestamp >= lower && timestamp <= upper);
    }

    return comp(beat) || comp(beat + 1);
  }

  /**
   * Returns a value 0 to 1 based on nearby beats. To be used for pulsating things
   */
  getPulse(bpm = this.track.bpm, beat = this.currentBeat,
           timestamp = this.track.sound.currentTime || this.introTrack.currentTime) {
    return ((beat + 1) * timeUtil.msPerBeat(bpm) - timestamp) / timeUtil.msPerBeat(bpm);
  }

  render() {
    this.graphics.clear();

    if (!this.track) return;

    // Do the background color
    this.graphics.beginFill(0x212121);
    this.graphics.drawRect(0, 0, this.game.width, this.game.height);
    this.graphics.endFill();

    // Do the outline
    const pulse = this.getPulse() * 2;
    const topLeft = {
      x: 2 - pulse + this.scoreAreaWidth,
      y: 2 - pulse,
    };
    const botRight = {
      x: this.scoreAreaWidth + this.gameSize.width - 1 - (2 - pulse),
      y: this.gameSize.height - 1 - (2 - pulse),
    };

    this.graphics.lineStyle(1, 0xFAFAFA, 1);
    this.graphics.moveTo(topLeft.x, topLeft.y);
    this.graphics.lineTo(botRight.x, topLeft.y);
    this.graphics.lineTo(botRight.x, botRight.y);
    this.graphics.lineTo(topLeft.x, botRight.y);
    this.graphics.lineTo(topLeft.x, topLeft.y);
    this.graphics.lineStyle(0, null, 0);

    this.grid.draw(this.graphics, this.getPulse());

    if (this.oldGrid) {
      this.oldGrid.draw(this.graphics, this.getPulse());
    }

    this.player.draw(this.graphics, this.getPulse());
    this.enemies.forEach(enemy => {
      enemy.draw(this.graphics, this.getPulse());
    });

    this.graphics.beginFill(0x212121);
    this.graphics.drawRect(this.gameSize.width + this.scoreAreaWidth, 0,
                           this.game.width, this.game.height);
    this.graphics.endFill();

    this.graphics.beginFill(0x212121);
    this.graphics.drawRect(0, 0, this.scoreAreaWidth, this.game.height);
    this.graphics.endFill();

    // Draw score area
    const spacing = 3;
    const height = 7;

    // High score ~~~ghosts~~~
    let curTop = botRight.y - height + 1;

    this.graphics.beginFill(0x212121);
    this.graphics.lineStyle(1, 0xFAFAFA, 1);
    for (let i = 1; i <= this.highScore; i++) {
      this.graphics.drawRect(0, curTop,
                             this.scoreAreaWidth - 2, height - 1);
      curTop -= height + spacing;
      if (i % 5 === 0) {
        curTop -= height;
      }
    }
    this.graphics.endFill();
    this.graphics.lineStyle(0, null, 0);

    curTop = botRight.y - height + 1;

    this.graphics.beginFill(0xFAFAFA);
    for (let i = 1; i <= this.level; i++) {
      this.graphics.drawRect(0, curTop,
                             this.scoreAreaWidth - 1, height);
      curTop -= height + spacing;
      if (i % 5 === 0) {
        curTop -= height;
      }
    }
    this.graphics.endFill();
  }

  advance() {
    this.enemies.forEach(enemy => {
      enemy.advance(timeUtil.msPerBeat(this.track.bpm));
    });

    const enemies = this.enemyGenerator.next();
    if (enemies.value) {
      this.enemies = this.enemies.concat(enemies.value.map(enemy => {
        Object.assign(enemy, {
          game: this.game,
          grid: this.grid,
        });
        return enemy;
      }));
    }

    this.enemies = this.enemies.filter(enemy => enemy.pos.y < 8);
  }

  playTrack(track) {
    this.track.sound = this.sound.add(track.key);
    this.track.sound.addMarker('intro', 0, 40, 1, true);
    this.track.sound.addMarker('loop', 40, 64);
    this.track.sound = this.track.sound.play('intro');
    this.track.sound.onMarkerComplete.add(() => {
      this.track.sound = this.track.sound.play('loop');
    });
    this.currentBeat = 0;
  }

  youLose() {
    if (!this.ulost) {
      this.maybeSetHighScore();
      this.ulost = true;
      this.sound.stopAll();
      this.sound.stopAll();
      this.sound.play('fail-sound');
      this.state.restart();
    }
  }

  handleWin() {
    const easing = Phaser.Easing.Circular.InOut;
    if (this.isWon) {
      return;
    }

    this.sound.play('grid-complete');

    this.isWon = true;
    this.level += 1;
    if (this.level === 1) {
      this.introTrack.stop();
      this.playTrack(this.track);
    }
    this.oldGrid = this.grid;
    this.grid = new Grid(3, 8, 75, 10, this.scoreAreaWidth, this.level);
    const gridSize = this.grid.getSize();
    if (this.level === 1) {
      this.grid.origin = {
        x: this.scoreAreaWidth + gridSize.width,
        y: -95,
      };
    } else {
      this.grid.origin = {
        x: this.scoreAreaWidth + gridSize.width,
        y: -gridSize.height + 190,
      };
    }

    this.player.grid = this.grid;
    this.player.pos = {
      x: 0,
      y: 7,
    };

    const tweenTime = timeUtil.msPerBeat(this.track.bpm) * (4 / 3);

    this.game.add.tween(this.gameSize)
      .to({ width: this.gameSize.width * 2 }, tweenTime, easing, true)
      .onComplete.add(() => {
        this.game.add.tween(this.grid.origin)
          .to({ y: 0 }, tweenTime, easing, true)
          .onComplete.add(() => {
            this.game.add.tween(this.grid.origin)
              .to({ x: this.scoreAreaWidth }, tweenTime, easing, true);
            this.game.add.tween(this.gameSize)
              .to({ width: this.gameSize.width / 2 }, tweenTime, easing, true)
              .onComplete.add(() => {
                this.isWon = false;
              });
          });

        this.game.add.tween(this.oldGrid.origin)
          .to({ y: this.oldGrid.origin.y + 510 }, tweenTime, easing, true)
          .onComplete.add(() => {
            this.game.add.tween(this.oldGrid.origin)
              .to({ x: -gridSize.width }, tweenTime, easing, true);
          });
        this.game.add.tween(this.logo)
          .to({ y: this.logo.y + 510 }, tweenTime, easing, true)
          .onComplete.add(() => {
            this.game.add.tween(this.logo)
              .to({ x: this.logo.x - gridSize.width }, tweenTime, easing, true);
          })
      });

    this.enemies = [];
    this.enemyGenerator.return();
    this.enemyGenerator = generateEnemy(this.level);
  }

  passThrough() {
    if (!this.succSounds.some(sound => sound.isPlaying)) {
      let currentBeat = this.currentBeat;
      let delay = this.track.sound.currentTime -
        (currentBeat * timeUtil.msPerBeat(this.track.bpm));

      if (delay > 400) {
        delay = this.track.sound.currentTime -
          ((currentBeat++) * timeUtil.msPerBeat(this.track.bpm));
      }

      this.succSounds[currentBeat % 4].play('', delay);
    }
  }

  maybeSetHighScore() {
    const highScore = localStorage.highScore;

    if (highScore) {
      if (parseInt(highScore, 10) < this.level) {
        localStorage.highScore = this.level;
      }
    } else {
      localStorage.highScore = this.level;
    }
  }
}

export { GameState };
<commit_msg>changed how background is rendered<commit_after>'use strict';

import { Phaser } from 'phaser';
import { TrackManager } from './track-manager';

import { Grid } from 'grid';
import { PlayerGridEntity } from 'gridentity';

import { generateEnemy } from './grid-util';

import * as timeUtil from './time-util';

class GameState extends Phaser.State {
  preload() {
    TrackManager.getTrack('track-1', this)
      .then(track => {
        this.track = track;
        // this.playTrack(track);
      });
    this.load.audio('fail-sound', './tracks/fail.m4a');
    this.load.audio('succ-beat-1', './tracks/succ-beat-1.m4a');
    this.load.audio('succ-beat-2', './tracks/succ-beat-2.m4a');
    this.load.audio('succ-beat-3', './tracks/succ-beat-3.m4a');
    this.load.audio('succ-beat-4', './tracks/succ-beat-4.m4a');
    this.load.audio('grid-complete', './tracks/grid-complete.m4a');
    this.load.audio('intro-loop', './tracks/intro.m4a');
    this.load.image('logo', './images/logo.png');
  }

  create() {
    this.scoreAreaWidth = 35;

    this.game.stage.backgroundColor = 0x212121;

    this.level = 0;
    this.highScore = parseInt(localStorage.highScore, 10) || 0;

    this.grid = new Grid(3, 2, 75, 10, this.scoreAreaWidth, this.level);
    this.grid.origin = {
      x: this.scoreAreaWidth,
      y: 700 - 190,
    };

    this.game.scale.setGameSize(275 * 2 + this.scoreAreaWidth, 700);
    this.gameSize = Object.assign({}, {
      width: 275,
      height: 700,
    });

    this.player = new PlayerGridEntity(this.game, this.grid, { x: 0, y: 1 }, 0x00FF00);
    this.enemyGenerator = generateEnemy(this.level);
    this.enemies = [];

    this.graphics = this.game.add.graphics(0, 0);
    window.graphics = this.graphics;

    this.succSounds = [
      this.sound.add('succ-beat-1'),
      this.sound.add('succ-beat-2'),
      this.sound.add('succ-beat-3'),
      this.sound.add('succ-beat-4'),
    ];

    this.ulost = false;
    this.isWon = false;

    this.introTrack = this.sound.play('intro-loop', 1, true);
    this.logo = this.add.image(137.5 + this.scoreAreaWidth, 275, 'logo');
    this.logo.anchor = {
      x: 0.5,
      y: 0.5,
    };

    // Add captures so the keys don't scroll the page
    game.input.keyboard.addKeyCapture([
      Phaser.Keyboard.LEFT,
      Phaser.Keyboard.RIGHT,
      Phaser.Keyboard.UP,
      Phaser.Keyboard.DOWN,
    ]);
  }

  update() {
    if (!this.track) return;

    if (this.logo.visible) {
      this.logo.scale.set(1 + (this.getPulse() * 0.01));
    }

    if (this.introTrack.isPlaying) {
      const beat = Math.floor(this.introTrack.currentTime / timeUtil.msPerBeat(this.track.bpm));
      if (beat !== this.currentBeat) {
        if (beat % 2 === 1) {
          this.advance();
        }
        this.currentBeat = beat;
      }
    } else if (this.track.sound.isPlaying) {
      const beat = Math.floor(this.track.sound.currentTime / timeUtil.msPerBeat(this.track.bpm));
      if (beat !== this.currentBeat) {
        if (beat % 2 === 1) {
          this.advance();
        }
        this.currentBeat = beat;
      }
    }

    // Check collisions
    this.enemies.forEach(enemy => {
      if (enemy.collides(this.player, false)) {
        this.youLose();
      }
      if (enemy.collides(this.player, true)) {
        this.passThrough();
      }
    });

    if (this.ulost) {
      return;
    }

    // Check win state
    if ((!this.level && this.player.pos.y === 0 && this.player.pos.x === this.grid.width - 1) ||
        (this.level > 0 && this.player.pos.y === 1 && this.player.pos.x === this.grid.width - 1)) {
      this.handleWin();
    }

    this.player.update();
  }

  inputWithinWindow(bpm = this.track.bpm, beat = this.currentBeat,
                    timestamp = this.track.sound.currentTime || this.introTrack.currentTime) {
    const beatWindow = 75;

    function comp(_beat) {
      const upper = _beat * timeUtil.msPerBeat(bpm) + beatWindow;
      const lower = _beat * timeUtil.msPerBeat(bpm) - beatWindow;
      return (timestamp >= lower && timestamp <= upper);
    }

    return comp(beat) || comp(beat + 1);
  }

  /**
   * Returns a value 0 to 1 based on nearby beats. To be used for pulsating things
   */
  getPulse(bpm = this.track.bpm, beat = this.currentBeat,
           timestamp = this.track.sound.currentTime || this.introTrack.currentTime) {
    return ((beat + 1) * timeUtil.msPerBeat(bpm) - timestamp) / timeUtil.msPerBeat(bpm);
  }

  render() {
    this.graphics.clear();

    if (!this.track) return;

    // Do the outline
    const pulse = this.getPulse() * 2;
    const topLeft = {
      x: 2 - pulse + this.scoreAreaWidth,
      y: 2 - pulse,
    };
    const botRight = {
      x: this.scoreAreaWidth + this.gameSize.width - 1 - (2 - pulse),
      y: this.gameSize.height - 1 - (2 - pulse),
    };

    this.graphics.lineStyle(1, 0xFAFAFA, 1);
    this.graphics.moveTo(topLeft.x, topLeft.y);
    this.graphics.lineTo(botRight.x, topLeft.y);
    this.graphics.lineTo(botRight.x, botRight.y);
    this.graphics.lineTo(topLeft.x, botRight.y);
    this.graphics.lineTo(topLeft.x, topLeft.y);
    this.graphics.lineStyle(0, null, 0);

    this.grid.draw(this.graphics, this.getPulse());

    if (this.oldGrid) {
      this.oldGrid.draw(this.graphics, this.getPulse());
    }

    this.player.draw(this.graphics, this.getPulse());
    this.enemies.forEach(enemy => {
      enemy.draw(this.graphics, this.getPulse());
    });

    this.graphics.beginFill(0x212121);
    this.graphics.drawRect(this.gameSize.width + this.scoreAreaWidth, 0,
                           this.game.width, this.game.height);
    this.graphics.endFill();

    this.graphics.beginFill(0x212121);
    this.graphics.drawRect(0, 0, this.scoreAreaWidth, this.game.height);
    this.graphics.endFill();

    // Draw score area
    const spacing = 3;
    const height = 7;

    // High score ~~~ghosts~~~
    let curTop = botRight.y - height + 1;

    this.graphics.beginFill(0x212121);
    this.graphics.lineStyle(1, 0xFAFAFA, 1);
    for (let i = 1; i <= this.highScore; i++) {
      this.graphics.drawRect(0, curTop,
                             this.scoreAreaWidth - 2, height - 1);
      curTop -= height + spacing;
      if (i % 5 === 0) {
        curTop -= height;
      }
    }
    this.graphics.endFill();
    this.graphics.lineStyle(0, null, 0);

    curTop = botRight.y - height + 1;

    this.graphics.beginFill(0xFAFAFA);
    for (let i = 1; i <= this.level; i++) {
      this.graphics.drawRect(0, curTop,
                             this.scoreAreaWidth - 1, height);
      curTop -= height + spacing;
      if (i % 5 === 0) {
        curTop -= height;
      }
    }
    this.graphics.endFill();
  }

  advance() {
    this.enemies.forEach(enemy => {
      enemy.advance(timeUtil.msPerBeat(this.track.bpm));
    });

    const enemies = this.enemyGenerator.next();
    if (enemies.value) {
      this.enemies = this.enemies.concat(enemies.value.map(enemy => {
        Object.assign(enemy, {
          game: this.game,
          grid: this.grid,
        });
        return enemy;
      }));
    }

    this.enemies = this.enemies.filter(enemy => enemy.pos.y < 8);
  }

  playTrack(track) {
    this.track.sound = this.sound.add(track.key);
    this.track.sound.addMarker('intro', 0, 40, 1, true);
    this.track.sound.addMarker('loop', 40, 64);
    this.track.sound = this.track.sound.play('intro');
    this.track.sound.onMarkerComplete.add(() => {
      this.track.sound = this.track.sound.play('loop');
    });
    this.currentBeat = 0;
  }

  youLose() {
    if (!this.ulost) {
      this.maybeSetHighScore();
      this.ulost = true;
      this.sound.stopAll();
      this.sound.stopAll();
      this.sound.play('fail-sound');
      this.state.restart();
    }
  }

  handleWin() {
    const easing = Phaser.Easing.Circular.InOut;
    if (this.isWon) {
      return;
    }

    this.sound.play('grid-complete');

    this.isWon = true;
    this.level += 1;
    if (this.level === 1) {
      this.introTrack.stop();
      this.playTrack(this.track);
    }
    this.oldGrid = this.grid;
    this.grid = new Grid(3, 8, 75, 10, this.scoreAreaWidth, this.level);
    const gridSize = this.grid.getSize();
    if (this.level === 1) {
      this.grid.origin = {
        x: this.scoreAreaWidth + gridSize.width,
        y: -95,
      };
    } else {
      this.grid.origin = {
        x: this.scoreAreaWidth + gridSize.width,
        y: -gridSize.height + 190,
      };
    }

    this.player.grid = this.grid;
    this.player.pos = {
      x: 0,
      y: 7,
    };

    const tweenTime = timeUtil.msPerBeat(this.track.bpm) * (4 / 3);

    this.game.add.tween(this.gameSize)
      .to({ width: this.gameSize.width * 2 }, tweenTime, easing, true)
      .onComplete.add(() => {
        this.game.add.tween(this.grid.origin)
          .to({ y: 0 }, tweenTime, easing, true)
          .onComplete.add(() => {
            this.game.add.tween(this.grid.origin)
              .to({ x: this.scoreAreaWidth }, tweenTime, easing, true);
            this.game.add.tween(this.gameSize)
              .to({ width: this.gameSize.width / 2 }, tweenTime, easing, true)
              .onComplete.add(() => {
                this.isWon = false;
              });
          });

        this.game.add.tween(this.oldGrid.origin)
          .to({ y: this.oldGrid.origin.y + 510 }, tweenTime, easing, true)
          .onComplete.add(() => {
            this.game.add.tween(this.oldGrid.origin)
              .to({ x: -gridSize.width }, tweenTime, easing, true);
          });
        this.game.add.tween(this.logo)
          .to({ y: this.logo.y + 510 }, tweenTime, easing, true)
          .onComplete.add(() => {
            this.game.add.tween(this.logo)
              .to({ x: this.logo.x - gridSize.width }, tweenTime, easing, true);
          })
      });

    this.enemies = [];
    this.enemyGenerator.return();
    this.enemyGenerator = generateEnemy(this.level);
  }

  passThrough() {
    if (!this.succSounds.some(sound => sound.isPlaying)) {
      let currentBeat = this.currentBeat;
      let delay = this.track.sound.currentTime -
        (currentBeat * timeUtil.msPerBeat(this.track.bpm));

      if (delay > 400) {
        delay = this.track.sound.currentTime -
          ((currentBeat++) * timeUtil.msPerBeat(this.track.bpm));
      }

      this.succSounds[currentBeat % 4].play('', delay);
    }
  }

  maybeSetHighScore() {
    const highScore = localStorage.highScore;

    if (highScore) {
      if (parseInt(highScore, 10) < this.level) {
        localStorage.highScore = this.level;
      }
    } else {
      localStorage.highScore = this.level;
    }
  }
}

export { GameState };
<|endoftext|>


<commit_before>/*
unFocus.FlashPlayerInfo, version 1.1 b6 (beta) (2007/09/11)
Copyright: 2005-2007, Kevin Newman (http://www.unfocus.com/Projects/)

This file is part of unFocus.History Keeper.

unFocus.History Keeper is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 3 of the License, or (at your option) any later version.

unFocus.History Keeper is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
if (!window.unFocus) var unFocus = {};

unFocus.FlashPlayerInfo = (function() {
	// private vars
	var _installed = false,
		_beta = false,
		_version = 0,
		_majorRevision = 0,
		_minorRevision = 0,
		_betaVersion = 0,
		_versionRaw = "",
		_playerType = "",
		_releaseCode = "";

	// detection work
	if (navigator.plugins && navigator.plugins.length > 0) {
		_versionRaw = navigator.plugins["Shockwave Flash 2.0"] || navigator.plugins["Shockwave Flash"];
		if (_versionRaw) {
			_versionRaw = _versionRaw.description;
			_installed = true;
			_playerType = "PlugIn";
			if (/Shockwave Flash/.test(_versionRaw)) {
				_version = _versionRaw.match(/Shockwave Flash (\d)\.(\d)/);
				_majorRevision = _version[2];
				if (/r\d+/.test(_versionRaw)) {
					_releaseCode = "r";
					_minorRevision = _versionRaw.match(/r(\d+)/)[1];
				}
				_version = _version[1];
				if (/[abd]\d+/.test(_versionRaw)) { // I'm not sure what other letters would be here, but I've encountered b, d and a (alpha) so far
					_betaVersion = _versionRaw.match(/([abd])(\d+)/);
					_releaseCode = _betaVersion[1];
					_beta = true;
					_betaVersion = _betaVersion[2];
				}
			} else _version = 1;
		}
	} else if (window.ActiveXObject) {
		// src: Player.vbs
		var _ax;
		function _getActiveXObject($objectString) {
			try {
				_ax = new ActiveXObject($objectString);
				return true;
			} catch (e){
				return false;
			}
		}
		var _versionTemp;

		function _parseVersion() {
			var _versionTemp = _ax.GetVariable("$version");
			_versionRaw = _versionTemp;
			_versionTemp = _versionTemp.split(",");
			_version = _versionTemp[0].match(/\d+/);
			_majorRevision = _versionTemp[1];
			_minorRevision = _versionTemp[2];
			_betaVersion = _versionTemp[3];
			if (_versionTemp[3]>0) _beta = true;
			// if the last number is 0, assume this is a release version
			else _releaseCode = "r";
		}

		// we have to detect around Flash 6, since it can crash some versions of IE
		if (_getActiveXObject("ShockwaveFlash.ShockwaveFlash.7"))
			_parseVersion();
		else if (_getActiveXObject("ShockwaveFlash.ShockwaveFlash.6")) {
			// tread lightly
			try {
				// will throw error if < 6.0.47 (info glombed from Adobe's Detection Kit - thanks!)
				_ax.AllowScriptAccess = "always";
				// now safe to call GetVariable
				_parseVersion();
			} catch (e) {
				_version = 6;
				_minorRevision = 0; // cannot be safely detected
			}
		} else if (_getActiveXObject("ShockwaveFlash.ShockwaveFlash.5"))
			_parseVersion();
		else if (_getActiveXObject("ShockwaveFlash.ShockwaveFlash.4"))
			_version = 4;
		else if (_getActiveXObject("ShockwaveFlash.ShockwaveFlash.3"))
			_version = 3;
		else if (_getActiveXObject("ShockwaveFlash.ShockwaveFlash"))
			// Tested on Windows 95 with flash player 2 - using the ".2" at the end doesn't work, but this does ;-)
			// :BUG: This doesn't seem to work when FP2 is installed in WinXP
			_version = 2;
		if (_version) {
			_installed = true;
			_playerType = "ActiveX";
		}
	} else if (/WebTV/.test(navigator.userAgent)) { // WebTV
		_playerType = "WebTV";
		_versionRaw = navigator.userAgent.match(/WebTV\/(\d\.\d)/)[1];
		if (_versionRaw > 2.5) _version = 4;
		else if (_versionRaw == 2.5) _version = 3;
		else _version = 2;
	}

	// public/priveleged Getters
	var FlashPlayerInfo = {
		isInstalled: function() {
			return _installed;
		},
		isBeta: function() {
			return _beta;
		},
		getVersion: function() {
			return _version;
		},
		getMajorRevision: function() {
			return _majorRevision;
		},
		getMinorRevision: function() {
			return _minorRevision;
		},
		getBetaVersion: function() {
			return _betaVersion;
		},
		getVersionRaw: function() {
			return _versionRaw;
		},
		// for backward compat - deprecated, will be removed in next version
		getPluginType: function() {
			return this.getPlayerType();
		},
		getPlayerType: function() {
			return _playerType;
		},
		getReleaseCode: function() {
			return _releaseCode;
		}
	};
	return FlashPlayerInfo;
})();
<commit_msg>Fixed Flash Player 10 PlugIn detection.<commit_after>/*
unFocus.FlashPlayerInfo, version 1.1 b7 (beta) (2008/05/20)
Copyright: 2005-2008, Kevin Newman (http://www.unfocus.com/Projects/)

This file is part of unFocus.History Keeper.

unFocus.History Keeper is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 3 of the License, or (at your option) any later version.

unFocus.History Keeper is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
if (!window.unFocus) var unFocus = {};

unFocus.FlashPlayerInfo = (function() {
	// private vars
	var _installed = false,
		_beta = false,
		_version = 0,
		_majorRevision = 0,
		_minorRevision = 0,
		_betaVersion = 0,
		_versionRaw = "",
		_playerType = "",
		_releaseCode = "";

	// detection work
	if (navigator.plugins && navigator.plugins.length > 0) {
		_versionRaw = navigator.plugins["Shockwave Flash 2.0"] || navigator.plugins["Shockwave Flash"];
		if (_versionRaw) {
			_versionRaw = _versionRaw.description;
			_installed = true;
			_playerType = "PlugIn";
			if (/Shockwave Flash/.test(_versionRaw)) {
				_version = _versionRaw.match(/Shockwave Flash (\d+)\.(\d+)/);
				_majorRevision = _version[2];
				if (/r\d+/.test(_versionRaw)) {
					_releaseCode = "r";
					_minorRevision = _versionRaw.match(/r(\d+)/)[1];
				}
				_version = _version[1];
				if (/[abd]\d+/.test(_versionRaw)) { // I'm not sure what other letters would be here, but I've encountered b, d and a (alpha) so far
					_betaVersion = _versionRaw.match(/([abd])(\d+)/);
					_releaseCode = _betaVersion[1];
					_beta = true;
					_betaVersion = _betaVersion[2];
				}
			} else _version = 1;
		}
	} else if (window.ActiveXObject) {
		// src: Player.vbs
		var _ax;
		function _getActiveXObject($objectString) {
			try {
				_ax = new ActiveXObject($objectString);
				return true;
			} catch (e){
				return false;
			}
		}
		var _versionTemp;

		function _parseVersion() {
			var _versionTemp = _ax.GetVariable("$version");
			_versionRaw = _versionTemp;
			_versionTemp = _versionTemp.split(",");
			_version = _versionTemp[0].match(/\d+/);
			_majorRevision = _versionTemp[1];
			_minorRevision = _versionTemp[2];
			_betaVersion = _versionTemp[3];
			if (_versionTemp[3]>0) _beta = true;
			// if the last number is 0, assume this is a release version
			else _releaseCode = "r";
		}

		// we have to detect around Flash 6, since it can crash some versions of IE
		if (_getActiveXObject("ShockwaveFlash.ShockwaveFlash.7"))
			_parseVersion();
		else if (_getActiveXObject("ShockwaveFlash.ShockwaveFlash.6")) {
			// tread lightly
			try {
				// will throw error if < 6.0.47 (info glombed from Adobe's Detection Kit - thanks!)
				_ax.AllowScriptAccess = "always";
				// now safe to call GetVariable
				_parseVersion();
			} catch (e) {
				_version = 6;
				_minorRevision = 0; // cannot be safely detected
			}
		} else if (_getActiveXObject("ShockwaveFlash.ShockwaveFlash.5"))
			_parseVersion();
		else if (_getActiveXObject("ShockwaveFlash.ShockwaveFlash.4"))
			_version = 4;
		else if (_getActiveXObject("ShockwaveFlash.ShockwaveFlash.3"))
			_version = 3;
		else if (_getActiveXObject("ShockwaveFlash.ShockwaveFlash"))
			// Tested on Windows 95 with flash player 2 - using the ".2" at the end doesn't work, but this does ;-)
			// :BUG: This doesn't seem to work when FP2 is installed in WinXP
			_version = 2;
		if (_version) {
			_installed = true;
			_playerType = "ActiveX";
		}
	} else if (/WebTV/.test(navigator.userAgent)) { // WebTV
		_playerType = "WebTV";
		_versionRaw = navigator.userAgent.match(/WebTV\/(\d\.\d)/)[1];
		if (_versionRaw > 2.5) _version = 4;
		else if (_versionRaw == 2.5) _version = 3;
		else _version = 2;
	}

	// public/priveleged Getters
	var FlashPlayerInfo = {
		isInstalled: function() {
			return _installed;
		},
		isBeta: function() {
			return _beta;
		},
		getVersion: function() {
			return _version;
		},
		getMajorRevision: function() {
			return _majorRevision;
		},
		getMinorRevision: function() {
			return _minorRevision;
		},
		getBetaVersion: function() {
			return _betaVersion;
		},
		getVersionRaw: function() {
			return _versionRaw;
		},
		// for backward compat - deprecated, will be removed in next version
		getPluginType: function() {
			return this.getPlayerType();
		},
		getPlayerType: function() {
			return _playerType;
		},
		getReleaseCode: function() {
			return _releaseCode;
		}
	};
	return FlashPlayerInfo;
})();
<|endoftext|>


<commit_before>var util = require("util")
var stream = require("stream")
module.exports.type = "xlsx"

var XLSX_MAGIC = new Buffer([0x50, 0x4b, 0x03, 0x04])
var XLS_MAGIC = new Buffer([0xd0, 0xcf, 0x11, 0xe0, 0xa1, 0xb1, 0x1a, 0xe1])

module.exports.is = function isCSV( sample, options ) {
    if (!(sample instanceof Buffer)) {
        return false
    }

    return sample.slice(0, XLSX_MAGIC.length).equals(XLSX_MAGIC)
        || sample.slice(0, XLS_MAGIC.length).equals(XLS_MAGIC)
}

module.exports.parser = function ( options ) {
    return new Stream()
}

module.exports.requires = [ "xlsx" ]

util.inherits(Stream, stream.Transform)
function Stream() {
    stream.Transform.call(this, { readableObjectMode: true })
    this._buff = new Buffer([])
}

Stream.prototype._transform = function (data, enc, done) {
    this._buff = Buffer.concat([this._buff, data])
    done()
}

Stream.prototype._flush = function (done) {
    var xlsx = require( "xlsx" )
    try {
        var workbook = xlsx.read(this._buff)
    } catch (err) {
        done(err)
        return
    }

    var regexp = /([A-Z]+)([0-9]+)/i
    workbook.SheetNames.forEach(function (name) {
        var sheet = workbook.Sheets[name]
        var data = []
        for (var k in sheet) {
            if (k[0] == '!') {
                continue // Only keep normal cells, not metadata.
            }

            // k is a cell name, i.e. "A1", "C9". Split it into the row and col
            var comps = k.match(regexp)
            var col = comps[1]
            var row = comps[2]
            if (row == '1') {
                continue // first row is reserved as the header line
            }

            if (!data[row]) {
                data[row] = { __sheet: name }
            }

            // extract the header name value from the first row for this col
            var h = sheet[col + '1'].v
            data[row][h] = sheet[k].v
        }

        // the data list may contain some empty undefined cells (at rows 0 and
        // 1). Filter these out.
        data.filter(Boolean).forEach(function (d) {
            this.push(d)
        }, this)
    }, this)

    done(null)
}
<commit_msg>fetch the formatted value if available<commit_after>var util = require("util")
var stream = require("stream")
module.exports.type = "xlsx"

var XLSX_MAGIC = new Buffer([0x50, 0x4b, 0x03, 0x04])
var XLS_MAGIC = new Buffer([0xd0, 0xcf, 0x11, 0xe0, 0xa1, 0xb1, 0x1a, 0xe1])

module.exports.is = function isCSV( sample, options ) {
    if (!(sample instanceof Buffer)) {
        return false
    }

    return sample.slice(0, XLSX_MAGIC.length).equals(XLSX_MAGIC)
        || sample.slice(0, XLS_MAGIC.length).equals(XLS_MAGIC)
}

module.exports.parser = function ( options ) {
    return new Stream()
}

module.exports.requires = [ "xlsx" ]

util.inherits(Stream, stream.Transform)
function Stream() {
    stream.Transform.call(this, { readableObjectMode: true })
    this._buff = new Buffer([])
}

Stream.prototype._transform = function (data, enc, done) {
    this._buff = Buffer.concat([this._buff, data])
    done()
}

Stream.prototype._flush = function (done) {
    var xlsx = require( "xlsx" )
    try {
        var workbook = xlsx.read(this._buff)
    } catch (err) {
        done(err)
        return
    }

    var regexp = /([A-Z]+)([0-9]+)/i
    workbook.SheetNames.forEach(function (name) {
        var sheet = workbook.Sheets[name]
        var data = []
        for (var k in sheet) {
            if (k[0] == '!') {
                continue // Only keep normal cells, not metadata.
            }

            // k is a cell name, i.e. "A1", "C9". Split it into the row and col
            var comps = k.match(regexp)
            var col = comps[1]
            var row = comps[2]
            if (row == '1') {
                continue // first row is reserved as the header line
            }

            if (!data[row]) {
                data[row] = { __sheet: name }
            }

            // extract the header name value from the first row for this col
            var h = sheet[col + '1'].v
                data[row][h] = sheet[k].w || sheet[k].v
        }

        // the data list may contain some empty undefined cells (at rows 0 and
        // 1). Filter these out.
        data.filter(Boolean).forEach(function (d) {
            this.push(d)
        }, this)
    }, this)

    done(null)
}
<|endoftext|>


<commit_before>(function (factory) {
    if (typeof exports === 'object') {
        module.exports = factory(require('backbone'), require('underscore'), require('jquery'));
    } else if (typeof define === 'function' && define.amd) {
        define(['backbone', 'underscore', 'jquery'], factory);
    }
} (function (Backbone, _, $) {
    Backbone.HypermediaModel = Backbone.Model.extend({
        follow: function () {
            if (!this.links) {
                return;
            }

            var keys = _.keys(this.links);
            var promises = new Array();

            for (var i = 0; i < keys.length; i++) {
                var key = keys[i];
                var context;
                var links;
                var self = this;

                if (key.split('.').length > 1) {
                    var attr = key.split('.')[0];
                    key = key.split('.')[1];
                    context = this.get(attr);

                    if (context instanceof Array) {
                        _.forEach(context, function (item) {
                            links = item.links;
                            self._addPromise(promises, links, self, item, key, keys[i]);
                        });
                        continue;
                    } else if (context instanceof Backbone.Collection) {
                        context.each(function (item) {
                            links = item.get('links');
                            self._addPromise(promises, links, self, item, key, keys[i]);
                        });
                    } else {
                        links = context.links;
                    }
                } else {
                    context = this;
                    links = this.get('links');
                }

                this._addPromise(promises, links, this, context, key, keys[i]);
            }

            return $.when.apply($, promises);
        },

        _addPromise: function (promises, links, model, context, key, linkIndex) {
            var isArray = key.indexOf('[]', key.length - 2) !== -1;

            if (isArray) {
                key = key.substr(0, key.length - 2);
            }

            var rels = _.filter(links, function (l) { return l.rel == key; });

            if (rels.length > 1 && !isArray) {
                throw 'Found more than one link with rel \'' + key + '\', but the link was not specified as allowing multiple values. To allow multiple values, suffix the link key with \'[]\'.';
            }

            for (var i = 0; i < rels.length; i++) {
                var related = new model.links[linkIndex](),
                    urlFactory = _.isFunction(related.urlFactory) ? related.urlFactory : _.identity;

                if (isArray) {
                    if (!context[key]) {
                        context[key] = new Array();
                    }

                    context[key].push(related);
                } else {
                    context[key] = related;
                }

                promises.push(related.fetch({ url: urlFactory(rels[i].href) }));
            }
        },

        fetch: function (options) {
            var self = this;

            return Backbone.Model.prototype.fetch.call(this, options)
                .then(function () {
                    if (self.follow) {
                        return self.follow();
                    }
                })
                .then(function () {
                    if (self.follow) {
                        self.trigger('follow');
                    }
                });
        },

        sync: function (method, model, options) {
            if (this.mediaType) {
                options.accepts = { json: this.mediaType };

                if (method === 'create' || method === 'update' || method === 'patch') {
                    options.contentType = this.mediaType;
                }
            }

            return Backbone.sync(method, model, options);
        },

        toJSON: function () {
            var json = Backbone.Model.prototype.toJSON.apply(this, arguments);

            // use extend to create a deep copy, otherwise complex properties
            // are copied by reference, and any subsequent changes
            // are made against the model
            json = $.extend(true, {}, json);

            if (this.links) {
                var keys = _.keys(this.links);
                var self = this;

                _.each(keys, function (key) {
                    var context;
                    var jsonContext;

                    if (key.split('.').length > 1) {
                        var attr = key.split('.')[0];
                        key = key.split('.')[1];
                        context = self.get(attr);
                        jsonContext = json[attr];
                    } else {
                        context = self;
                        jsonContext = json;
                    }

                    var isArray = key.indexOf('[]', key.length - 2) !== -1;

                    if (isArray) {
                        key = key.substr(0, key.length - 2);
                    }

                    if (context[key]) {
                        if (isArray) {
                            jsonContext[key] = new Array();

                            for (var i = 0; i < context[key].length; i++) {
                                jsonContext[key].push(context[key][i].toJSON());
                            }
                        } else {
                            jsonContext[key] = context[key].toJSON();
                        }
                    }
                });
            }

            return json;
        }
    });

    Backbone.HypermediaCollection = Backbone.Collection.extend({
        fetch: function (options) {
            var self = this;

            return Backbone.Collection.prototype.fetch.call(this, options).then(function () {
                return $.when.apply($, self.map(function (model) {
                    return model.follow();
                }));
            })
            .then(function () {
                self.trigger('follow');
            });
        },

        sync: function (method, model, options) {
            if (this.mediaType) {
                options.accepts = { json: this.mediaType };
            }

            return Backbone.sync(method, model, options);
        }
    });
}));<commit_msg>Added ability to follow to cope with a Backbone model sub-object.<commit_after>(function (factory) {
    if (typeof exports === 'object') {
        module.exports = factory(require('backbone'), require('underscore'), require('jquery'));
    } else if (typeof define === 'function' && define.amd) {
        define(['backbone', 'underscore', 'jquery'], factory);
    }
} (function (Backbone, _, $) {
    Backbone.HypermediaModel = Backbone.Model.extend({
        follow: function () {
            if (!this.links) {
                return;
            }

            var keys = _.keys(this.links);
            var promises = new Array();

            for (var i = 0; i < keys.length; i++) {
                var key = keys[i];
                var context;
                var links;
                var self = this;

                if (key.split('.').length > 1) {
                    var attr = key.split('.')[0];
                    key = key.split('.')[1];
                    context = this.get(attr);

                    if (context instanceof Array) {
                        _.forEach(context, function (item) {
                            links = item.links;
                            self._addPromise(promises, links, self, item, key, keys[i]);
                        });
                        continue;
                    } else if (context instanceof Backbone.Collection) {
                        context.each(function (item) {
                            links = item.get('links');
                            self._addPromise(promises, links, self, item, key, keys[i]);
                        });
                    } else if (context instanceof Backbone.Model) {
                        links = context.get('links');
                    } else {
                        links = context.links;
                    }
                } else {
                    context = this;
                    links = this.get('links');
                }

                this._addPromise(promises, links, this, context, key, keys[i]);
            }

            return $.when.apply($, promises);
        },

        _addPromise: function (promises, links, model, context, key, linkIndex) {
            var isArray = key.indexOf('[]', key.length - 2) !== -1;

            if (isArray) {
                key = key.substr(0, key.length - 2);
            }

            var rels = _.filter(links, function (l) { return l.rel == key; });

            if (rels.length > 1 && !isArray) {
                throw 'Found more than one link with rel \'' + key + '\', but the link was not specified as allowing multiple values. To allow multiple values, suffix the link key with \'[]\'.';
            }

            for (var i = 0; i < rels.length; i++) {
                var related = new model.links[linkIndex](),
                    urlFactory = _.isFunction(related.urlFactory) ? related.urlFactory : _.identity;

                if (isArray) {
                    if (!context[key]) {
                        context[key] = new Array();
                    }

                    context[key].push(related);
                } else {
                    context[key] = related;
                }

                promises.push(related.fetch({ url: urlFactory(rels[i].href) }));
            }
        },

        fetch: function (options) {
            var self = this;

            return Backbone.Model.prototype.fetch.call(this, options)
                .then(function () {
                    if (self.follow) {
                        return self.follow();
                    }
                })
                .then(function () {
                    if (self.follow) {
                        self.trigger('follow');
                    }
                });
        },

        sync: function (method, model, options) {
            if (this.mediaType) {
                options.accepts = { json: this.mediaType };

                if (method === 'create' || method === 'update' || method === 'patch') {
                    options.contentType = this.mediaType;
                }
            }

            return Backbone.sync(method, model, options);
        },

        toJSON: function () {
            var json = Backbone.Model.prototype.toJSON.apply(this, arguments);

            // use extend to create a deep copy, otherwise complex properties
            // are copied by reference, and any subsequent changes
            // are made against the model
            json = $.extend(true, {}, json);

            if (this.links) {
                var keys = _.keys(this.links);
                var self = this;

                _.each(keys, function (key) {
                    var context;
                    var jsonContext;

                    if (key.split('.').length > 1) {
                        var attr = key.split('.')[0];
                        key = key.split('.')[1];
                        context = self.get(attr);
                        jsonContext = json[attr];
                    } else {
                        context = self;
                        jsonContext = json;
                    }

                    var isArray = key.indexOf('[]', key.length - 2) !== -1;

                    if (isArray) {
                        key = key.substr(0, key.length - 2);
                    }

                    if (context[key]) {
                        if (isArray) {
                            jsonContext[key] = new Array();

                            for (var i = 0; i < context[key].length; i++) {
                                jsonContext[key].push(context[key][i].toJSON());
                            }
                        } else {
                            jsonContext[key] = context[key].toJSON();
                        }
                    }
                });
            }

            return json;
        }
    });

    Backbone.HypermediaCollection = Backbone.Collection.extend({
        fetch: function (options) {
            var self = this;

            return Backbone.Collection.prototype.fetch.call(this, options).then(function () {
                return $.when.apply($, self.map(function (model) {
                    return model.follow();
                }));
            })
            .then(function () {
                self.trigger('follow');
            });
        },

        sync: function (method, model, options) {
            if (this.mediaType) {
                options.accepts = { json: this.mediaType };
            }

            return Backbone.sync(method, model, options);
        }
    });
}));<|endoftext|>


<commit_before>const initialState = {
  images: [],
  activeImageId: null,

  items: [],
  pickingPositionForId: null,

  uploadingId: null,

  tags: [],
};

export default function elevationMeasurement(state = initialState, action) {
  switch (action.type) {
    case 'MAP_RESET':
    case 'SET_TOOL':
      return initialState;
    case 'SET_ACTIVE_MODAL':
      return {
        ...state,
        items: [],
        pickingPositionForId: null,
      };
    case 'GALLERY_SET_IMAGES':
      return {
        ...state,
        images: action.payload,
        activeImageId: action.payload.length ? action.payload[0].id : null,
      };
    case 'GALLERY_SET_ACTIVE_IMAGE_ID':
      return {
        ...state,
        activeImageId: action.payload,
      };

    case 'GALLERY_ADD_ITEM':
      return {
        ...state,
        items: [...state.items, action.payload],
      };
    case 'GALLERY_REMOVE_ITEM':
      return {
        ...state,
        items: state.items.filter(({ id }) => action.payload !== id),
      };
    case 'GALLERY_SET_ITEM_URL':
      return {
        ...state,
        items: state.items.map(item => (item.id === action.payload.id ? { ...item, dataURL: action.payload.value } : item)),
      };
    case 'GALLERY_SET_ITEM_TITLE':
      return {
        ...state,
        items: state.items.map(item => (item.id === action.payload.id ? { ...item, title: action.payload.value } : item)),
      };
    case 'GALLERY_SET_ITEM_DESCRIPTION':
      return {
        ...state,
        items: state.items.map(item => (item.id === action.payload.id ? { ...item, description: action.payload.value } : item)),
      };
    case 'GALLERY_SET_ITEM_TAKEN_AT':
      return {
        ...state,
        items: state.items.map(item => (item.id === action.payload.id ? { ...item, takenAt: action.payload.value } : item)),
      };
    case 'GALLERY_SET_ITEM_TAGS':
      return {
        ...state,
        items: state.items.map(item => (item.id === action.payload.id ? { ...item, tags: action.payload.value } : item)),
      };
    case 'GALLERY_SET_ITEM_ERROR':
      return {
        ...state,
        items: state.items.map(item => (item.id === action.payload.id ? { ...item, error: action.payload.value } : item)),
      };
    case 'GALLERY_SET_PICKING_POSITION':
      return {
        ...state,
        pickingPosition: action.payload,
      };
    case 'GALLERY_CONFIRM_PICKED_POSITION':
      return {
        ...state,
        pickingPositionForId: null,
        pickingPosition: null,
        items: state.items.map(item => (item.id === state.pickingPositionForId ? { ...item, position: state.pickingPosition } : item)),
      };
    case 'GALLERY_SET_ITEM_FOR_POSITION_PICKING':
      return {
        ...state,
        pickingPositionForId: action.payload,
        pickingPosition: typeof action.payload === 'number' ? state.items.find(({ id }) => id === action.payload).position : null,
      };
    case 'GALLERY_UPLOAD':
    {
      const items = state.uploadingId === null ? state.items.map(item => ({ ...item, error: getError(item) })) : state.items;
      const next = items.find(item => !item.error);

      return {
        ...state,
        items,
        uploadingId: next ? next.id : null,
      };
    }
    case 'GALLERY_SET_TAGS':
      return { ...state, tags: action.payload };
    default:
      return state;
  }
}

function getError(item) {
  const errors = [];
  if (!item.position) {
    errors.push('Chýba pozícía.');
  }
  if (item.takenAt && isNaN(item.takenAt)) {
    errors.push('Nevalidný dátum a čas fotenia.');
  }
  return errors.length ? errors.join('\n') : null;
}
<commit_msg>fixed typo<commit_after>const initialState = {
  images: [],
  activeImageId: null,

  items: [],
  pickingPositionForId: null,

  uploadingId: null,

  tags: [],
};

export default function elevationMeasurement(state = initialState, action) {
  switch (action.type) {
    case 'MAP_RESET':
    case 'SET_TOOL':
      return initialState;
    case 'SET_ACTIVE_MODAL':
      return {
        ...state,
        items: [],
        pickingPositionForId: null,
      };
    case 'GALLERY_SET_IMAGES':
      return {
        ...state,
        images: action.payload,
        activeImageId: action.payload.length ? action.payload[0].id : null,
      };
    case 'GALLERY_SET_ACTIVE_IMAGE_ID':
      return {
        ...state,
        activeImageId: action.payload,
      };

    case 'GALLERY_ADD_ITEM':
      return {
        ...state,
        items: [...state.items, action.payload],
      };
    case 'GALLERY_REMOVE_ITEM':
      return {
        ...state,
        items: state.items.filter(({ id }) => action.payload !== id),
      };
    case 'GALLERY_SET_ITEM_URL':
      return {
        ...state,
        items: state.items.map(item => (item.id === action.payload.id ? { ...item, dataURL: action.payload.value } : item)),
      };
    case 'GALLERY_SET_ITEM_TITLE':
      return {
        ...state,
        items: state.items.map(item => (item.id === action.payload.id ? { ...item, title: action.payload.value } : item)),
      };
    case 'GALLERY_SET_ITEM_DESCRIPTION':
      return {
        ...state,
        items: state.items.map(item => (item.id === action.payload.id ? { ...item, description: action.payload.value } : item)),
      };
    case 'GALLERY_SET_ITEM_TAKEN_AT':
      return {
        ...state,
        items: state.items.map(item => (item.id === action.payload.id ? { ...item, takenAt: action.payload.value } : item)),
      };
    case 'GALLERY_SET_ITEM_TAGS':
      return {
        ...state,
        items: state.items.map(item => (item.id === action.payload.id ? { ...item, tags: action.payload.value } : item)),
      };
    case 'GALLERY_SET_ITEM_ERROR':
      return {
        ...state,
        items: state.items.map(item => (item.id === action.payload.id ? { ...item, error: action.payload.value } : item)),
      };
    case 'GALLERY_SET_PICKING_POSITION':
      return {
        ...state,
        pickingPosition: action.payload,
      };
    case 'GALLERY_CONFIRM_PICKED_POSITION':
      return {
        ...state,
        pickingPositionForId: null,
        pickingPosition: null,
        items: state.items.map(item => (item.id === state.pickingPositionForId ? { ...item, position: state.pickingPosition } : item)),
      };
    case 'GALLERY_SET_ITEM_FOR_POSITION_PICKING':
      return {
        ...state,
        pickingPositionForId: action.payload,
        pickingPosition: typeof action.payload === 'number' ? state.items.find(({ id }) => id === action.payload).position : null,
      };
    case 'GALLERY_UPLOAD':
    {
      const items = state.uploadingId === null ? state.items.map(item => ({ ...item, error: getError(item) })) : state.items;
      const next = items.find(item => !item.error);

      return {
        ...state,
        items,
        uploadingId: next ? next.id : null,
      };
    }
    case 'GALLERY_SET_TAGS':
      return { ...state, tags: action.payload };
    default:
      return state;
  }
}

function getError(item) {
  const errors = [];
  if (!item.position) {
    errors.push('Chýba pozícia.');
  }
  if (item.takenAt && isNaN(item.takenAt)) {
    errors.push('Nevalidný dátum a čas fotenia.');
  }
  return errors.length ? errors.join('\n') : null;
}
<|endoftext|>


<commit_before>/**
 * Created by ksinger on 24.08.2015.
 */
import angular from "angular";
import ngAnimate from "angular-animate";

import "ng-redux";
import labelledHrModule from "./labelled-hr.js";
import createIsseeksModule from "./create-isseeks.js";
import publishButtonModule from "./publish-button.js";
import { get, attach, delay, getIn } from "../utils.js";
import { actionCreators } from "../actions/actions.js";
import { connect2Redux, findUseCaseByNeed } from "../won-utils.js";
import * as generalSelectors from "../selectors/general-selectors.js";
import * as needUtils from "../need-utils.js";
import * as processSelectors from "../selectors/process-selectors.js";

import { useCases } from "useCaseDefinitions";

import "style/_create-post.scss";
import "style/_responsiveness-utils.scss";
import { values } from "min-dash";

const serviceDependencies = [
  "$ngRedux",
  "$scope",
  "$element" /*'$routeParams' /*injections as strings here*/,
];

function genComponentConf() {
  const template = `

                <svg style="--local-primary:var(--won-primary-color);"
                    class="cp__header__back__icon show-in-responsive">
                    <use xlink:href="#ico36_backarrow" href="#ico36_backarrow"></use>
                </svg>
                <svg style="--local-primary:var(--won-primary-color);"
                    class="cp__header__back__icon hide-in-responsive">
                    <use xlink:href="#ico36_close" href="#ico36_close"></use>
                </svg>

            <svg class="cp__header__icon"
                title="{{self.useCase['label']}}"
                ng-if="self.useCase['icon']"
                style="--local-primary:var(--won-primary-color);">
                    <use xlink:href="{{self.useCase['icon']}}" href="{{self.useCase['icon']}}"></use>
            </svg>
            {{self.useCase.label}}
            Duplicate from '{{self.useCase.label}}'

                <svg class="cp__content__loading__spinner hspinner">
                    <use xlink:href="#ico_loading_anim" href="#ico_loading_anim"></use>
                </svg>

                    Loading...

                <svg class="cp__content__failed__icon">
                    <use xlink:href="#ico16_indicator_error" href="#ico16_indicator_error"></use>
                </svg>

                    Failed To Load - Need might have been deleted

                    <button class="cp__content__failed__actions__button red won-button--outlined thin"
                        ng-click="self.needs__fetchUnloadedNeed(self.fromNeedUri)()">
                        Try Reload
                    </button>

              Your offer or self description

            <won-create-isseeks
                ng-if="self.showCreateInput && self.useCase.details"
                is-or-seeks="::'Description'"
                detail-list="self.useCase.details"
                initial-draft="self.useCase.draft.content"
                on-update="::self.updateDraft(draft, 'content')"
                on-scroll="::self.scrollIntoView(element)">
            </won-create-isseeks>

              Looking For

            <won-create-isseeks
                ng-if="self.showCreateInput && self.useCase.seeksDetails"
                is-or-seeks="::'Search'"
                detail-list="self.useCase.seeksDetails"
                initial-draft="self.useCase.draft.seeks"
                on-update="::self.updateDraft(draft, 'seeks')"
                on-scroll="::self.scrollIntoView(element)">
            </won-create-isseeks>

            <won-labelled-hr label="::'done?'" class="cp__footer__labelledhr"></won-labelled-hr>
            <won-publish-button on-publish="self.publish(persona)" is-valid="self.isValid()" show-personas="self.isHoldable" ng-if="self.showCreateInput"></won-publish-button>

    `;

  class Controller {
    constructor(/* arguments <- serviceDependencies */) {
      attach(this, serviceDependencies, arguments);
      this.focusedElement = null;
      window.cnc4dbg = this;

      this.windowHeight = window.screen.height;
      this.scrollContainer().addEventListener("scroll", e => this.onResize(e));

      this.draftObject = {};

      this.details = { is: [], seeks: [] };
      this.isNew = true;

      const selectFromState = state => {
        const fromNeedUri = generalSelectors.getFromNeedUriFromRoute(state);
        const mode = generalSelectors.getModeFromRoute(state);
        let fromNeed;

        let useCaseString;
        let useCase;

        const isCreateFromNeed = !!(fromNeedUri && mode === "DUPLICATE");

        let isFromNeedLoading = false;
        let isFromNeedToLoad = false;
        let hasFromNeedFailedToLoad = false;

        if (isCreateFromNeed) {
          isFromNeedLoading = processSelectors.isNeedLoading(
            state,
            fromNeedUri
          );
          isFromNeedToLoad = processSelectors.isNeedToLoad(state, fromNeedUri);
          hasFromNeedFailedToLoad = processSelectors.hasNeedFailedToLoad(
            state,
            fromNeedUri
          );
          fromNeed =
            !isFromNeedLoading &&
            !isFromNeedToLoad &&
            !hasFromNeedFailedToLoad &&
            getIn(state, ["needs", fromNeedUri]);

          if (fromNeed) {
            const matchingUseCase = findUseCaseByNeed(fromNeed);

            useCaseString = matchingUseCase
              ? matchingUseCase["identifier"]
              : "customUseCase";
            useCase = matchingUseCase
              ? matchingUseCase
              : selectUseCaseFrom(useCaseString, useCases);

            const fromNeedContent = get(fromNeed, "content");
            const fromNeedSeeks = get(fromNeed, "seeks");
            const facetsReset = needUtils.getFacetsWithKeysReset(fromNeed);
            const defaultFacetReset = needUtils.getDefaultFacetWithKeyReset(
              fromNeed
            );
            const seeksFacetsReset = needUtils.getSeeksFacetsWithKeysReset(
              fromNeed
            );
            const seeksDefaultFacetReset = needUtils.getSeeksDefaultFacetWithKeyReset(
              fromNeed
            );

            if (fromNeedContent) {
              useCase.draft.content = fromNeedContent.toJS();
            }
            if (fromNeedSeeks) {
              useCase.draft.seeks = fromNeedSeeks.toJS();
            }

            if (facetsReset) {
              useCase.draft.content.facets = facetsReset.toJS();
            }
            if (defaultFacetReset) {
              useCase.draft.content.defaultFacet = defaultFacetReset.toJS();
            }

            if (seeksFacetsReset) {
              useCase.draft.seeks.facets = seeksFacetsReset.toJS();
            }
            if (seeksDefaultFacetReset) {
              useCase.draft.seeks.defaultFacet = seeksDefaultFacetReset.toJS();
            }
          }
        } else {
          useCaseString = generalSelectors.getUseCaseFromRoute(state);
          useCase = selectUseCaseFrom(useCaseString, useCases);
        }

        return {
          processingPublish: state.getIn(["process", "processingPublish"]),
          connectionHasBeenLost: !generalSelectors.selectIsConnected(state),
          useCaseString,
          useCase,
          fromNeed,
          fromNeedUri,
          isCreateFromNeed,
          isFromNeedLoading,
          isFromNeedToLoad,
          isHoldable:
            useCase &&
            useCase.draft &&
            useCase.draft.content &&
            useCase.draft.content.facets &&
            values(useCase.draft.content.facets).includes("won:HoldableFacet"),
          hasFromNeedFailedToLoad,
          showCreateInput:
            useCase &&
            !(
              isCreateFromNeed &&
              (isFromNeedLoading || hasFromNeedFailedToLoad || isFromNeedToLoad)
            ),
        };
      };
      // Using actionCreators like this means that every action defined there is available in the template.
      connect2Redux(selectFromState, actionCreators, [], this);

      this.$scope.$watch(
        () => this.isFromNeedToLoad,
        () => delay(0).then(() => this.ensureFromNeedIsLoaded())
      );

      this.$scope.$watch(
        () => this.showCreateInput,
        () => delay(0).then(() => this.loadInitialDraft())
      );
    }

    ensureFromNeedIsLoaded() {
      if (this.isFromNeedToLoad) {
        this.needs__fetchUnloadedNeed(this.fromNeedUri);
      }
    }

    onResize() {
      if (this.focusedElement) {
        if (this.windowHeight < window.screen.height) {
          this.windowHeight < window.screen.height;
          this.scrollIntoView(document.querySelector(this.focusedElement));
        } else {
          this.windowHeight = window.screen.height;
        }
      }
    }

    scrollIntoView(element) {
      this._programmaticallyScrolling = true;

      if (element) {
        element.scrollIntoView({ behavior: "smooth", block: "nearest" });
      }
    }

    scrollContainer() {
      if (!this._scrollContainer) {
        this._scrollContainer = this.$element[0].querySelector(".cp__content");
      }
      return this._scrollContainer;
    }

    toggleTuningOptions() {}

    isValid() {
      const draft = this.draftObject;
      const draftContent = get(draft, "content");
      const seeksBranch = get(draft, "seeks");

      if (draftContent || seeksBranch) {
        const mandatoryContentDetailsSet = mandatoryDetailsSet(
          draftContent,
          this.useCase.details
        );
        const mandatorySeeksDetailsSet = mandatoryDetailsSet(
          seeksBranch,
          this.useCase.seeksDetails
        );
        if (mandatoryContentDetailsSet && mandatorySeeksDetailsSet) {
          const hasContent = isBranchContentPresent(draftContent);
          const hasSeeksContent = isBranchContentPresent(seeksBranch);

          return !this.connectionHasBeenLost && (hasContent || hasSeeksContent);
        }
      }
      return false;
    }

    loadInitialDraft() {
      if (this.showCreateInput && this.useCase.draft) {
        // deep clone of draft
        this.draftObject = JSON.parse(JSON.stringify(this.useCase.draft));
      }
    }

    updateDraft(updatedDraft, branch) {
      if (this.isNew) {
        this.isNew = false;
      }

      this.draftObject[branch] = updatedDraft;
    }

    publish(persona) {
      if (!this.processingPublish) {
        this.draftObject.useCase = get(this.useCase, "identifier");

        if (!isBranchContentPresent(this.draftObject.content)) {
          delete this.draftObject.content;
        }
        if (!isBranchContentPresent(this.draftObject.seeks, true)) {
          delete this.draftObject.seeks;
        }

        this.needs__create(
          this.draftObject,
          persona,
          this.$ngRedux.getState().getIn(["config", "defaultNodeUri"])
        );
      }
    }
  }

  Controller.$inject = serviceDependencies;

  return {
    restrict: "E",
    controller: Controller,
    controllerAs: "self",
    bindToController: true, //scope-bindings -> ctrl
    scope: {
      /*scope-isolation*/
    },
    template: template,
  };
}

function selectUseCaseFrom(useCaseString, useCases) {
  if (useCaseString) {
    for (const useCaseName in useCases) {
      if (useCaseString === useCases[useCaseName]["identifier"]) {
        return useCases[useCaseName];
      }
    }
  }
  return undefined;
}

// returns true if the branch has any content present
function isBranchContentPresent(isOrSeeks, includeType = false) {
  if (isOrSeeks) {
    const details = Object.keys(isOrSeeks);
    for (let d of details) {
      if (isOrSeeks[d] && (includeType || d !== "type")) {
        return true;
      }
    }
  }
  return false;
}
// returns true if the part in isOrSeeks, has all the mandatory details of the useCaseBranchDetails
function mandatoryDetailsSet(isOrSeeks, useCaseBranchDetails) {
  if (!useCaseBranchDetails) {
    return true;
  }

  for (const key in useCaseBranchDetails) {
    if (useCaseBranchDetails[key].mandatory) {
      const detailSaved = isOrSeeks && isOrSeeks[key];
      if (!detailSaved) {
        return false;
      }
    }
  }
  return true;
}

export default //.controller('CreateNeedController', [...serviceDependencies, CreateNeedController])
angular
  .module("won.owner.components.createPost", [
    labelledHrModule,
    createIsseeksModule,
    ngAnimate,
    publishButtonModule,
  ])
  .directive("wonCreatePost", genComponentConf).name;
<commit_msg>Invoke digest to display the draft<commit_after>/**
 * Created by ksinger on 24.08.2015.
 */
import angular from "angular";
import ngAnimate from "angular-animate";

import "ng-redux";
import labelledHrModule from "./labelled-hr.js";
import createIsseeksModule from "./create-isseeks.js";
import publishButtonModule from "./publish-button.js";
import { get, attach, delay, getIn } from "../utils.js";
import { actionCreators } from "../actions/actions.js";
import { connect2Redux, findUseCaseByNeed } from "../won-utils.js";
import * as generalSelectors from "../selectors/general-selectors.js";
import * as needUtils from "../need-utils.js";
import * as processSelectors from "../selectors/process-selectors.js";

import { useCases } from "useCaseDefinitions";

import "style/_create-post.scss";
import "style/_responsiveness-utils.scss";
import { values } from "min-dash";

const serviceDependencies = [
  "$ngRedux",
  "$scope",
  "$element" /*'$routeParams' /*injections as strings here*/,
];

function genComponentConf() {
  const template = `

                <svg style="--local-primary:var(--won-primary-color);"
                    class="cp__header__back__icon show-in-responsive">
                    <use xlink:href="#ico36_backarrow" href="#ico36_backarrow"></use>
                </svg>
                <svg style="--local-primary:var(--won-primary-color);"
                    class="cp__header__back__icon hide-in-responsive">
                    <use xlink:href="#ico36_close" href="#ico36_close"></use>
                </svg>

            <svg class="cp__header__icon"
                title="{{self.useCase['label']}}"
                ng-if="self.useCase['icon']"
                style="--local-primary:var(--won-primary-color);">
                    <use xlink:href="{{self.useCase['icon']}}" href="{{self.useCase['icon']}}"></use>
            </svg>
            {{self.useCase.label}}
            Duplicate from '{{self.useCase.label}}'

                <svg class="cp__content__loading__spinner hspinner">
                    <use xlink:href="#ico_loading_anim" href="#ico_loading_anim"></use>
                </svg>

                    Loading...

                <svg class="cp__content__failed__icon">
                    <use xlink:href="#ico16_indicator_error" href="#ico16_indicator_error"></use>
                </svg>

                    Failed To Load - Need might have been deleted

                    <button class="cp__content__failed__actions__button red won-button--outlined thin"
                        ng-click="self.needs__fetchUnloadedNeed(self.fromNeedUri)()">
                        Try Reload
                    </button>

              Your offer or self description

            <won-create-isseeks
                ng-if="self.showCreateInput && self.useCase.details"
                is-or-seeks="::'Description'"
                detail-list="self.useCase.details"
                initial-draft="self.useCase.draft.content"
                on-update="::self.updateDraft(draft, 'content')"
                on-scroll="::self.scrollIntoView(element)">
            </won-create-isseeks>

              Looking For

            <won-create-isseeks
                ng-if="self.showCreateInput && self.useCase.seeksDetails"
                is-or-seeks="::'Search'"
                detail-list="self.useCase.seeksDetails"
                initial-draft="self.useCase.draft.seeks"
                on-update="::self.updateDraft(draft, 'seeks')"
                on-scroll="::self.scrollIntoView(element)">
            </won-create-isseeks>

            <won-labelled-hr label="::'done?'" class="cp__footer__labelledhr"></won-labelled-hr>
            <won-publish-button on-publish="self.publish(persona)" is-valid="self.isValid()" show-personas="self.isHoldable" ng-if="self.showCreateInput"></won-publish-button>

    `;

  class Controller {
    constructor(/* arguments <- serviceDependencies */) {
      attach(this, serviceDependencies, arguments);
      this.focusedElement = null;
      window.cnc4dbg = this;

      this.windowHeight = window.screen.height;
      this.scrollContainer().addEventListener("scroll", e => this.onResize(e));

      this.draftObject = {};

      this.details = { is: [], seeks: [] };
      this.isNew = true;

      const selectFromState = state => {
        const fromNeedUri = generalSelectors.getFromNeedUriFromRoute(state);
        const mode = generalSelectors.getModeFromRoute(state);
        let fromNeed;

        let useCaseString;
        let useCase;

        const isCreateFromNeed = !!(fromNeedUri && mode === "DUPLICATE");

        let isFromNeedLoading = false;
        let isFromNeedToLoad = false;
        let hasFromNeedFailedToLoad = false;

        if (isCreateFromNeed) {
          isFromNeedLoading = processSelectors.isNeedLoading(
            state,
            fromNeedUri
          );
          isFromNeedToLoad = processSelectors.isNeedToLoad(state, fromNeedUri);
          hasFromNeedFailedToLoad = processSelectors.hasNeedFailedToLoad(
            state,
            fromNeedUri
          );
          fromNeed =
            !isFromNeedLoading &&
            !isFromNeedToLoad &&
            !hasFromNeedFailedToLoad &&
            getIn(state, ["needs", fromNeedUri]);

          if (fromNeed) {
            const matchingUseCase = findUseCaseByNeed(fromNeed);

            useCaseString = matchingUseCase
              ? matchingUseCase["identifier"]
              : "customUseCase";
            useCase = matchingUseCase
              ? matchingUseCase
              : selectUseCaseFrom(useCaseString, useCases);

            const fromNeedContent = get(fromNeed, "content");
            const fromNeedSeeks = get(fromNeed, "seeks");
            const facetsReset = needUtils.getFacetsWithKeysReset(fromNeed);
            const defaultFacetReset = needUtils.getDefaultFacetWithKeyReset(
              fromNeed
            );
            const seeksFacetsReset = needUtils.getSeeksFacetsWithKeysReset(
              fromNeed
            );
            const seeksDefaultFacetReset = needUtils.getSeeksDefaultFacetWithKeyReset(
              fromNeed
            );

            if (fromNeedContent) {
              useCase.draft.content = fromNeedContent.toJS();
            }
            if (fromNeedSeeks) {
              useCase.draft.seeks = fromNeedSeeks.toJS();
            }

            if (facetsReset) {
              useCase.draft.content.facets = facetsReset.toJS();
            }
            if (defaultFacetReset) {
              useCase.draft.content.defaultFacet = defaultFacetReset.toJS();
            }

            if (seeksFacetsReset) {
              useCase.draft.seeks.facets = seeksFacetsReset.toJS();
            }
            if (seeksDefaultFacetReset) {
              useCase.draft.seeks.defaultFacet = seeksDefaultFacetReset.toJS();
            }
          }
        } else {
          useCaseString = generalSelectors.getUseCaseFromRoute(state);
          useCase = selectUseCaseFrom(useCaseString, useCases);
        }

        return {
          processingPublish: state.getIn(["process", "processingPublish"]),
          connectionHasBeenLost: !generalSelectors.selectIsConnected(state),
          useCaseString,
          useCase,
          fromNeed,
          fromNeedUri,
          isCreateFromNeed,
          isFromNeedLoading,
          isFromNeedToLoad,
          isHoldable:
            useCase &&
            useCase.draft &&
            useCase.draft.content &&
            useCase.draft.content.facets &&
            values(useCase.draft.content.facets).includes("won:HoldableFacet"),
          hasFromNeedFailedToLoad,
          showCreateInput:
            useCase &&
            !(
              isCreateFromNeed &&
              (isFromNeedLoading || hasFromNeedFailedToLoad || isFromNeedToLoad)
            ),
        };
      };
      // Using actionCreators like this means that every action defined there is available in the template.
      connect2Redux(selectFromState, actionCreators, [], this);

      this.$scope.$watch(
        () => this.isFromNeedToLoad,
        () => delay(0).then(() => this.ensureFromNeedIsLoaded())
      );

      this.$scope.$watch(
        () => this.showCreateInput,
        () => delay(0).then(() => this.loadInitialDraft())
      );
    }

    ensureFromNeedIsLoaded() {
      if (this.isFromNeedToLoad) {
        this.needs__fetchUnloadedNeed(this.fromNeedUri);
      }
    }

    onResize() {
      if (this.focusedElement) {
        if (this.windowHeight < window.screen.height) {
          this.windowHeight < window.screen.height;
          this.scrollIntoView(document.querySelector(this.focusedElement));
        } else {
          this.windowHeight = window.screen.height;
        }
      }
    }

    scrollIntoView(element) {
      this._programmaticallyScrolling = true;

      if (element) {
        element.scrollIntoView({ behavior: "smooth", block: "nearest" });
      }
    }

    scrollContainer() {
      if (!this._scrollContainer) {
        this._scrollContainer = this.$element[0].querySelector(".cp__content");
      }
      return this._scrollContainer;
    }

    toggleTuningOptions() {}

    isValid() {
      const draft = this.draftObject;
      const draftContent = get(draft, "content");
      const seeksBranch = get(draft, "seeks");

      if (draftContent || seeksBranch) {
        const mandatoryContentDetailsSet = mandatoryDetailsSet(
          draftContent,
          this.useCase.details
        );
        const mandatorySeeksDetailsSet = mandatoryDetailsSet(
          seeksBranch,
          this.useCase.seeksDetails
        );
        if (mandatoryContentDetailsSet && mandatorySeeksDetailsSet) {
          const hasContent = isBranchContentPresent(draftContent);
          const hasSeeksContent = isBranchContentPresent(seeksBranch);

          return !this.connectionHasBeenLost && (hasContent || hasSeeksContent);
        }
      }
      return false;
    }

    loadInitialDraft() {
      if (this.showCreateInput && this.useCase.draft) {
        // deep clone of draft
        this.draftObject = JSON.parse(JSON.stringify(this.useCase.draft));
        this.$scope.$digest();
      }
    }

    updateDraft(updatedDraft, branch) {
      if (this.isNew) {
        this.isNew = false;
      }

      this.draftObject[branch] = updatedDraft;
    }

    publish(persona) {
      if (!this.processingPublish) {
        this.draftObject.useCase = get(this.useCase, "identifier");

        if (!isBranchContentPresent(this.draftObject.content)) {
          delete this.draftObject.content;
        }
        if (!isBranchContentPresent(this.draftObject.seeks, true)) {
          delete this.draftObject.seeks;
        }

        this.needs__create(
          this.draftObject,
          persona,
          this.$ngRedux.getState().getIn(["config", "defaultNodeUri"])
        );
      }
    }
  }

  Controller.$inject = serviceDependencies;

  return {
    restrict: "E",
    controller: Controller,
    controllerAs: "self",
    bindToController: true, //scope-bindings -> ctrl
    scope: {
      /*scope-isolation*/
    },
    template: template,
  };
}

function selectUseCaseFrom(useCaseString, useCases) {
  if (useCaseString) {
    for (const useCaseName in useCases) {
      if (useCaseString === useCases[useCaseName]["identifier"]) {
        return useCases[useCaseName];
      }
    }
  }
  return undefined;
}

// returns true if the branch has any content present
function isBranchContentPresent(isOrSeeks, includeType = false) {
  if (isOrSeeks) {
    const details = Object.keys(isOrSeeks);
    for (let d of details) {
      if (isOrSeeks[d] && (includeType || d !== "type")) {
        return true;
      }
    }
  }
  return false;
}
// returns true if the part in isOrSeeks, has all the mandatory details of the useCaseBranchDetails
function mandatoryDetailsSet(isOrSeeks, useCaseBranchDetails) {
  if (!useCaseBranchDetails) {
    return true;
  }

  for (const key in useCaseBranchDetails) {
    if (useCaseBranchDetails[key].mandatory) {
      const detailSaved = isOrSeeks && isOrSeeks[key];
      if (!detailSaved) {
        return false;
      }
    }
  }
  return true;
}

export default //.controller('CreateNeedController', [...serviceDependencies, CreateNeedController])
angular
  .module("won.owner.components.createPost", [
    labelledHrModule,
    createIsseeksModule,
    ngAnimate,
    publishButtonModule,
  ])
  .directive("wonCreatePost", genComponentConf).name;
<|endoftext|>


<commit_before>import { createAction, handleActions } from 'redux-actions'
// import createReducer from 'utils/createReducer'
import Firebase from 'firebase'
import constants from 'utils/constants'

const ref = new Firebase(constants.FIREBASE + '/quotes')
let quotes = 'yo'

ref.on('value', function (snapshot) {
  quotes = snapshot.val()
}, function (errorObject) {
  console.log('The read failed: ' + errorObject.code)
})

// ------------------------------------
// Constants
// ------------------------------------
const GETQUOTES = 'GETQUOTES'

// ------------------------------------
// Actions
// ------------------------------------
export const getQuotes = createAction(GETQUOTES, (value = quotes) => value)
export const actions = {
  getQuotes
}

// ------------------------------------
// Reducer
// ------------------------------------
// export default createReducer({}, {
//   [LOGIN]: (state) => authData
// })
//

// ------------------------------------
// Reducer
// ------------------------------------
export default handleActions({
  [GETQUOTES]: (state, { payload }) => state + payload
}, quotes)
<commit_msg>feat (getting list async)<commit_after>import { createAction, handleActions } from 'redux-actions'
// import createReducer from 'utils/createReducer'
import Firebase from 'firebase'
import constants from 'utils/constants'

const ref = new Firebase(constants.FIREBASE + '/quotes')
let quotes = ref.on('value', function (snapshot) {
  return snapshot.val()
  console.log(quotes)
}, function (errorObject) {
  console.log('The read failed: ' + errorObject.code)
})

// ------------------------------------
// Constants
// ------------------------------------
const GET_QUOTES = 'GET_QUOTES'
const FETCH_QUOTES = 'FETCH_QUOTES'
const FETCH_STARTED = 'FETCH_STARTED'

// ------------------------------------
// Actions
// ------------------------------------
export const fetch = () => {
    return (dispatch) => {
      ref.on('value', snapshot => dispatch({
        type: GET_QUOTES,
        payload: dataFromSnapshot(snapshot)
      }))
    }
  }

export const getQuotes = () => {
  return (dispatch) => {
    dispatch({ type: FETCH_STARTED })
    dispatch(fetch())
  }
}

function dataFromSnapshot(snapshot) {
  let data = snapshot.val()
  return data
}

export const actions = {
  fetch,
  getQuotes
}

// ------------------------------------
// Reducer
// ------------------------------------
// export default createReducer({}, {
//   [LOGIN]: (state) => authData
// })
//

// ------------------------------------
// Reducer
// ------------------------------------
export default handleActions({
  [GET_QUOTES]: (state, { payload }) => state + payload
}, quotes)
<|endoftext|>


<commit_before>'use strict';

module.exports = {
	isNull : function (obj) {
		return (typeof obj === 'null' ? true : false);
	},
	isUndefined : function (obj) {
		return (typeof obj === 'undefined' ? true : false);
	}
};<commit_msg>Modified the TestUtility utility.<commit_after>/**
 * @name TestUtility
 * @desc TestUtility utility
 */

'use strict';

var TestUtility = function () {

  return(function () {

    return {

      isNull : function (obj) {
        return (typeof obj === 'null' ? true : false);
      },

      isUndefined : function (obj) {
        return (typeof obj === 'undefined' ? true : false);
      }

    }

  })();

};

module.exports = TestUtility;<|endoftext|>


<commit_before>import React, { Component } from 'react';
import { Row, Icon, Text } from '@tlon/indigo-react';
import defaultApps from '~/logic/lib/default-apps';
import Sigil from '~/logic/lib/sigil';

export class OmniboxResult extends Component {
  constructor(props) {
    super(props);
    this.state = {
      isSelected: false,
      hovered: false
    };
    this.setHover = this.setHover.bind(this);
    this.result = React.createRef();
  }

  componentDidUpdate(prevProps) {
    const { props, state } = this;
    if (prevProps &&
      !state.hovered &&
      prevProps.selected !== props.selected &&
      props.selected === props.link
      ) {
        this.result.current.scrollIntoView({ block: 'nearest' });
      }
  }

  getIcon(icon, dark, selected, link) {
    const iconFill = (this.state.hovered || (selected === link)) ? 'white' : 'black';
    const sigilFill = (this.state.hovered || (selected === link)) ? '#3a8ff7' : '#ffffff';

    let graphic = <div />;
    if (defaultApps.includes(icon.toLowerCase()) || icon.toLowerCase() === 'links') {
      icon = (icon === 'Dojo') ? 'ChevronEast' : icon;
      icon = (icon === 'Link') ? 'Links' : icon;
      graphic = <Icon display="inline-block" verticalAlign="middle" icon={icon} mr='2' size='16px' color={iconFill} />;
    } else if (icon === 'logout') {
      graphic = <Icon display="inline-block" verticalAlign="middle" icon='ArrowWest' mr='2' size='16px' color={iconFill} />;
    } else if (icon === 'profile') {
      graphic = <Sigil color={sigilFill} classes='dib v-mid mr2' ship={window.ship} size={16} />;
    } else {
      graphic = <Icon verticalAlign="middle" mr='2' size="16px" color={iconFill} />;
    }

    return graphic;
  }

  setHover(boolean) {
    this.setState({ hovered: boolean });
  }

  render() {
    const { icon, text, subtext, link, navigate, selected, dark } = this.props;

    const graphic = this.getIcon(icon, dark, selected, link);

    return (
      <Row
      py='2'
      px='2'
      cursor='pointer'
      onMouseEnter={() => this.setHover(true)}
      onMouseLeave={() => this.setHover(false)}
      backgroundColor={
        this.state.hovered || selected === link ? 'blue' : 'white'
      }
      onClick={navigate}
      width="100%"
      ref={this.result}
      >
        {graphic}
        <Text
        display="inline-block"
        verticalAlign="middle"
        color={this.state.hovered || selected === link ? 'white' : 'black'}
        maxWidth="60%"
        style={{ flexShrink: 0 }}
        mr='1'
        >
          {text}
        </Text>
        <Text pr='2'
        display="inline-block"
        verticalAlign="middle"
        color={this.state.hovered || selected === link ? 'white' : 'black'}
        width='100%'
        textAlign='right'
        >
          {subtext}
        </Text>
      </Row>
    );
  }
}

export default OmniboxResult;
<commit_msg>leap: address #3613 feedback<commit_after>import React, { Component } from 'react';
import { Row, Icon, Text } from '@tlon/indigo-react';
import defaultApps from '~/logic/lib/default-apps';
import Sigil from '~/logic/lib/sigil';

export class OmniboxResult extends Component {
  constructor(props) {
    super(props);
    this.state = {
      isSelected: false,
      hovered: false
    };
    this.setHover = this.setHover.bind(this);
    this.result = React.createRef();
  }

  componentDidUpdate(prevProps) {
    const { props, state } = this;
    if (prevProps &&
      !state.hovered &&
      prevProps.selected !== props.selected &&
      props.selected === props.link
      ) {
        this.result.current.scrollIntoView({ block: 'nearest' });
      }
  }

  getIcon(icon, dark, selected, link) {
    const iconFill = (this.state.hovered || (selected === link)) ? 'white' : 'black';
    const sigilFill = (this.state.hovered || (selected === link)) ? '#3a8ff7' : '#ffffff';

    let graphic = <div />;
    if (defaultApps.includes(icon.toLowerCase()) || icon.toLowerCase() === 'links') {
      icon = (icon === 'Dojo') ? 'ChevronEast' : icon;
      icon = (icon === 'Link') ? 'Links' : icon;
      graphic = <Icon display="inline-block" verticalAlign="middle" icon={icon} mr='2' size='16px' color='transparent' stroke={iconFill} />;
    } else if (icon === 'logout') {
      graphic = <Icon display="inline-block" verticalAlign="middle" icon='ArrowWest' mr='2' size='16px' color={iconFill} />;
    } else if (icon === 'profile') {
      graphic = <Sigil color={sigilFill} classes='dib v-mid mr2' ship={window.ship} size={16} />;
    } else {
      graphic = <Icon verticalAlign="middle" mr='2' size="16px" color={iconFill} />;
    }

    return graphic;
  }

  setHover(boolean) {
    this.setState({ hovered: boolean });
  }

  render() {
    const { icon, text, subtext, link, navigate, selected, dark } = this.props;

    const graphic = this.getIcon(icon, dark, selected, link);

    return (
      <Row
      py='2'
      px='2'
      cursor='pointer'
      onMouseEnter={() => this.setHover(true)}
      onMouseLeave={() => this.setHover(false)}
      backgroundColor={
        this.state.hovered || selected === link ? 'blue' : 'white'
      }
      onClick={navigate}
      width="100%"
      ref={this.result}
      >
        {graphic}
        <Text
        display="inline-block"
        verticalAlign="middle"
        color={this.state.hovered || selected === link ? 'white' : 'black'}
        maxWidth="60%"
        style={{ flexShrink: 0 }}
        mr='1'
        >
          {text}
        </Text>
        <Text pr='2'
        display="inline-block"
        verticalAlign="middle"
        color={this.state.hovered || selected === link ? 'white' : 'black'}
        width='100%'
        textAlign='right'
        >
          {subtext}
        </Text>
      </Row>
    );
  }
}

export default OmniboxResult;
<|endoftext|>


<commit_before>'use strict';

angular.module('myApp.scannerService', ['fsCordova'])
    .factory('Scanner', ['CordovaService',
        function (CordovaService) {
          return {
            scan: function() {

              return CordovaService.ready.then(function() {

                var scanner = cordova.require("cordova/plugin/BarcodeScanner");

                scanner.scan( function (result) {

                   console.log("Scanner result: \n" +
                        "text: " + result.text + "\n" +
                        "format: " + result.format + "\n" +
                        "cancelled: " + result.cancelled + "\n");

                    if (result.cancelled) {
                        return {};
                    }

                    if (!result.text) {
                        return { error: "Can not read barcode"};
                    }

                    if (result.format != "QR_CODE") {
                        return { error: "Unknown barcode format" };
                    }

                    return { code: result.text };

                }, function (error) {
                  return { error: "Scanning failed: " + error };
                } );

              });
            }
          }
        }]);<commit_msg>Trying to fix return in scanner<commit_after>'use strict';

angular.module('myApp.scannerService', ['fsCordova'])
    .factory('Scanner', ['CordovaService',
        function (CordovaService) {
          return {
            scan: function() {

              return CordovaService.ready.then(function() {

                var scanner = cordova.require("cordova/plugin/BarcodeScanner");

                return scanner.scan( function (result) {

                   console.log("Scanner result: \n" +
                        "text: " + result.text + "\n" +
                        "format: " + result.format + "\n" +
                        "cancelled: " + result.cancelled + "\n");

                    if (result.cancelled) {
                        return {};
                    }

                    if (!result.text) {
                        return { error: "Can not read barcode"};
                    }

                    if (result.format != "QR_CODE") {
                        return { error: "Unknown barcode format" };
                    }

                    return { code: result.text };

                }, function (error) {
                  return { error: "Scanning failed: " + error };
                } );

              });
            }
          }
        }]);<|endoftext|>


<commit_before>define(function (require) {
    var defineComponent = require('flight/lib/component');
    var _ = require('lodash/lodash');

    return defineComponent(checkpoint);

    function checkpoint() {

        this.serveCheckpoints = function () {
            var self = this;
            $.ajax('/api/users/course/checkpoints', {
                method: 'get'
            }).fail(function () {
                console.log('获取checkpoint失败');
                console.log(data);

            }).done(function (data) {
                self.trigger('dataCheckpointServed', {makeup: self.renderCheckpoint(data)});
            });
        };

        this.renderCheckpoint = function (checkpoints) {
            var groupedCheckpoint = this.groupCheckpoints(checkpoints);
            var checkPointTemplate = Hogan.compile(
                '{{#groups}}' +
                '
{{groupName}}
' +
                '{{#checkpoints}}' +
                '{{#checked}}
<input id="{{_id}}" class="checkpoint-item" type="checkbox" checked="true" >{{name}}
{{/checked}}' +
                '{{^checked}}
<input id="{{_id}}" class="checkpoint-item" type="checkbox">{{name}}
{{/checked}}' +
                '{{/checkpoints}}' +
                '{{/groups}}'
            );
            return checkPointTemplate.render(
                {groups: groupedCheckpoint});
        };

        this.groupCheckpoints = function (checkpoints) {
            var groupCheckpoints = [];
            var groupNames = _.uniq(_.pluck(checkpoints, 'type'));
            _.forEach(groupNames, function (groupName) {
                groupCheckpoints.push({groupName: groupName, checkpoints: _.where(checkpoints, {type: groupName})})
            });
            return groupCheckpoints;
        };

        this.changeCheckPoint = function (event, data) {
            console.log(data);
            $.ajax('/api/users/course/checkpoints', {
                method: 'patch',
                data: data
            }).fail(function () {
                console.log('checkpoint 更新失败');
            }).done(function () {
                console.log('checkpoint 更新成功');
            });
        };

        this.after('initialize', function () {
            this.on('uiCheckpointsRequested', this.serveCheckpoints);
            this.on('uiChangeCheckedIdList', this.changeCheckPoint);
        });
    }
});
<commit_msg>disable checkbox when checkpoint disable<commit_after>define(function (require) {
    var defineComponent = require('flight/lib/component');
    var _ = require('lodash/lodash');

    return defineComponent(checkpoint);

    function checkpoint() {

        this.serveCheckpoints = function () {
            var self = this;
            $.ajax('/api/users/course/checkpoints', {
                method: 'get'
            }).fail(function () {
                console.log('获取checkpoint失败');
                console.log(data);

            }).done(function (data) {
                self.trigger('dataCheckpointServed', {makeup: self.renderCheckpoint(data)});
            });
        };

        this.renderCheckpoint = function (checkpoints) {
            var groupedCheckpoint = this.groupCheckpoints(checkpoints);
            var checkPointTemplate = Hogan.compile(
                '{{#groups}}' +
                '
{{groupName}}
' +
                '{{#checkpoints}}' +
                '{{#disable}}'+
                '{{#checked}}
<input id="{{_id}}" class="checkpoint-item" type="checkbox" checked="true" disabled="true">{{name}}
{{/checked}}' +
                '{{^checked}}
<input id="{{_id}}" class="checkpoint-item" type="checkbox" disabled="true">{{name}}
{{/checked}}' +
                '{{/disable}}'+
                '{{^disable}}'+
                '{{#checked}}
<input id="{{_id}}" class="checkpoint-item" type="checkbox" disabled="true" >{{name}}
{{/checked}}' +
                '{{^checked}}
<input id="{{_id}}" class="checkpoint-item" type="checkbox">{{name}}
{{/checked}}' +
                '{{/disable}}'+
                '{{/checkpoints}}' +
                '{{/groups}}'
            );
            return checkPointTemplate.render(
                {groups: groupedCheckpoint});
        };

        this.groupCheckpoints = function (checkpoints) {
            var groupCheckpoints = [];
            var groupNames = _.uniq(_.pluck(checkpoints, 'type'));
            _.forEach(groupNames, function (groupName) {
                groupCheckpoints.push({groupName: groupName, checkpoints: _.where(checkpoints, {type: groupName})})
            });
            return groupCheckpoints;
        };

        this.changeCheckPoint = function (event, data) {
            console.log(data);
            $.ajax('/api/users/course/checkpoints', {
                method: 'patch',
                data: data
            }).fail(function () {
                console.log('checkpoint 更新失败');
            }).done(function () {
                console.log('checkpoint 更新成功');
            });
        };

        this.after('initialize', function () {
            this.on('uiCheckpointsRequested', this.serveCheckpoints);
            this.on('uiChangeCheckedIdList', this.changeCheckPoint);
        });
    }
});
<|endoftext|>