<commit_before>// Game state.
var highScore = 0;
var points = 0;

var hardMode = true;

/** This is the state in which the game is played. */
var gameState = {
  // Custom "variables".
  tweenAPosition: 1950,
  tweenBPosition: 70,

  textTween: null,
  text: null,
	tapSound: null,

	gameobjects: null,
	backgrounds: null,
  walls: null,

  score: 0,
	tempScore: 0,

  currentHighscore: new Array(),
  currentHighscoreUsers: new Array(),
  randomNames: new Array("Bob","Achmed","Ash","John","Seymore"),

 	/** @method
	* @name preload
	* @description this is a preload function that is fired before the create function, this is where we create variables and images
	*/
  preload: function() {
  	var str_names = JSON.parse(localStorage.getItem('users'));

		if (str_names == null || str_names == "null") {

		} else {
			console.log("names ="+str_names);
			this.currentHighscoreUsers = str_names;
		}

		var str_score = JSON.parse(localStorage.getItem('highScore'));

		if (str_score == null || str_score == "null") {

		} else {
			console.log("score ="+str_score);
			this.currentHighscore = str_score;
		}

		var tapSound = localStorage.getItem('characterSound');

		if (tapSound == null || tapSound == "null") {
			tapSound = 'click2.wav';
		}

		var character = localStorage.getItem('characterImage');

		if (character == null || character == "null") {
			character = 'image.0.png';
		}
		/*
		else {
			character = parseInt(str_character);
		}
		*/

		this.gameobjects = game.add.group();
		this.backgrounds = game.add.group();
		this.walls = game.add.group();

		game.load.image('background', 'assets/background/background.0.png');
		game.load.image('ball', 'assets/balls/' + character);
		game.load.image('goal', 'assets/goal/goal.0.png');

		game.load.image('wall', 'assets/image.png');

		game.load.audio('tapSound', 'assets/audio/soundeffect/' + tapSound);
	},

	/** @method
	* @name create
	* @description this is a create function that is fired after the preload function, this is where we set all the variables
	*/
  create: function() {
		// this has to be active for the fps to be counting.
		game.time.advancedTiming = true;

		game.stage.backgroundColor = '#C85A17';
		game.physics.startSystem(Phaser.Physics.ARCADE);
		game.physics.arcade.gravity.y = 1500;

		game.world.bringToTop(this.backgrounds);
		game.world.bringToTop(this.walls);
		game.world.bringToTop(this.gameobjects);

		// sounds
		tapSound = game.add.audio('tapSound');

		// Add gameobjects to game
		this.ball = game.add.sprite(game.world.centerX, 20, 'ball');
		this.goal = game.add.sprite(this.tweenAPosition, game.world.height - 50, 'goal');

/*
		this.wall1 = game.add.sprite(-70, game.world.height, 'wall1');
		this.wall2 = game.add.sprite(game.world.width + 70, game.world.height, 'wall2');
		this.ceiling = game.add.sprite()
*/
		this.walls.create(-70, game.world.height, 'wall');
		this.walls.create(game.world.width + 70, game.world.height, 'wall');
		this.walls.create(game.world.width / 2, game.world.height + (game.world.height / 2), 'wall');

		this.background = game.add.tileSprite(0, 0, game.world.width, game.world.height, 'background');

		game.physics.arcade.enable([
			this.ball,
      this.goal,
      this.walls
      ]);

    // Background setup
    this.backgrounds.add(this.background);

		// Ball setup
		this.ball.anchor.setTo(0.5, 0.5);
		this.ball.body.bounce.setTo(0.9, 0.9);

		this.gameobjects.add(this.ball);

		// Goal setup
		this.goal.anchor.setTo(0.5, 0.5);
		this.goal.body.immovable = true;
		this.goal.body.allowGravity = false;
		this.goal.body.setSize(64, 64, 0, 0);

		this.gameobjects.add(this.goal);

		// Walls setup
		for (var i = 0; i < this.walls.children.length; i++) {
			this.walls.children[i].anchor.setTo(0.5, 1);
			this.walls.children[i].scale.setTo(0.5, game.world.height + (game.world.height / 2));
			this.walls.children[i].body.immovable = true;
			this.walls.children[i].body.allowGravity = false;
		}
		// Reset ceiling size
		this.walls.children[2].anchor.setTo(0.5);
		this.walls.children[2].scale.setTo(50, 0.5);

		// Back button.
		var escKey = game.input.keyboard.addKey(Phaser.Keyboard.Q);
		escKey.onDown.add(this.goToMain, this);

		// Ball control.
		game.input.onDown.add(this.bounce, this);

		//set the goals tweens.
		tweenA = game.add.tween(this.goal).to({ x: this.tweenAPosition }, 5000, 'Linear', true, 0);
		tweenB = game.add.tween(this.goal).to({ x: this.tweenBPosition }, 5000, 'Linear', true, 0);

		//set score text
		scoreText = game.add.text(game.world.centerX, 20, "0");

		//	Font style
		scoreText.font = 'Arial Black';
		scoreText.fontSize = 50;
		scoreText.fontWeight = 'bold';

		//	Stroke color and thickness
		scoreText.stroke = '#FFFF00';
		scoreText.strokeThickness = 3;
		scoreText.fill = '#FF2828';

		textTween = game.add.tween(scoreText).to({ fontSize:100}, 100, Phaser.Easing.Linear.None, false, 0,0,true);
  },

	/** @method
	* @name update
	* @description this is a update function that is fired after the create function,and updates every frame.
	*/
  update: function() {
		game.physics.arcade.collide(this.walls, this.ball, this.wallsCollisionHandler, null, this);
		game.physics.arcade.collide(this.goal, this.ball, this.goalCollisionHandler, null, this);

		if (this.ball.world.y >= game.world.height) {
			this.goToMain();
		}

		if(this.goal.world.x == this.tweenAPosition) {
			tweenB.start();
		} else if(this.goal.world.x == this.tweenBPosition) {
			tweenA.start();
		}
  },

	/** @method
	* @name render
	* @description this is a render function that is used for rendering debug texts
	*/
  render: function() {
    // fps log
    game.debug.text(game.time.fps, 2, 14, "#00ff00");
  },

  // Custom functions
  	/** @method
	* @name wallsCollisionHandler
	* @description this is a collision function that is fired when hitting a wall and is used for adding score for a skill shot
	*/
  wallsCollisionHandler: function() {
    this.tempScore++;
  },

 	/** @method
	* @name goalCollisionHandler
	* @description this is a collision function that is fired when the ball hits the goal and is used for adding score for a skill shot
	*/
  goalCollisionHandler: function() {
    //game.state.start('game');
    this.score += this.tempScore + 1;
    this.tempScore = 0;
    points += this.score;

    this.setScoreText();
    this.ball.body.velocity.setTo(0, 0);
    this.ball.body.angularVelocity = 0;
    this.ball.position.x = game.world.randomX;
    this.ball.position.y = 0;
  },

	/** @method
	* @name setScoreText
	* @description this is a function that is fired when the ball hits the goal and is used for updateing the score text on the UI.
	*/
  setScoreText: function() {
   scoreText.text = this.score;
   textTween.start();
  },
	/** @method
	* @name bounce
	* @description this is a function that is fired when the player taps the screen and is used for adding force to the ball.
	*/
  bounce: function() {
		var yVelocity = 0;
		this.tempScore = 0;
		tapSound.play();

		if (game.input.activePointer.y > this.ball.y) {
		  yVelocity = -800;
		} else {
			this.tempScore++;

		  yVelocity = this.ball.body.velocity.y + 800;
		}

		if (hardMode == true) {
			var xVelocity = Phaser.Math.difference(game.input.activePointer.x, this.ball.x);

			/*
			if (velocityMode == true) {
				xVelocity = 400 - Phaser.Math.difference(game.input.activePointer.x, this.ball.x);

				if (xVelocity < 0) {
				  xVelocity = 0;
				}

			} else {
			}
			*/

			this.ball.body.angularVelocity = angVelocity = this.ball.x - game.input.activePointer.x;

			if (game.input.activePointer.x > this.ball.x) {
			  this.ball.body.velocity.setTo(this.ball.body.velocity.x + -xVelocity, yVelocity);
			} else {
		  	this.ball.body.velocity.setTo(this.ball.body.velocity.x + xVelocity, yVelocity);
			}
		} else {
		  this.ball.body.velocity.setTo(this.ball.body.velocity.x, yVelocity);
		}
  },

	/** @method
	* @name goToMain
	* @description this is a function that returns the player to the main menu.
	*/
  goToMain: function() {
			if (this.score > this.currentHighscore[0] && this.score != 0 || this.score > 0 && this.currentHighscore[0] == null) {
			this.currentHighscore.push("\n" + this.score);
			this.currentHighscoreUsers.push(this.randomNames[Math.floor(Math.random() * 5)]);
			localStorage.setItem('users', JSON.stringify(this.currentHighscoreUsers));
			localStorage.setItem('highScore', JSON.stringify(this.currentHighscore));
			}
		localStorage.setItem('points', points);

		this.score = 0;
		game.state.start('mainMenu');
  },
};<commit_msg>tween position is set to world size<commit_after>// Game state.
var highScore = 0;
var points = 0;

var hardMode = true;

/** This is the state in which the game is played. */
var gameState = {
  // Custom "variables".
  tweenAPosition: 0,
  tweenBPosition: 70,

  textTween: null,
  text: null,
	tapSound: null,

	gameobjects: null,
	backgrounds: null,
  walls: null,

  score: 0,
	tempScore: 0,

  currentHighscore: new Array(),
  currentHighscoreUsers: new Array(),
  randomNames: new Array("Bob","Achmed","Ash","John","Seymore"),

 	/** @method
	* @name preload
	* @description this is a preload function that is fired before the create function, this is where we create variables and images
	*/
  preload: function() {
  	var str_names = JSON.parse(localStorage.getItem('users'));

		if (str_names == null || str_names == "null") {

		} else {
			console.log("names ="+str_names);
			this.currentHighscoreUsers = str_names;
		}

		var str_score = JSON.parse(localStorage.getItem('highScore'));

		if (str_score == null || str_score == "null") {

		} else {
			console.log("score ="+str_score);
			this.currentHighscore = str_score;
		}

		var tapSound = localStorage.getItem('characterSound');

		if (tapSound == null || tapSound == "null") {
			tapSound = 'click2.wav';
		}

		var character = localStorage.getItem('characterImage');

		if (character == null || character == "null") {
			character = 'image.0.png';
		}
		/*
		else {
			character = parseInt(str_character);
		}
		*/

		this.gameobjects = game.add.group();
		this.backgrounds = game.add.group();
		this.walls = game.add.group();

		game.load.image('background', 'assets/background/background.0.png');
		game.load.image('ball', 'assets/balls/' + character);
		game.load.image('goal', 'assets/goal/goal.0.png');

		game.load.image('wall', 'assets/image.png');

		game.load.audio('tapSound', 'assets/audio/soundeffect/' + tapSound);
	},

	/** @method
	* @name create
	* @description this is a create function that is fired after the preload function, this is where we set all the variables
	*/
  create: function() {
		// this has to be active for the fps to be counting.
		game.time.advancedTiming = true;

		game.stage.backgroundColor = '#C85A17';
		game.physics.startSystem(Phaser.Physics.ARCADE);
		game.physics.arcade.gravity.y = 1500;

		game.world.bringToTop(this.backgrounds);
		game.world.bringToTop(this.walls);
		game.world.bringToTop(this.gameobjects);

		// sounds
		tapSound = game.add.audio('tapSound');

		//set tween position
		this.tweenAPosition = game.world.width - 100;
		// Add gameobjects to game
		this.ball = game.add.sprite(game.world.centerX, 20, 'ball');
		this.goal = game.add.sprite(this.tweenAPosition, game.world.height - 50, 'goal');

/*
		this.wall1 = game.add.sprite(-70, game.world.height, 'wall1');
		this.wall2 = game.add.sprite(game.world.width + 70, game.world.height, 'wall2');
		this.ceiling = game.add.sprite()
*/
		this.walls.create(-70, game.world.height, 'wall');
		this.walls.create(game.world.width + 70, game.world.height, 'wall');
		this.walls.create(game.world.width / 2, game.world.height + (game.world.height / 2), 'wall');

		this.background = game.add.tileSprite(0, 0, game.world.width, game.world.height, 'background');

		game.physics.arcade.enable([
			this.ball,
      this.goal,
      this.walls
      ]);

    // Background setup
    this.backgrounds.add(this.background);

		// Ball setup
		this.ball.anchor.setTo(0.5, 0.5);
		this.ball.body.bounce.setTo(0.9, 0.9);

		this.gameobjects.add(this.ball);

		// Goal setup
		this.goal.anchor.setTo(0.5, 0.5);
		this.goal.body.immovable = true;
		this.goal.body.allowGravity = false;
		this.goal.body.setSize(64, 64, 0, 0);

		this.gameobjects.add(this.goal);

		// Walls setup
		for (var i = 0; i < this.walls.children.length; i++) {
			this.walls.children[i].anchor.setTo(0.5, 1);
			this.walls.children[i].scale.setTo(0.5, game.world.height + (game.world.height / 2));
			this.walls.children[i].body.immovable = true;
			this.walls.children[i].body.allowGravity = false;
		}
		// Reset ceiling size
		this.walls.children[2].anchor.setTo(0.5);
		this.walls.children[2].scale.setTo(50, 0.5);

		// Back button.
		var escKey = game.input.keyboard.addKey(Phaser.Keyboard.Q);
		escKey.onDown.add(this.goToMain, this);

		// Ball control.
		game.input.onDown.add(this.bounce, this);

		//set the goals tweens.
		tweenA = game.add.tween(this.goal).to({ x: this.tweenAPosition }, 5000, 'Linear', true, 0);
		tweenB = game.add.tween(this.goal).to({ x: this.tweenBPosition }, 5000, 'Linear', true, 0);

		//set score text
		scoreText = game.add.text(game.world.centerX, 20, "0");

		//	Font style
		scoreText.font = 'Arial Black';
		scoreText.fontSize = 50;
		scoreText.fontWeight = 'bold';

		//	Stroke color and thickness
		scoreText.stroke = '#FFFF00';
		scoreText.strokeThickness = 3;
		scoreText.fill = '#FF2828';

		textTween = game.add.tween(scoreText).to({ fontSize:100}, 100, Phaser.Easing.Linear.None, false, 0,0,true);
  },

	/** @method
	* @name update
	* @description this is a update function that is fired after the create function,and updates every frame.
	*/
  update: function() {
		game.physics.arcade.collide(this.walls, this.ball, this.wallsCollisionHandler, null, this);
		game.physics.arcade.collide(this.goal, this.ball, this.goalCollisionHandler, null, this);

		if (this.ball.world.y >= game.world.height) {
			this.goToMain();
		}

		if(this.goal.world.x == this.tweenAPosition) {
			tweenB.start();
		} else if(this.goal.world.x == this.tweenBPosition) {
			tweenA.start();
		}
  },

	/** @method
	* @name render
	* @description this is a render function that is used for rendering debug texts
	*/
  render: function() {
    // fps log
    game.debug.text(game.time.fps, 2, 14, "#00ff00");
  },

  // Custom functions
  	/** @method
	* @name wallsCollisionHandler
	* @description this is a collision function that is fired when hitting a wall and is used for adding score for a skill shot
	*/
  wallsCollisionHandler: function() {
    this.tempScore++;
  },

 	/** @method
	* @name goalCollisionHandler
	* @description this is a collision function that is fired when the ball hits the goal and is used for adding score for a skill shot
	*/
  goalCollisionHandler: function() {
    //game.state.start('game');
    this.score += this.tempScore + 1;
    this.tempScore = 0;
    points += this.score;

    this.setScoreText();
    this.ball.body.velocity.setTo(0, 0);
    this.ball.body.angularVelocity = 0;
    this.ball.position.x = game.world.randomX;
    this.ball.position.y = 0;
  },

	/** @method
	* @name setScoreText
	* @description this is a function that is fired when the ball hits the goal and is used for updateing the score text on the UI.
	*/
  setScoreText: function() {
   scoreText.text = this.score;
   textTween.start();
  },
	/** @method
	* @name bounce
	* @description this is a function that is fired when the player taps the screen and is used for adding force to the ball.
	*/
  bounce: function() {
		var yVelocity = 0;
		this.tempScore = 0;
		tapSound.play();

		if (game.input.activePointer.y > this.ball.y) {
		  yVelocity = -800;
		} else {
			this.tempScore++;

		  yVelocity = this.ball.body.velocity.y + 800;
		}

		if (hardMode == true) {
			var xVelocity = Phaser.Math.difference(game.input.activePointer.x, this.ball.x);

			/*
			if (velocityMode == true) {
				xVelocity = 400 - Phaser.Math.difference(game.input.activePointer.x, this.ball.x);

				if (xVelocity < 0) {
				  xVelocity = 0;
				}

			} else {
			}
			*/

			this.ball.body.angularVelocity = angVelocity = this.ball.x - game.input.activePointer.x;

			if (game.input.activePointer.x > this.ball.x) {
			  this.ball.body.velocity.setTo(this.ball.body.velocity.x + -xVelocity, yVelocity);
			} else {
		  	this.ball.body.velocity.setTo(this.ball.body.velocity.x + xVelocity, yVelocity);
			}
		} else {
		  this.ball.body.velocity.setTo(this.ball.body.velocity.x, yVelocity);
		}
  },

	/** @method
	* @name goToMain
	* @description this is a function that returns the player to the main menu.
	*/
  goToMain: function() {
			if (this.score > this.currentHighscore[0] && this.score != 0 || this.score > 0 && this.currentHighscore[0] == null) {
			this.currentHighscore.push("\n" + this.score);
			this.currentHighscoreUsers.push(this.randomNames[Math.floor(Math.random() * 5)]);
			localStorage.setItem('users', JSON.stringify(this.currentHighscoreUsers));
			localStorage.setItem('highScore', JSON.stringify(this.currentHighscore));
			localStorage.setItem('highestScore', this.score);
			}
		localStorage.setItem('points', points);

		this.score = 0;
		game.state.start('mainMenu');
  },
};<|endoftext|>


<commit_before>/**
 * Copyright (c) 2015-present, Facebook, Inc.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */
'use strict';

const path = require('path');

const validateBoolOption = (name, value, defaultValue) => {
  if (typeof value === 'undefined') {
    value = defaultValue;
  }

  if (typeof value !== 'boolean') {
    throw new Error(`Preset react-app: '${name}' option must be a boolean.`);
  }

  return value;
};

module.exports = function(api, opts, env) {
  if (!opts) {
    opts = {};
  }

  var isEnvDevelopment = env === 'development';
  var isEnvProduction = env === 'production';
  var isEnvTest = env === 'test';

  var useESModules = validateBoolOption(
    'useESModules',
    opts.useESModules,
    isEnvDevelopment || isEnvProduction
  );
  var isFlowEnabled = validateBoolOption('flow', opts.flow, true);
  var isTypeScriptEnabled = validateBoolOption(
    'typescript',
    opts.typescript,
    true
  );
  var areHelpersEnabled = validateBoolOption('helpers', opts.helpers, true);
  var useAbsoluteRuntime = validateBoolOption(
    'absoluteRuntime',
    opts.absoluteRuntime,
    true
  );

  var absoluteRuntimePath = undefined;
  if (useAbsoluteRuntime) {
    absoluteRuntimePath = path.dirname(
      require.resolve('@babel/runtime/package.json')
    );
  }

  if (!isEnvDevelopment && !isEnvProduction && !isEnvTest) {
    throw new Error(
      'Using `babel-preset-react-app` requires that you specify `NODE_ENV` or ' +
        '`BABEL_ENV` environment variables. Valid values are "development", ' +
        '"test", and "production". Instead, received: ' +
        JSON.stringify(env) +
        '.'
    );
  }

  return {
    presets: [
      isEnvTest && [
        // ES features necessary for user's Node version
        require('@babel/preset-env').default,
        {
          targets: {
            node: 'current',
          },
        },
      ],
      (isEnvProduction || isEnvDevelopment) && [
        // Latest stable ECMAScript features
        require('@babel/preset-env').default,
        {
          // Allow importing core-js in entrypoint and use browserlist to select polyfills
          useBuiltIns: 'entry',
          // Set the corejs version we are using to avoid warnings in console
          // This will need to change once we upgrade to corejs@3
          corejs: 3,
          // Do not transform modules to CJS
          modules: false,
          // Exclude transforms that make all code slower
          exclude: ['transform-typeof-symbol'],
        },
      ],
      [
        require('@babel/preset-react').default,
        {
          // Adds component stack to warning messages
          // Adds __self attribute to JSX which React will use for some warnings
          development: isEnvDevelopment || isEnvTest,
          // Will use the native built-in instead of trying to polyfill
          // behavior for any plugins that require one.
          useBuiltIns: true,
        },
      ],
      isTypeScriptEnabled && [require('@babel/preset-typescript').default],
    ].filter(Boolean),
    plugins: [
      // Strip flow types before any other transform, emulating the behavior
      // order as-if the browser supported all of the succeeding features
      // https://github.com/facebook/create-react-app/pull/5182
      // We will conditionally enable this plugin below in overrides as it clashes with
      // @babel/plugin-proposal-decorators when using TypeScript.
      // https://github.com/facebook/create-react-app/issues/5741
      isFlowEnabled && [
        require('@babel/plugin-transform-flow-strip-types').default,
        false,
      ],
      // Experimental macros support. Will be documented after it's had some time
      // in the wild.
      require('babel-plugin-macros'),
      // Disabled as it's handled automatically by preset-env, and `selectiveLoose` isn't
      // yet merged into babel: https://github.com/babel/babel/pull/9486
      // Related: https://github.com/facebook/create-react-app/pull/8215
      // [
      //   require('@babel/plugin-transform-destructuring').default,
      //   {
      //     // Use loose mode for performance:
      //     // https://github.com/facebook/create-react-app/issues/5602
      //     loose: false,
      //     selectiveLoose: [
      //       'useState',
      //       'useEffect',
      //       'useContext',
      //       'useReducer',
      //       'useCallback',
      //       'useMemo',
      //       'useRef',
      //       'useImperativeHandle',
      //       'useLayoutEffect',
      //       'useDebugValue',
      //     ],
      //   },
      // ],
      // Turn on legacy decorators for TypeScript files
      isTypeScriptEnabled && [
        require('@babel/plugin-proposal-decorators').default,
        false,
      ],
      // class { handleClick = () => { } }
      // Enable loose mode to use assignment instead of defineProperty
      // See discussion in https://github.com/facebook/create-react-app/issues/4263
      [
        require('@babel/plugin-proposal-class-properties').default,
        {
          loose: true,
        },
      ],
      // Adds Numeric Separators
      require('@babel/plugin-proposal-numeric-separator').default,
      // Polyfills the runtime needed for async/await, generators, and friends
      // https://babeljs.io/docs/en/babel-plugin-transform-runtime
      [
        require('@babel/plugin-transform-runtime').default,
        {
          corejs: false,
          helpers: areHelpersEnabled,
          // By default, babel assumes babel/runtime version 7.0.0-beta.0,
          // explicitly resolving to match the provided helper functions.
          // https://github.com/babel/babel/issues/10261
          version: require('@babel/runtime/package.json').version,
          regenerator: true,
          // https://babeljs.io/docs/en/babel-plugin-transform-runtime#useesmodules
          // We should turn this on once the lowest version of Node LTS
          // supports ES Modules.
          useESModules,
          // Undocumented option that lets us encapsulate our runtime, ensuring
          // the correct version is used
          // https://github.com/babel/babel/blob/090c364a90fe73d36a30707fc612ce037bdbbb24/packages/babel-plugin-transform-runtime/src/index.js#L35-L42
          absoluteRuntime: absoluteRuntimePath,
        },
      ],
      isEnvProduction && [
        // Remove PropTypes from production build
        require('babel-plugin-transform-react-remove-prop-types').default,
        {
          removeImport: true,
        },
      ],
      // Optional chaining and nullish coalescing are supported in @babel/preset-env,
      // but not yet supported in webpack due to support missing from acorn.
      // These can be removed once webpack has support.
      // See https://github.com/facebook/create-react-app/issues/8445#issuecomment-588512250
      require('@babel/plugin-proposal-optional-chaining').default,
      require('@babel/plugin-proposal-nullish-coalescing-operator').default,
    ].filter(Boolean),
    overrides: [
      isFlowEnabled && {
        exclude: /\.tsx?$/,
        plugins: [require('@babel/plugin-transform-flow-strip-types').default],
      },
      isTypeScriptEnabled && {
        test: /\.tsx?$/,
        plugins: [
          [
            require('@babel/plugin-proposal-decorators').default,
            { legacy: true },
          ],
        ],
      },
    ].filter(Boolean),
  };
};
<commit_msg>Remove outdated comment (#8858)<commit_after>/**
 * Copyright (c) 2015-present, Facebook, Inc.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */
'use strict';

const path = require('path');

const validateBoolOption = (name, value, defaultValue) => {
  if (typeof value === 'undefined') {
    value = defaultValue;
  }

  if (typeof value !== 'boolean') {
    throw new Error(`Preset react-app: '${name}' option must be a boolean.`);
  }

  return value;
};

module.exports = function(api, opts, env) {
  if (!opts) {
    opts = {};
  }

  var isEnvDevelopment = env === 'development';
  var isEnvProduction = env === 'production';
  var isEnvTest = env === 'test';

  var useESModules = validateBoolOption(
    'useESModules',
    opts.useESModules,
    isEnvDevelopment || isEnvProduction
  );
  var isFlowEnabled = validateBoolOption('flow', opts.flow, true);
  var isTypeScriptEnabled = validateBoolOption(
    'typescript',
    opts.typescript,
    true
  );
  var areHelpersEnabled = validateBoolOption('helpers', opts.helpers, true);
  var useAbsoluteRuntime = validateBoolOption(
    'absoluteRuntime',
    opts.absoluteRuntime,
    true
  );

  var absoluteRuntimePath = undefined;
  if (useAbsoluteRuntime) {
    absoluteRuntimePath = path.dirname(
      require.resolve('@babel/runtime/package.json')
    );
  }

  if (!isEnvDevelopment && !isEnvProduction && !isEnvTest) {
    throw new Error(
      'Using `babel-preset-react-app` requires that you specify `NODE_ENV` or ' +
        '`BABEL_ENV` environment variables. Valid values are "development", ' +
        '"test", and "production". Instead, received: ' +
        JSON.stringify(env) +
        '.'
    );
  }

  return {
    presets: [
      isEnvTest && [
        // ES features necessary for user's Node version
        require('@babel/preset-env').default,
        {
          targets: {
            node: 'current',
          },
        },
      ],
      (isEnvProduction || isEnvDevelopment) && [
        // Latest stable ECMAScript features
        require('@babel/preset-env').default,
        {
          // Allow importing core-js in entrypoint and use browserlist to select polyfills
          useBuiltIns: 'entry',
          // Set the corejs version we are using to avoid warnings in console
          corejs: 3,
          // Do not transform modules to CJS
          modules: false,
          // Exclude transforms that make all code slower
          exclude: ['transform-typeof-symbol'],
        },
      ],
      [
        require('@babel/preset-react').default,
        {
          // Adds component stack to warning messages
          // Adds __self attribute to JSX which React will use for some warnings
          development: isEnvDevelopment || isEnvTest,
          // Will use the native built-in instead of trying to polyfill
          // behavior for any plugins that require one.
          useBuiltIns: true,
        },
      ],
      isTypeScriptEnabled && [require('@babel/preset-typescript').default],
    ].filter(Boolean),
    plugins: [
      // Strip flow types before any other transform, emulating the behavior
      // order as-if the browser supported all of the succeeding features
      // https://github.com/facebook/create-react-app/pull/5182
      // We will conditionally enable this plugin below in overrides as it clashes with
      // @babel/plugin-proposal-decorators when using TypeScript.
      // https://github.com/facebook/create-react-app/issues/5741
      isFlowEnabled && [
        require('@babel/plugin-transform-flow-strip-types').default,
        false,
      ],
      // Experimental macros support. Will be documented after it's had some time
      // in the wild.
      require('babel-plugin-macros'),
      // Disabled as it's handled automatically by preset-env, and `selectiveLoose` isn't
      // yet merged into babel: https://github.com/babel/babel/pull/9486
      // Related: https://github.com/facebook/create-react-app/pull/8215
      // [
      //   require('@babel/plugin-transform-destructuring').default,
      //   {
      //     // Use loose mode for performance:
      //     // https://github.com/facebook/create-react-app/issues/5602
      //     loose: false,
      //     selectiveLoose: [
      //       'useState',
      //       'useEffect',
      //       'useContext',
      //       'useReducer',
      //       'useCallback',
      //       'useMemo',
      //       'useRef',
      //       'useImperativeHandle',
      //       'useLayoutEffect',
      //       'useDebugValue',
      //     ],
      //   },
      // ],
      // Turn on legacy decorators for TypeScript files
      isTypeScriptEnabled && [
        require('@babel/plugin-proposal-decorators').default,
        false,
      ],
      // class { handleClick = () => { } }
      // Enable loose mode to use assignment instead of defineProperty
      // See discussion in https://github.com/facebook/create-react-app/issues/4263
      [
        require('@babel/plugin-proposal-class-properties').default,
        {
          loose: true,
        },
      ],
      // Adds Numeric Separators
      require('@babel/plugin-proposal-numeric-separator').default,
      // Polyfills the runtime needed for async/await, generators, and friends
      // https://babeljs.io/docs/en/babel-plugin-transform-runtime
      [
        require('@babel/plugin-transform-runtime').default,
        {
          corejs: false,
          helpers: areHelpersEnabled,
          // By default, babel assumes babel/runtime version 7.0.0-beta.0,
          // explicitly resolving to match the provided helper functions.
          // https://github.com/babel/babel/issues/10261
          version: require('@babel/runtime/package.json').version,
          regenerator: true,
          // https://babeljs.io/docs/en/babel-plugin-transform-runtime#useesmodules
          // We should turn this on once the lowest version of Node LTS
          // supports ES Modules.
          useESModules,
          // Undocumented option that lets us encapsulate our runtime, ensuring
          // the correct version is used
          // https://github.com/babel/babel/blob/090c364a90fe73d36a30707fc612ce037bdbbb24/packages/babel-plugin-transform-runtime/src/index.js#L35-L42
          absoluteRuntime: absoluteRuntimePath,
        },
      ],
      isEnvProduction && [
        // Remove PropTypes from production build
        require('babel-plugin-transform-react-remove-prop-types').default,
        {
          removeImport: true,
        },
      ],
      // Optional chaining and nullish coalescing are supported in @babel/preset-env,
      // but not yet supported in webpack due to support missing from acorn.
      // These can be removed once webpack has support.
      // See https://github.com/facebook/create-react-app/issues/8445#issuecomment-588512250
      require('@babel/plugin-proposal-optional-chaining').default,
      require('@babel/plugin-proposal-nullish-coalescing-operator').default,
    ].filter(Boolean),
    overrides: [
      isFlowEnabled && {
        exclude: /\.tsx?$/,
        plugins: [require('@babel/plugin-transform-flow-strip-types').default],
      },
      isTypeScriptEnabled && {
        test: /\.tsx?$/,
        plugins: [
          [
            require('@babel/plugin-proposal-decorators').default,
            { legacy: true },
          ],
        ],
      },
    ].filter(Boolean),
  };
};
<|endoftext|>


<commit_before>var path = require('path');
var fs = require('fs');
var cp = require('child_process');
var execFile = cp.execFile;
var pythonExecutable = process.env.PYTHON;

module.exports = function(cb) {
  verifyNode();
  verifyPython27(cb);
};

function verifyNode() {
  var nodeVersion = process.versions.node.split('.');
  var nodeMajorVersion = +nodeVersion[0];
  var nodeMinorVersion = +nodeVersion[1];
  if (nodeMajorVersion === 0 && nodeMinorVersion < 10) {
    console.warn("node v0.10 is required to build Atom.");
    process.exit(1);
  }
}

function verifyPython27(cb) {
  if (process.platform !== 'win32') {
    cb();
  }
  else {
    if (!pythonExecutable) {
      var systemDrive = process.env.SystemDrive || 'C:\\';
      pythonExecutable = path.join(systemDrive, 'Python27');

      if (fs.existsSync(pythonExecutable)) {
        pythonExecutable = path.join(pythonExecutable, 'python');
      }
      else {
        pythonExecutable = 'python';
      }
    }

    checkPythonVersion(pythonExecutable, cb);
  }
}

function checkPythonVersion (python, cb) {
  var pythonHelpMessage = "Set the PYTHON env var to '/path/to/Python27/python.exe' if your python is installed in a non-default location.";

  execFile(python, ['-c', 'import platform; print(platform.python_version());'], { env: process.env }, function (err, stdout) {
    if (err) {
      console.log("Python 2.7 is required to build Atom. An error occured when checking for python '" + err + "'");
      console.log(pythonHelpMessage);
      process.exit(1);
    }

    var version = stdout.trim();
    if (~version.indexOf('+')) {
      version = version.replace(/\+/g, '');
    }
    if (~version.indexOf('rc')) {
      version = version.replace(/rc(.*)$/ig, '');
    }

    // Atom requires python 2.7 or higher (but not python 3) for node-gyp
    var versionArray = version.split('.').map(function(num) { return +num; });
    var goodPythonVersion = (versionArray[0] === 2 && versionArray[1] >= 7);
    if (!goodPythonVersion) {
      console.log("Python 2.7 is required to build Atom. '" + python + "' returns version " + version);
      console.log(pythonHelpMessage);
      process.exit(1);
    }

    // Finally, if we've gotten this far, callback to resume the install process.
    cb();
  });
}
<commit_msg>Assume the PYTHON env points to python.exe<commit_after>var path = require('path');
var fs = require('fs');
var cp = require('child_process');
var execFile = cp.execFile;
var pythonExecutable = process.env.PYTHON;

module.exports = function(cb) {
  verifyNode();
  verifyPython27(cb);
};

function verifyNode() {
  var nodeVersion = process.versions.node.split('.');
  var nodeMajorVersion = +nodeVersion[0];
  var nodeMinorVersion = +nodeVersion[1];
  if (nodeMajorVersion === 0 && nodeMinorVersion < 10) {
    console.warn("node v0.10 is required to build Atom.");
    process.exit(1);
  }
}

function verifyPython27(cb) {
  if (false && process.platform !== 'win32') {
    cb();
  }
  else {
    if (!pythonExecutable) {
      var systemDrive = process.env.SystemDrive || 'C:\\';
      pythonExecutable = path.join(systemDrive, 'Python27', 'python.exe');

      if (!fs.existsSync(pythonExecutable)) {
        pythonExecutable = 'python';
      }
    }

    checkPythonVersion(pythonExecutable, cb);
  }
}

function checkPythonVersion (python, cb) {
  var pythonHelpMessage = "Set the PYTHON env var to '/path/to/Python27/python.exe' if your python is installed in a non-default location.";

  execFile(python, ['-c', 'import platform; print(platform.python_version());'], { env: process.env }, function (err, stdout) {
    if (err) {
      console.log("Python 2.7 is required to build Atom. An error occured when checking for python '" + err + "'");
      console.log(pythonHelpMessage);
      process.exit(1);
    }

    var version = stdout.trim();
    if (~version.indexOf('+')) {
      version = version.replace(/\+/g, '');
    }
    if (~version.indexOf('rc')) {
      version = version.replace(/rc(.*)$/ig, '');
    }

    // Atom requires python 2.7 or higher (but not python 3) for node-gyp
    var versionArray = version.split('.').map(function(num) { return +num; });
    var goodPythonVersion = (versionArray[0] === 2 && versionArray[1] >= 7);
    if (!goodPythonVersion) {
      console.log("Python 2.7 is required to build Atom. '" + python + "' returns version " + version);
      console.log(pythonHelpMessage);
      process.exit(1);
    }

    // Finally, if we've gotten this far, callback to resume the install process.
    cb();
  });
}
<|endoftext|>


<commit_before>'use strict';

const transformer = require('./transformer');

module.exports = function(markdownData, {
  lang = 'react-example',
  babelConfig,
  noreact,
}) {
  const { content } = markdownData;

  // ignore customized content
  if (Array.isArray(content)) {
    markdownData.content = content.map(node => {
      const tagName = node[0];
      const attr = node[1];
      if (tagName === 'pre' && attr && attr.lang === lang) {
        const code = node[2][1];
        const processedCode = transformer(code, babelConfig, noreact);
        return {
          __BISHENG_EMBEDED_CODE: true,
          code: processedCode,
        };
      }
      return node;
    });
  }

  return markdownData;
};
<commit_msg>fix: should parse before pass<commit_after>'use strict';

const transformer = require('./transformer');

module.exports = function(markdownData, {
  lang = 'react-example',
  babelConfig,
  noreact,
}) {
  const { content } = markdownData;

  // ignore customized content
  if (Array.isArray(content)) {
    markdownData.content = content.map(node => {
      const tagName = node[0];
      const attr = node[1];
      if (tagName === 'pre' && attr && attr.lang === lang) {
        const code = node[2][1];
        const processedCode = transformer(code, babelConfig && JSON.parse(babelConfig), noreact);
        return {
          __BISHENG_EMBEDED_CODE: true,
          code: processedCode,
        };
      }
      return node;
    });
  }

  return markdownData;
};
<|endoftext|>


<commit_before>(function() {

	"use strict";

	//Declare root variable - window in the browser, global on the server
	var root = this,
		Chart = root.Chart,
		helpers = Chart.helpers;

	Chart.elements = {};

	Chart.Element = function(configuration) {
		helpers.extend(this, configuration);
		this.initialize.apply(this, arguments);
	};
	helpers.extend(Chart.Element.prototype, {
		initialize: function() {},
		pivot: function() {
			if (!this._view) {
				this._view = helpers.clone(this._model);
			}
			this._start = helpers.clone(this._view);
			return this;
		},
		transition: function(ease) {
			if (!this._view) {
				this._view = helpers.clone(this._model);
			}
			if (!this._start) {
				this.pivot();
			}

			helpers.each(this._model, function(value, key) {

				if (key[0] === '_' || !this._model.hasOwnProperty(key)) {
					// Only non-underscored properties
				}

				// Init if doesn't exist
				else if (!this._view[key]) {
					if (typeof value === 'number' && isNaN(this._view[key]) === false) {
						this._view[key] = value * ease;
					} else {
						this._view[key] = value || null;
					}
				}

				// No unnecessary computations
				else if (this._model[key] === this._view[key]) {
					// It's the same! Woohoo!
				}

				// Color transitions if possible
				else if (typeof value === 'string') {
					try {
						var color = helpers.color(this._start[key]).mix(helpers.color(this._model[key]), ease);
						this._view[key] = color.rgbString();
					} catch (err) {
						this._view[key] = value;
					}
				}
				// Number transitions
				else if (typeof value === 'number') {
					var startVal = this._start[key] !== undefined && isNaN(this._start[key]) === false ? this._start[key] : 0;
					this._view[key] = ((this._model[key] - startVal) * ease) + startVal;
				}
				// Everything else
				else {
					this._view[key] = value;
				}
			}, this);

			if (ease === 1) {
				delete this._start;
			}
			return this;
		},
		tooltipPosition: function() {
			return {
				x: this._model.x,
				y: this._model.y
			};
		},
		hasValue: function() {
			return helpers.isNumber(this._model.x) && helpers.isNumber(this._model.y);
		}
	});

	Chart.Element.extend = helpers.inherits;

}).call(this);
<commit_msg>Transition optimizations<commit_after>(function() {

	"use strict";

	//Declare root variable - window in the browser, global on the server
	var root = this,
		Chart = root.Chart,
		helpers = Chart.helpers;

	Chart.elements = {};

	Chart.Element = function(configuration) {
		helpers.extend(this, configuration);
		this.initialize.apply(this, arguments);
	};
	helpers.extend(Chart.Element.prototype, {
		initialize: function() {},
		pivot: function() {
			if (!this._view) {
				this._view = helpers.clone(this._model);
			}
			this._start = helpers.clone(this._view);
			return this;
		},
		transition: function(ease) {
			if (!this._view) {
				this._view = helpers.clone(this._model);
			}

			// No animation -> No Transition
			if (ease === 1) {
				this._view = this._model;
				this._start = null;
				return this;
			}

			if (!this._start) {
				this.pivot();
			}

			helpers.each(this._model, function(value, key) {

				if (key[0] === '_' || !this._model.hasOwnProperty(key)) {
					// Only non-underscored properties
				}

				// Init if doesn't exist
				else if (!this._view.hasOwnProperty(key)) {
					if (typeof value === 'number' && !isNaN(this._view[key])) {
						this._view[key] = value * ease;
					} else {
						this._view[key] = value;
					}
				}

				// No unnecessary computations
				else if (value === this._view[key]) {
					// It's the same! Woohoo!
				}

				// Color transitions if possible
				else if (typeof value === 'string') {
					try {
						var color = helpers.color(this._start[key]).mix(helpers.color(this._model[key]), ease);
						this._view[key] = color.rgbString();
					} catch (err) {
						this._view[key] = value;
					}
				}
				// Number transitions
				else if (typeof value === 'number') {
					var startVal = this._start[key] !== undefined && isNaN(this._start[key]) === false ? this._start[key] : 0;
					this._view[key] = ((this._model[key] - startVal) * ease) + startVal;
				}
				// Everything else
				else {
					this._view[key] = value;
				}
			}, this);

			return this;
		},
		tooltipPosition: function() {
			return {
				x: this._model.x,
				y: this._model.y
			};
		},
		hasValue: function() {
			return helpers.isNumber(this._model.x) && helpers.isNumber(this._model.y);
		}
	});

	Chart.Element.extend = helpers.inherits;

}).call(this);
<|endoftext|>


<commit_before>import PropTypes from 'prop-types';
import React from 'react';
import {
  TouchableNativeFeedback,
  TouchableHighlight,
  StyleSheet,
  View,
  Platform,
  ActivityIndicator,
  Text as NativeText,
} from 'react-native';
import colors from '../config/colors';
import Text from '../text/Text';
import MaterialIcon from 'react-native-vector-icons/MaterialIcons';
import getIconType from '../helpers/getIconType';
import normalize from '../helpers/normalizeText';
import ViewPropTypes from '../config/ViewPropTypes';

const log = () => {
  console.log('please attach method to this component'); //eslint-disable-line no-console
};

const Button = props => {
  const {
    disabled,
    loading,
    loadingRight,
    activityIndicatorStyle,
    buttonStyle,
    borderRadius,
    title,
    onPress,
    icon,
    iconComponent,
    secondary,
    secondary2,
    secondary3,
    primary1,
    primary2,
    backgroundColor,
    color,
    fontSize,
    underlayColor,
    raised,
    textStyle,
    large,
    iconRight,
    fontWeight,
    disabledStyle,
    fontFamily,
    containerViewStyle,
    rounded,
    outline,
    transparent,
    textNumberOfLines,
    textEllipsizeMode,
    allowFontScaling,
    ...attributes
  } = props;
  let { Component } = props;

  let iconElement;
  if (icon) {
    let Icon;
    if (iconComponent) {
      Icon = iconComponent;
    } else if (!icon.type) {
      Icon = MaterialIcon;
    } else {
      Icon = getIconType(icon.type);
    }
    iconElement = (
      <Icon
        {...icon}
        color={icon.color || 'white'}
        size={icon.size || (large ? 26 : 18)}
        style={[
          iconRight ? styles.iconRight : styles.icon,
          icon.style && icon.style,
        ]}
      />
    );
  }
  let loadingElement;
  if (loading) {
    loadingElement = (
      <ActivityIndicator
        animating={true}
        style={[styles.activityIndicatorStyle, activityIndicatorStyle]}
        color={color || 'white'}
        size={(large && 'large') || 'small'}
      />
    );
  }
  if (!Component && Platform.OS === 'ios') {
    Component = TouchableHighlight;
  }
  if (!Component && Platform.OS === 'android') {
    Component = TouchableNativeFeedback;
  }
  if (!Component) {
    Component = TouchableHighlight;
  }

  if (Platform.OS === 'android' && (borderRadius && !attributes.background)) {
    attributes.background = TouchableNativeFeedback.Ripple(
      'ThemeAttrAndroid',
      true
    );
  }

  const baseFont = {
    color: (textStyle && textStyle.color) || color || stylesObject.text.color,
    size: (textStyle && textStyle.fontSize) ||
      fontSize ||
      (!large && stylesObject.smallFont.fontSize) ||
      stylesObject.text.fontSize,
  };

  let textOptions = {};
  if (textNumberOfLines) {
    textOptions.numberOfLines = textNumberOfLines;
    if (textEllipsizeMode) {
      textOptions.ellipsizeMode = textEllipsizeMode;
    }
  }

  return (
    <View
      style={[styles.container, raised && styles.raised, containerViewStyle]}
    >
      <Component
        underlayColor={underlayColor || 'transparent'}
        onPress={onPress || log}
        disabled={disabled || false}
        {...attributes}
      >
        <View
          style={[
            styles.button,
            secondary && { backgroundColor: colors.secondary },
            secondary2 && { backgroundColor: colors.secondary2 },
            secondary3 && { backgroundColor: colors.secondary3 },
            primary1 && { backgroundColor: colors.primary1 },
            primary2 && { backgroundColor: colors.primary2 },
            backgroundColor && { backgroundColor: backgroundColor },
            borderRadius && { borderRadius },
            !large && styles.small,
            rounded && {
              borderRadius: baseFont.size * 3.8,
              paddingHorizontal: !large
                ? stylesObject.small.padding * 1.5
                : stylesObject.button.padding * 1.5,
            },
            outline && {
              borderWidth: 1,
              backgroundColor: 'transparent',
              borderColor: baseFont.color,
            },
            transparent && {
              borderWidth: 0,
              backgroundColor: 'transparent',
            },
            buttonStyle && buttonStyle,
            disabled && { backgroundColor: colors.disabled },
            disabled && disabledStyle && disabledStyle,
          ]}
        >
          {icon && !iconRight && iconElement}
          {loading && !loadingRight && loadingElement}
          <Text
            style={[
              styles.text,
              color && { color },
              !large && styles.smallFont,
              fontSize && { fontSize },
              textStyle && textStyle,
              fontWeight && { fontWeight },
              fontFamily && { fontFamily },
            ]}
            {...textOptions}
            allowFontScaling={allowFontScaling}
          >
            {title}
          </Text>
          {loading && loadingRight && loadingElement}
          {icon && iconRight && iconElement}
        </View>
      </Component>
    </View>
  );
};

Button.propTypes = {
  buttonStyle: ViewPropTypes.style,
  title: PropTypes.string,
  onPress: PropTypes.any,
  icon: PropTypes.object,
  iconComponent: PropTypes.any,
  secondary: PropTypes.bool,
  secondary2: PropTypes.bool,
  secondary3: PropTypes.bool,
  primary1: PropTypes.bool,
  primary2: PropTypes.bool,
  backgroundColor: PropTypes.string,
  color: PropTypes.string,
  fontSize: PropTypes.any,
  underlayColor: PropTypes.string,
  raised: PropTypes.bool,
  textStyle: NativeText.propTypes.style,
  disabled: PropTypes.bool,
  loading: PropTypes.bool,
  activityIndicatorStyle: ViewPropTypes.style,
  loadingRight: PropTypes.bool,
  Component: PropTypes.any,
  borderRadius: PropTypes.number,
  large: PropTypes.bool,
  iconRight: PropTypes.bool,
  fontWeight: PropTypes.string,
  disabledStyle: ViewPropTypes.style,
  fontFamily: PropTypes.string,
  containerViewStyle: ViewPropTypes.style,
  rounded: PropTypes.bool,
  outline: PropTypes.bool,
  transparent: PropTypes.bool,
  allowFontScaling: PropTypes.bool,
  textNumberOfLines: PropTypes.number,
  textEllipsizeMode: PropTypes.string,
};

const stylesObject = {
  container: {
    backgroundColor: 'transparent',
    marginLeft: 15,
    marginRight: 15,
  },
  button: {
    padding: 19,
    backgroundColor: colors.primary,
    justifyContent: 'center',
    alignItems: 'center',
    flexDirection: 'row',
  },
  text: {
    color: 'white',
    fontSize: normalize(16),
  },
  icon: {
    marginRight: 10,
  },
  iconRight: {
    marginLeft: 10,
  },
  small: {
    padding: 12,
  },
  smallFont: {
    fontSize: normalize(14),
  },
  activityIndicatorStyle: {
    marginHorizontal: 10,
    height: 0,
  },
  raised: {
    ...Platform.select({
      ios: {
        shadowColor: 'rgba(0,0,0, .4)',
        shadowOffset: { height: 1, width: 1 },
        shadowOpacity: 1,
        shadowRadius: 1,
      },
      android: {
        elevation: 2,
      },
    }),
  },
};

const styles = StyleSheet.create(stylesObject);

export default Button;
<commit_msg>Add background color to Button raised for android to calculate elevation. Fixes #491<commit_after>import PropTypes from 'prop-types';
import React from 'react';
import {
  TouchableNativeFeedback,
  TouchableHighlight,
  StyleSheet,
  View,
  Platform,
  ActivityIndicator,
  Text as NativeText,
} from 'react-native';
import colors from '../config/colors';
import Text from '../text/Text';
import MaterialIcon from 'react-native-vector-icons/MaterialIcons';
import getIconType from '../helpers/getIconType';
import normalize from '../helpers/normalizeText';
import ViewPropTypes from '../config/ViewPropTypes';

const log = () => {
  console.log('please attach method to this component'); //eslint-disable-line no-console
};

const Button = props => {
  const {
    disabled,
    loading,
    loadingRight,
    activityIndicatorStyle,
    buttonStyle,
    borderRadius,
    title,
    onPress,
    icon,
    iconComponent,
    secondary,
    secondary2,
    secondary3,
    primary1,
    primary2,
    backgroundColor,
    color,
    fontSize,
    underlayColor,
    raised,
    textStyle,
    large,
    iconRight,
    fontWeight,
    disabledStyle,
    fontFamily,
    containerViewStyle,
    rounded,
    outline,
    transparent,
    textNumberOfLines,
    textEllipsizeMode,
    allowFontScaling,
    ...attributes
  } = props;
  let { Component } = props;

  let iconElement;
  if (icon) {
    let Icon;
    if (iconComponent) {
      Icon = iconComponent;
    } else if (!icon.type) {
      Icon = MaterialIcon;
    } else {
      Icon = getIconType(icon.type);
    }
    iconElement = (
      <Icon
        {...icon}
        color={icon.color || 'white'}
        size={icon.size || (large ? 26 : 18)}
        style={[
          iconRight ? styles.iconRight : styles.icon,
          icon.style && icon.style,
        ]}
      />
    );
  }
  let loadingElement;
  if (loading) {
    loadingElement = (
      <ActivityIndicator
        animating={true}
        style={[styles.activityIndicatorStyle, activityIndicatorStyle]}
        color={color || 'white'}
        size={(large && 'large') || 'small'}
      />
    );
  }
  if (!Component && Platform.OS === 'ios') {
    Component = TouchableHighlight;
  }
  if (!Component && Platform.OS === 'android') {
    Component = TouchableNativeFeedback;
  }
  if (!Component) {
    Component = TouchableHighlight;
  }

  if (Platform.OS === 'android' && (borderRadius && !attributes.background)) {
    attributes.background = TouchableNativeFeedback.Ripple(
      'ThemeAttrAndroid',
      true
    );
  }

  const baseFont = {
    color: (textStyle && textStyle.color) || color || stylesObject.text.color,
    size: (textStyle && textStyle.fontSize) ||
      fontSize ||
      (!large && stylesObject.smallFont.fontSize) ||
      stylesObject.text.fontSize,
  };

  let textOptions = {};
  if (textNumberOfLines) {
    textOptions.numberOfLines = textNumberOfLines;
    if (textEllipsizeMode) {
      textOptions.ellipsizeMode = textEllipsizeMode;
    }
  }

  return (
    <View
      style={[styles.container, raised && styles.raised, containerViewStyle]}
    >
      <Component
        underlayColor={underlayColor || 'transparent'}
        onPress={onPress || log}
        disabled={disabled || false}
        {...attributes}
      >
        <View
          style={[
            styles.button,
            secondary && { backgroundColor: colors.secondary },
            secondary2 && { backgroundColor: colors.secondary2 },
            secondary3 && { backgroundColor: colors.secondary3 },
            primary1 && { backgroundColor: colors.primary1 },
            primary2 && { backgroundColor: colors.primary2 },
            backgroundColor && { backgroundColor: backgroundColor },
            borderRadius && { borderRadius },
            !large && styles.small,
            rounded && {
              borderRadius: baseFont.size * 3.8,
              paddingHorizontal: !large
                ? stylesObject.small.padding * 1.5
                : stylesObject.button.padding * 1.5,
            },
            outline && {
              borderWidth: 1,
              backgroundColor: 'transparent',
              borderColor: baseFont.color,
            },
            transparent && {
              borderWidth: 0,
              backgroundColor: 'transparent',
            },
            buttonStyle && buttonStyle,
            disabled && { backgroundColor: colors.disabled },
            disabled && disabledStyle && disabledStyle,
          ]}
        >
          {icon && !iconRight && iconElement}
          {loading && !loadingRight && loadingElement}
          <Text
            style={[
              styles.text,
              color && { color },
              !large && styles.smallFont,
              fontSize && { fontSize },
              textStyle && textStyle,
              fontWeight && { fontWeight },
              fontFamily && { fontFamily },
            ]}
            {...textOptions}
            allowFontScaling={allowFontScaling}
          >
            {title}
          </Text>
          {loading && loadingRight && loadingElement}
          {icon && iconRight && iconElement}
        </View>
      </Component>
    </View>
  );
};

Button.propTypes = {
  buttonStyle: ViewPropTypes.style,
  title: PropTypes.string,
  onPress: PropTypes.any,
  icon: PropTypes.object,
  iconComponent: PropTypes.any,
  secondary: PropTypes.bool,
  secondary2: PropTypes.bool,
  secondary3: PropTypes.bool,
  primary1: PropTypes.bool,
  primary2: PropTypes.bool,
  backgroundColor: PropTypes.string,
  color: PropTypes.string,
  fontSize: PropTypes.any,
  underlayColor: PropTypes.string,
  raised: PropTypes.bool,
  textStyle: NativeText.propTypes.style,
  disabled: PropTypes.bool,
  loading: PropTypes.bool,
  activityIndicatorStyle: ViewPropTypes.style,
  loadingRight: PropTypes.bool,
  Component: PropTypes.any,
  borderRadius: PropTypes.number,
  large: PropTypes.bool,
  iconRight: PropTypes.bool,
  fontWeight: PropTypes.string,
  disabledStyle: ViewPropTypes.style,
  fontFamily: PropTypes.string,
  containerViewStyle: ViewPropTypes.style,
  rounded: PropTypes.bool,
  outline: PropTypes.bool,
  transparent: PropTypes.bool,
  allowFontScaling: PropTypes.bool,
  textNumberOfLines: PropTypes.number,
  textEllipsizeMode: PropTypes.string,
};

const stylesObject = {
  container: {
    backgroundColor: 'transparent',
    marginLeft: 15,
    marginRight: 15,
  },
  button: {
    padding: 19,
    backgroundColor: colors.primary,
    justifyContent: 'center',
    alignItems: 'center',
    flexDirection: 'row',
  },
  text: {
    color: 'white',
    fontSize: normalize(16),
  },
  icon: {
    marginRight: 10,
  },
  iconRight: {
    marginLeft: 10,
  },
  small: {
    padding: 12,
  },
  smallFont: {
    fontSize: normalize(14),
  },
  activityIndicatorStyle: {
    marginHorizontal: 10,
    height: 0,
  },
  raised: {
    ...Platform.select({
      ios: {
        shadowColor: 'rgba(0,0,0, .4)',
        shadowOffset: { height: 1, width: 1 },
        shadowOpacity: 1,
        shadowRadius: 1,
      },
      android: {
        backgroundColor: '#fff',
        elevation: 2,
      },
    }),
  },
};

const styles = StyleSheet.create(stylesObject);

export default Button;
<|endoftext|>


<commit_before>const { Shims } = require("@truffle/compile-common");

function shimOutput({ contracts: list, sourceIndexes, compiler }) {
  const contracts = list
    // get old format
    .map(contract => Shims.NewToLegacy.forContract(contract))
    // get pair
    .map(contract => ({ [contract.contract_name]: contract }))
    // merge pairs
    .reduce((a, b) => Object.assign({}, a, b), {});

  return [contracts, sourceIndexes, compiler];
}

function shimBytecode(bytecode) {
  if (!bytecode) {
    return bytecode;
  }
  if (typeof bytecode === "string") {
    return bytecode;
  }

  let { bytes, linkReferences } = bytecode;

  linkReferences = linkReferences || [];

  // inline link references - start by flattening the offsets
  const flattenedLinkReferences = linkReferences
    // map each link ref to array of link refs with only one offset
    .map(({ offsets, length, name }) =>
      offsets.map(offset => ({ offset, length, name }))
    )
    // flatten
    .reduce((a, b) => [...a, ...b], []);

  // then overwite bytes with link reference
  bytes = flattenedLinkReferences.reduce((bytes, { offset, name, length }) => {
    // length is a byte offset
    const characterLength = length * 2;

    let linkId = `__${name.slice(0, characterLength - 2)}`;
    while (linkId.length < characterLength) {
      linkId += "_";
    }

    const start = offset * 2;

    return `${bytes.substring(0, start)}${linkId}${bytes.substring(
      start + characterLength
    )}`;
  }, bytes);

  return `0x${bytes}`;
}

module.exports = {
  shimOutput,
  shimBytecode
};
<commit_msg>Remove other unused shim<commit_after>const { Shims } = require("@truffle/compile-common");

function shimOutput({ contracts: list, sourceIndexes, compiler }) {
  const contracts = list
    // get old format
    .map(contract => Shims.NewToLegacy.forContract(contract))
    // get pair
    .map(contract => ({ [contract.contract_name]: contract }))
    // merge pairs
    .reduce((a, b) => Object.assign({}, a, b), {});

  return [contracts, sourceIndexes, compiler];
}

module.exports = {
  shimOutput
};
<|endoftext|>


<commit_before>var path = require('path');
var fs = require('fs');
var cp = require('child_process');
var execFile = cp.execFile;
var pythonExecutable = process.env.PYTHON;

module.exports = function(cb) {
  verifyNode(function(error, nodeSuccessMessage) {
    if (error) {
      cb(error);
      return;
    }

    verifyPython27(function(error, pythonSuccessMessage) {
      cb(error, nodeSuccessMessage + "\n" + pythonSuccessMessage);
    });
  });

};

function verifyNode(cb) {
  var nodeVersion = process.versions.node;
  var versionArray = nodeVersion.split('.');
  var nodeMajorVersion = +versionArray[0];
  var nodeMinorVersion = +versionArray[1];
  if (nodeMajorVersion === 0 && nodeMinorVersion < 10) {
    error = "node v0.10 is required to build Atom.";
    cb(error);
  }
  else {
    cb(null, "Node: v" + nodeVersion);
  }
}

function verifyPython27(cb) {
  if (process.platform !== 'win32') {
    cb(null, "Python: <not verified>");
  }
  else {
    if (!pythonExecutable) {
      var systemDrive = process.env.SystemDrive || 'C:\\';
      pythonExecutable = path.join(systemDrive, 'Python27', 'python.exe');

      if (!fs.existsSync(pythonExecutable)) {
        pythonExecutable = 'python';
      }
    }

    checkPythonVersion(pythonExecutable, cb);
  }
}

function checkPythonVersion (python, cb) {
  var pythonHelpMessage = "Set the PYTHON env var to '/path/to/Python27/python.exe' if your python is installed in a non-default location.";

  execFile(python, ['-c', 'import platform; print(platform.python_version());'], { env: process.env }, function (err, stdout) {
    if (err) {
      error = "Python 2.7 is required to build Atom. An error occured when checking the version of '" + python + "'\n " + err + ". ";
      error += pythonHelpMessage;
      cb(error);
      return;
    }

    var version = stdout.trim();
    if (~version.indexOf('+')) {
      version = version.replace(/\+/g, '');
    }
    if (~version.indexOf('rc')) {
      version = version.replace(/rc(.*)$/ig, '');
    }

    // Atom requires python 2.7 or higher (but not python 3) for node-gyp
    var versionArray = version.split('.').map(function(num) { return +num; });
    var goodPythonVersion = (versionArray[0] === 2 && versionArray[1] >= 7);
    if (!goodPythonVersion) {
      error = "Python 2.7 is required to build Atom. '" + python + "' returns version " + version + ". ";
      error += pythonHelpMessage;
      cb(error);
      return;
    }

    // Finally, if we've gotten this far, callback to resume the install process.
    cb(null, "Python: v" + version);
  });
}
<commit_msg>:lipstick:<commit_after>var path = require('path');
var fs = require('fs');
var cp = require('child_process');
var execFile = cp.execFile;
var pythonExecutable = process.env.PYTHON;

module.exports = function(cb) {
  verifyNode(function(error, nodeSuccessMessage) {
    if (error) {
      cb(error);
      return;
    }

    verifyPython27(function(error, pythonSuccessMessage) {
      cb(error, nodeSuccessMessage + "\n" + pythonSuccessMessage);
    });
  });

};

function verifyNode(cb) {
  var nodeVersion = process.versions.node;
  var versionArray = nodeVersion.split('.');
  var nodeMajorVersion = +versionArray[0];
  var nodeMinorVersion = +versionArray[1];
  if (nodeMajorVersion === 0 && nodeMinorVersion < 10) {
    error = "node v0.10 is required to build Atom.";
    cb(error);
  }
  else {
    cb(null, "Node: v" + nodeVersion);
  }
}

function verifyPython27(cb) {
  if (process.platform !== 'win32') {
    cb(null, "Python: <not verified>");
  }
  else {
    if (!pythonExecutable) {
      var systemDrive = process.env.SystemDrive || 'C:\\';
      pythonExecutable = path.join(systemDrive, 'Python27', 'python.exe');

      if (!fs.existsSync(pythonExecutable)) {
        pythonExecutable = 'python';
      }
    }

    checkPythonVersion(pythonExecutable, cb);
  }
}

function checkPythonVersion (python, cb) {
  var pythonHelpMessage = "Set the PYTHON env var to '/path/to/Python27/python.exe' if your python is installed in a non-default location.";

  execFile(python, ['-c', 'import platform; print(platform.python_version());'], { env: process.env }, function (err, stdout) {
    if (err) {
      error = "Python 2.7 is required to build Atom. An error (" + err + ") occured when checking the version of '" + python + "'. ";
      error += pythonHelpMessage;
      cb(error);
      return;
    }

    var version = stdout.trim();
    if (~version.indexOf('+')) {
      version = version.replace(/\+/g, '');
    }
    if (~version.indexOf('rc')) {
      version = version.replace(/rc(.*)$/ig, '');
    }

    // Atom requires python 2.7 or higher (but not python 3) for node-gyp
    var versionArray = version.split('.').map(function(num) { return +num; });
    var goodPythonVersion = (versionArray[0] === 2 && versionArray[1] >= 7);
    if (!goodPythonVersion) {
      error = "Python 2.7 is required to build Atom. '" + python + "' returns version " + version + ". ";
      error += pythonHelpMessage;
      cb(error);
      return;
    }

    // Finally, if we've gotten this far, callback to resume the install process.
    cb(null, "Python: v" + version);
  });
}
<|endoftext|>


<commit_before>// @flow
import React, {Component, Element} from 'react';
import * as libs from '../libs';
import uuid from 'uuid';
import type {DOMEvent, FormActions, FormConfig,
  FormErrors, FormField, FormFields, ListRow} from '../types';
import deepEqual from 'deep-equal';

let lib, fields, FormControl, layouts, Button;

type Props = {
  actions: FormActions,
  className?: string,
  config: {
    view: string,
    form: FormConfig
  },
  data: ListRow,
  errors: FormErrors,
  formUpdate: Function,
  layout: string,
  lib?: string,
  onSubmit: Function
};

/**
 * Create a form
 */
class UiForm extends Component {
  props: Props

  state: {
    errors: Object,
    form: Object,
    data: Object,
    state: Object
  }
  fields: FormFields
  actions: FormActions
  handleChange: (e: DOMEvent, name: string) => {}
  handleBlur: (name: string) => {}
  onSubmit: (e: DOMEvent, data: Object) => {}

  /**
   * Constructor
   * @param {Object} props props
   */
  constructor(props: Props) {
    super(props);
    const {config, onSubmit} = this.props;
    let state = {};
    Object.keys(props.errors).forEach(key => state[key] = 'error');
    this.state = {
      errors: props.errors,
      form: config.form,
      data: props.data || {},
      state
    };
    let libType = config.lib || 'reactBootstrap';
    lib = libs[libType];
    fields = lib.fields;
    layouts = lib.layouts;
    FormControl = lib.FormControl;
    Button = lib.Button;

    this.fields = config.form.fields;
    Object.keys(this.fields).forEach(k => {
      this.fields[k].pristine = true;
    })
    this.actions = config.form.actions;

    this.state.data = this.makeState(props.data);

    this.handleChange = this.handleChange.bind(this);
    this.handleBlur = this.handleBlur.bind(this);
    this.onSubmit = onSubmit.bind(this);
    this.applyDataToForm(this.state.data);
  }

  /**
   * Will receive new props
   * @param {Object} newProps Props
   */
  componentWillReceiveProps(newProps: Props) {
    const {config, errors} = newProps;
    this.fields = config.form.fields;
    let state = {},
      data;
    Object.keys(errors).forEach(key => state[key] = 'error');

    if (!deepEqual(this.props.data, newProps.data)) {
      // this.applyDataToForm(this.state.data);
      data = this.makeState(newProps.data);
    }

    this.setState({data, state, errors});
  }

  /**
   * Build the form state, using this.props.data, then field value
   * for data.
   * @param {Object} data Props
   * @return {Object} list row
   */
  makeState(data: Props): ListRow {
    let name, state = {};
    for (name in this.fields) {
      if (data && data[name]) {
        state[name] = data[name];
      } else if (this.fields[name].default === undefined) {
        state[name] = '';
      } else {
        state[name] = this.fields[name].default;
      }
    }
    return state;
  }

  /**
   * Update the form's properties so that any config value that is a function is
   * run and the current record's data applied.
   * @param {Object} row Form state
   */
  applyDataToForm(row: ListRow) {
    let name,
      form = this.state.form;
    if (typeof (form._title) === 'function') {
      this.state.form.title = form._title(row);
    }
    for (name in form.actions) {
      if (typeof (form.actions[name]._label) === 'function') {
        this.state.form.actions[name].label = form.actions[name]._label(row);
      }
    }
  }

  /**
   * Validate a single field
   * @param {Object} field Field
   * @param {String} value Field value
   * @param {Object} data Form data
   * @return {Promise}
   */
  validateOne(field, value, data = {}): Promise<string> {
    if (field.validate === undefined) {
      return Promise.resolve();
    }
    let promises = field.validate.promises
      .map((p) =>
        p.rule(value, data, field.validate.msg)
    );

    return new Promise((resolve: Function, reject: Function) => {
      return Promise.all(promises)
        .then(() => resolve('success'))
        .catch(e => {
          reject(field.validate.msg(value, data));
        });
    })

  }

  /**
   * Get validation state
   * @param {string} name column name
   * @return {Object} validation state
   */
  getValidationState(name: string): Object {
    let field = this.fields[name],
      {errors} = this.state,
      state = this.state.state,
      i = 0,
      value = this.state.data[name],
      res = [],
      serverError = (errors[name] && errors[name].length > 0),
      serverSuccess = (errors[name] && errors[name].length === 0);

    if (!field.pristine) {
      this.validateOne(field, value, this.state.data)
      .then(ok => {
        state[name] = 'success';
        this.setState(state);
      })
      .catch(err => {
        state[name] = 'error';
        this.setState(state);
      })
    } else {
       if (serverError) {
        state[name] = 'error';
      }
      if (serverSuccess) {
        state[name] = 'success';
      }
    }

    this.setState(state);
    return state;
  }

  /**
   * Check field access, if no access property then return true
   * Otherwise it should be an object with functions keyed on edit or new
   * @param {Object} field To render
   * @return {Bool} Can access field
   */
  access(field: FormField): boolean {
    const mode = this.state.data.id === '' ? 'new' : 'edit';

    if (!field.access) {
      return true;
    }

    if (field.access[mode]) {
      return field.access[mode](field, this.state.data);
    }

    return true;
  }

  /**
   * Update the form's state
   * @param {String} name Field name
   * @param {String|number} value Field value
   */
  handleChange(name: string, value: string | number) {
    const {formUpdate, config} = this.props,
      field = this.fields[name];
    this.fields[name].pristine = false;
    if (typeof formUpdate === 'function') {
      formUpdate(config.view, field, name, value);
    }
    let data = this.state.data;
    data[name] = value;
    this.setState({data});

    if (field.onChange) {
      field.onChange(this);
    }
  }

  /**
   * Get the form's layout
   * @return {Dom} Dom node
   */
  formLayout() {
    const {layout} = this.props;
    if (typeof layout === 'function') {
      return layout;
    }
    let layoutName = layout && layout[0].toUpperCase() + layout.slice(1);
    return layouts[layoutName] ? layouts[layoutName] : layouts.Default;
  }

  /**
   * Handle field blur - check validation state
   */
  handleBlur(name: string) {
    this.fields[name].pristine = false;
    let state = this.getValidationState(name);
  }

  /**
   * Buid the react class for the field
   * @param {Object} field Field
   * @return {Element}
   */
  getReactField(field: FormField): Element<*> | null {
    let FieldComponent = null,
      type;
    if (typeof field === 'function') {
      FieldComponent = field;
    } else {
      switch (typeof field.type) {
      case 'string':
        // Ucase first the name
        type = field.type && field.type[0].toUpperCase()
          + field.type.slice(1);
        if (fields[type]) {
           FieldComponent = fields[type];
        }
        break;
      case 'function':
        FieldComponent = field.type;
        break;
      }
    }

    return FieldComponent;
  }
  /**
   * Build a field
   * @param {String} name Field name
   * @param {Object} field Field
   * @return {Node} FormGroup - field, help and label
   */
  makeField(name: string, field: FormField): Element<any> | null {
    let {errors} = this.state,
      error = errors[name] || [],
      FormGroup = lib.FormGroup,
      FieldComponent = this.getReactField(field);

    return <FormGroup
      key={`field-formgroup-${name}`}
      errors={error}
      FieldComponent={FieldComponent}
      field={field}
      name={name}
      row={this.state.data}
      onBlur={this.handleBlur}
      onChange={(name, value) => this.handleChange(name, value)}
      value={this.state.data[name] || field.value || ''}
      validationState={this.state.state[name]} />
  }

  /**
   * Render
   * @return {Node} Dom node
   */
  render(): React$Element<any> {
    const {errors} = this.props,
      FormActions = lib.FormActions,
      buttons = <FormActions
                  actions={this.actions}
                  onSubmit={e => {
                    e.preventDefault();
                    this.onSubmit(e, this.state.data)}
                  }/>,
      FormLayout = this.formLayout();

    let fields = {};

    Object.keys(this.fields)
      .filter(name => this.access(this.fields[name]))
      .forEach(name => {
        let field = this.fields[name];
        fields[name] = this.makeField(name, field);
    });

    return (<FormLayout
              actions={buttons}
              errors={errors}
              fields={fields}
              form={this.state.form}
              onSubmit={this.onSubmit} />);
  }
}

export default UiForm;
<commit_msg>form reloading with same data props destroyed form data state<commit_after>// @flow
import React, {Component, Element} from 'react';
import * as libs from '../libs';
import uuid from 'uuid';
import type {DOMEvent, FormActions, FormConfig,
  FormErrors, FormField, FormFields, ListRow} from '../types';
import deepEqual from 'deep-equal';

let lib, fields, FormControl, layouts, Button;

type Props = {
  actions: FormActions,
  className?: string,
  config: {
    view: string,
    form: FormConfig
  },
  data: ListRow,
  errors: FormErrors,
  formUpdate: Function,
  layout: string,
  lib?: string,
  onSubmit: Function
};

/**
 * Create a form
 */
class UiForm extends Component {
  props: Props

  state: {
    errors: Object,
    form: Object,
    data: Object,
    state: Object
  }
  fields: FormFields
  actions: FormActions
  handleChange: (e: DOMEvent, name: string) => {}
  handleBlur: (name: string) => {}
  onSubmit: (e: DOMEvent, data: Object) => {}

  /**
   * Constructor
   * @param {Object} props props
   */
  constructor(props: Props) {
    super(props);
    const {config, onSubmit} = this.props;
    let state = {};
    Object.keys(props.errors).forEach(key => state[key] = 'error');
    this.state = {
      errors: props.errors,
      form: config.form,
      data: props.data || {},
      state
    };
    let libType = config.lib || 'reactBootstrap';
    lib = libs[libType];
    fields = lib.fields;
    layouts = lib.layouts;
    FormControl = lib.FormControl;
    Button = lib.Button;

    this.fields = config.form.fields;
    Object.keys(this.fields).forEach(k => {
      this.fields[k].pristine = true;
    })
    this.actions = config.form.actions;

    this.state.data = this.makeState(props.data);

    this.handleChange = this.handleChange.bind(this);
    this.handleBlur = this.handleBlur.bind(this);
    this.onSubmit = onSubmit.bind(this);
    this.applyDataToForm(this.state.data);
  }

  /**
   * Will receive new props
   * @param {Object} newProps Props
   */
  componentWillReceiveProps(newProps: Props) {
    const {config, errors} = newProps;
    this.fields = config.form.fields;
    let state = {},
      newState = {};
    Object.keys(errors).forEach(key => state[key] = 'error');

    if (!deepEqual(this.props.data, newProps.data)) {
      newState.data = this.makeState(newProps.data);
    }

    this.setState({...newState, state, errors});
  }

  /**
   * Build the form state, using this.props.data, then field value
   * for data.
   * @param {Object} data Props
   * @return {Object} list row
   */
  makeState(data: Props): ListRow {
    let name, state = {};
    for (name in this.fields) {
      if (data && data[name]) {
        state[name] = data[name];
      } else if (this.fields[name].default === undefined) {
        state[name] = '';
      } else {
        state[name] = this.fields[name].default;
      }
    }
    return state;
  }

  /**
   * Update the form's properties so that any config value that is a function is
   * run and the current record's data applied.
   * @param {Object} row Form state
   */
  applyDataToForm(row: ListRow) {
    let name,
      form = this.state.form;
    if (typeof (form._title) === 'function') {
      this.state.form.title = form._title(row);
    }
    for (name in form.actions) {
      if (typeof (form.actions[name]._label) === 'function') {
        this.state.form.actions[name].label = form.actions[name]._label(row);
      }
    }
  }

  /**
   * Validate a single field
   * @param {Object} field Field
   * @param {String} value Field value
   * @param {Object} data Form data
   * @return {Promise}
   */
  validateOne(field, value, data = {}): Promise<string> {
    if (field.validate === undefined) {
      return Promise.resolve();
    }
    let promises = field.validate.promises
      .map((p) =>
        p.rule(value, data, field.validate.msg)
    );

    return new Promise((resolve: Function, reject: Function) => {
      return Promise.all(promises)
        .then(() => resolve('success'))
        .catch(e => {
          reject(field.validate.msg(value, data));
        });
    })

  }

  /**
   * Get validation state
   * @param {string} name column name
   * @return {Object} validation state
   */
  getValidationState(name: string): Object {
    let field = this.fields[name],
      {errors} = this.state,
      state = this.state.state,
      i = 0,
      value = this.state.data[name],
      res = [],
      serverError = (errors[name] && errors[name].length > 0),
      serverSuccess = (errors[name] && errors[name].length === 0);

    if (!field.pristine) {
      this.validateOne(field, value, this.state.data)
      .then(ok => {
        state[name] = 'success';
        this.setState(state);
      })
      .catch(err => {
        state[name] = 'error';
        this.setState(state);
      })
    } else {
       if (serverError) {
        state[name] = 'error';
      }
      if (serverSuccess) {
        state[name] = 'success';
      }
    }

    this.setState(state);
    return state;
  }

  /**
   * Check field access, if no access property then return true
   * Otherwise it should be an object with functions keyed on edit or new
   * @param {Object} field To render
   * @return {Bool} Can access field
   */
  access(field: FormField): boolean {
    const mode = this.state.data.id === '' ? 'new' : 'edit';

    if (!field.access) {
      return true;
    }

    if (field.access[mode]) {
      return field.access[mode](field, this.state.data);
    }

    return true;
  }

  /**
   * Update the form's state
   * @param {String} name Field name
   * @param {String|number} value Field value
   */
  handleChange(name: string, value: string | number) {
    const {formUpdate, config} = this.props,
      field = this.fields[name];
    this.fields[name].pristine = false;
    if (typeof formUpdate === 'function') {
      formUpdate(config.view, field, name, value);
    }
    let data = this.state.data;
    data[name] = value;
    this.setState({data});

    if (field.onChange) {
      field.onChange(this);
    }
  }

  /**
   * Get the form's layout
   * @return {Dom} Dom node
   */
  formLayout() {
    const {layout} = this.props;
    if (typeof layout === 'function') {
      return layout;
    }
    let layoutName = layout && layout[0].toUpperCase() + layout.slice(1);
    return layouts[layoutName] ? layouts[layoutName] : layouts.Default;
  }

  /**
   * Handle field blur - check validation state
   */
  handleBlur(name: string) {
    this.fields[name].pristine = false;
    let state = this.getValidationState(name);
  }

  /**
   * Buid the react class for the field
   * @param {Object} field Field
   * @return {Element}
   */
  getReactField(field: FormField): Element<*> | null {
    let FieldComponent = null,
      type;
    if (typeof field === 'function') {
      FieldComponent = field;
    } else {
      switch (typeof field.type) {
      case 'string':
        // Ucase first the name
        type = field.type && field.type[0].toUpperCase()
          + field.type.slice(1);
        if (fields[type]) {
           FieldComponent = fields[type];
        }
        break;
      case 'function':
        FieldComponent = field.type;
        break;
      }
    }

    return FieldComponent;
  }
  /**
   * Build a field
   * @param {String} name Field name
   * @param {Object} field Field
   * @return {Node} FormGroup - field, help and label
   */
  makeField(name: string, field: FormField): Element<any> | null {
    let {errors} = this.state,
      error = errors[name] || [],
      FormGroup = lib.FormGroup,
      FieldComponent = this.getReactField(field);

    return <FormGroup
      key={`field-formgroup-${name}`}
      errors={error}
      FieldComponent={FieldComponent}
      field={field}
      name={name}
      row={this.state.data}
      onBlur={this.handleBlur}
      onChange={(name, value) => this.handleChange(name, value)}
      value={this.state.data[name] || field.value || ''}
      validationState={this.state.state[name]} />
  }

  /**
   * Render
   * @return {Node} Dom node
   */
  render(): React$Element<any> {
    const {errors} = this.props,
      FormActions = lib.FormActions,
      buttons = <FormActions
                  actions={this.actions}
                  onSubmit={e => {
                    e.preventDefault();
                    this.onSubmit(e, this.state.data)}
                  }/>,
      FormLayout = this.formLayout();

    let fields = {};

    Object.keys(this.fields)
      .filter(name => this.access(this.fields[name]))
      .forEach(name => {
        let field = this.fields[name];
        fields[name] = this.makeField(name, field);
    });

    return (<FormLayout
              actions={buttons}
              errors={errors}
              fields={fields}
              form={this.state.form}
              onSubmit={this.onSubmit} />);
  }
}

export default UiForm;
<|endoftext|>