<commit_before>import React from "react";
import { Panel } from "react-bootstrap";
import { transform } from "lodash-es";
import { ListGroupItem, Icon, Identicon, Flex, FlexItem } from "../../../base";

const MemberEntry = ({ onEdit, onRemove, onToggleSelect, add, id, identicon, permissions, isSelected }) => (

        <ListGroupItem key={id} onClick={() => onToggleSelect(id)}>
            <Flex alignItems="center">
                {identicon ? <Identicon size={32} hash={identicon} /> : null}
                <FlexItem pad={10}>
                    {id}
                </FlexItem>
                <FlexItem grow={1} shrink={1}>
                    {onRemove
                        ? (
                            <Icon
                                name="trash"
                                bsStyle="danger"
                                tip="Remove Member"
                                pullRight
                                onClick={() => onRemove(id)}
                            />)
                        : null}
                    {add
                        ? (
                            <Icon
                                name="check"
                                bsStyle="success"
                                tip="Selected Member"
                                pullRight
                            />)
                        : null}
                </FlexItem>
            </Flex>
        </ListGroupItem>
        {isSelected
            ? (
                <Panel style={{margin: "0"}}>
                    <Panel.Body>
                        Permissions
                        {transform(permissions, (result, value, key) => {
                            result.push(
                                <ListGroupItem
                                    key={key}
                                    onClick={() => onEdit(id, key, !value)}
                                    bsStyle={value ? "success" : "danger"}
                                >
                                    {key}
                                    <Icon faStyle="far" name={value ? "check-square" : "square"} pullRight />
                                </ListGroupItem>
                            );
                            return result;
                        }, [])}
                    </Panel.Body>
                </Panel>
            )
            : null}

);

export default MemberEntry;
<commit_msg>Fix browser issue #1061 for firefox html onClick on button children <commit_after>import React from "react";
import { Panel } from "react-bootstrap";
import { transform } from "lodash-es";
import { ListGroupItem, Icon, Identicon, Flex, FlexItem } from "../../../base";

const MemberEntry = ({ onEdit, onRemove, onToggleSelect, add, id, identicon, permissions, isSelected }) => (

 onToggleSelect(id)}>
            <Flex alignItems="center">
                {identicon ? <Identicon size={32} hash={identicon} /> : null}
                <FlexItem pad={10}>
                    {id}
                </FlexItem>
                <FlexItem grow={1} shrink={1}>
                    {onRemove
                        ? (
                            <Icon
                                name="trash"
                                bsStyle="danger"
                                tip="Remove Member"
                                pullRight
                                onClick={() => onRemove(id)}
                            />)
                        : null}
                    {add
                        ? (
                            <Icon
                                name="check"
                                bsStyle="success"
                                tip="Selected Member"
                                pullRight
                            />)
                        : null}
                </FlexItem>
            </Flex>

        {isSelected
            ? (
                <Panel style={{margin: "0"}}>
                    <Panel.Body>
                        Permissions
                        {transform(permissions, (result, value, key) => {
                            result.push(
                                <ListGroupItem
                                    key={key}
                                    onClick={() => onEdit(id, key, !value)}
                                    bsStyle={value ? "success" : "danger"}
                                >
                                    {key}
                                    <Icon faStyle="far" name={value ? "check-square" : "square"} pullRight />
                                </ListGroupItem>
                            );
                            return result;
                        }, [])}
                    </Panel.Body>
                </Panel>
            )
            : null}

);

export default MemberEntry;
<|endoftext|>


<commit_before>(function() {
	"use strict";

	angular
		.module("app.matchday")
		.controller("List-Matchday", ListMatchday);

	function ListMatchday(initData, $scope, $rootScope) {
		$rootScope.$broadcast("state-btn", "list-matchday");
		$rootScope.$broadcast("show-phase-nav", true);

		var vm = this;
		var allMatch = [];
		vm.model = null;

		vm.subaAtionDiv = [];
		vm.subaAtionDiv[0] = true;
		vm.subaAtionDiv[1] = false;
		vm.subaAtionDiv[2] = false;

		vm.ratings = [];
		var maxRating = 5;
		vm.showInfoRating = false;

		$scope.$on("vm.model", modelChangeListener);

		vm.preUpdateRating = preUpdateRating;
		vm.preUpdateComment = preUpdateComment;
		vm.preUpdateVoting = preUpdateVoting;
		vm.mouseOverRating = mouseOverRating;
		vm.submitRating = submitRating;

		activate();
		function activate() {
			vm.model = initData.matchdayModelView.model;
			var i = 0;
			_.each(vm.model, function(m) {
				_.each(m, function(match) {
					match.showActionDiv = false;

					allMatch.push(match);
				});
			});
		}

		function submitRating(index) {
			vm.showInfoRating = false;
			console.log("submitRating : ", index);
			vm.showInfoRating = true;
		}

		function mouseOverRating(index) {
			_.each(vm.ratings, function(r) {
				r.isEmpty = true;
				if (r.index <= index) {
					r.isEmpty = false;
				}
			});
		}

		function preUpdateVoting(match) {
			toggleActionDiv(match);
			toggleSubcActionDiv(match, 2);
		}

		function preUpdateComment(match) {
			toggleActionDiv(match);
			toggleSubcActionDiv(match, 1);
		}

		function preUpdateRating(match) {
			toggleActionDiv(match);
			toggleSubcActionDiv(match, 0);
			vm.showInfoRating = false;
			initRating();
		}

		function initRating() {
			for(var i = 0; i < maxRating; i++) {
				vm.ratings[i] = {index:i, isEmpty:true}
			}
		}

		function toggleActionDiv(match) {
			_.each(allMatch, function(m) {
				m.showActionDiv = false;
			});
			match.showActionDiv = !match.showActionDiv;
		}

		function toggleSubcActionDiv(match, activeIndex) {
			for(var i in vm.subaAtionDiv) {
				vm.subaAtionDiv[i] = false;
			}
			vm.subaAtionDiv[activeIndex] = true;
		}

		function modelChangeListener(event, model) {
			vm.model = model;
		}
	}

})();
<commit_msg>Fix bug toggle action div element on matchday page<commit_after>(function() {
	"use strict";

	angular
		.module("app.matchday")
		.controller("List-Matchday", ListMatchday);

	function ListMatchday(initData, $scope, $rootScope) {
		$rootScope.$broadcast("state-btn", "list-matchday");
		$rootScope.$broadcast("show-phase-nav", true);

		var vm = this;
		var allMatch = [];
		vm.model = null;

		vm.subaAtionDiv = [];

		vm.ratings = [];
		var maxRating = 5;
		vm.showInfoRating = false;

		$scope.$on("vm.model", modelChangeListener);

		vm.preUpdateRating = preUpdateRating;
		vm.preUpdateComment = preUpdateComment;
		vm.preUpdateVoting = preUpdateVoting;
		vm.mouseOverRating = mouseOverRating;
		vm.submitRating = submitRating;

		activate();
		function activate() {
			vm.model = initData.matchdayModelView.model;
			modifyEachMatch();
		}

		function submitRating(index) {
			vm.showInfoRating = false;
			console.log("submitRating : ", index);
			vm.showInfoRating = true;
		}

		function mouseOverRating(index) {
			_.each(vm.ratings, function(r) {
				r.isEmpty = true;
				if (r.index <= index) {
					r.isEmpty = false;
				}
			});
		}

		function preUpdateVoting(match) {
			toggleActionDiv(match);
			toggleSubcActionDiv(match, 2);
		}

		function preUpdateComment(match) {
			toggleActionDiv(match);
			toggleSubcActionDiv(match, 1);
		}

		function preUpdateRating(match) {
			toggleActionDiv(match);
			toggleSubcActionDiv(match, 0);
			vm.showInfoRating = false;
			initRating();
		}

		function initRating() {
			for(var i = 0; i < maxRating; i++) {
				vm.ratings[i] = {index:i, isEmpty:true}
			}
		}

		function toggleActionDiv(match) {
			_.each(allMatch, function(m) {
				m.showActionDiv = false;
			});
			match.showActionDiv = true;
		}

		function toggleSubcActionDiv(match, activeIndex) {
			for(var i in vm.subaAtionDiv) {
				vm.subaAtionDiv[i] = false;
			}
			vm.subaAtionDiv[activeIndex] = true;
		}

		function modelChangeListener(event, model) {
			vm.model = model;
			modifyEachMatch();
		}

		function modifyEachMatch() {
			var i = 0;
			allMatch = [];
			_.each(vm.model, function(m) {
				_.each(m, function(match) {
					match.showActionDiv = false;

					allMatch[i] = match;
					i++;
				});
			});
			vm.subaAtionDiv[0] = true;
			vm.subaAtionDiv[1] = false;
			vm.subaAtionDiv[2] = false;
		}

	}
})();
<|endoftext|>


<commit_before>import { noop, is, check, remove, deferred, autoInc, asap, TASK } from './utils'
import { as, matcher } from './io'
import * as monitorActions from './monitorActions'

export const NOT_ITERATOR_ERROR = 'proc first argument (Saga function result) must be an iterator'
export const PARALLEL_AUTO_CANCEL = 'PARALLEL_AUTO_CANCEL'
export const RACE_AUTO_CANCEL = 'RACE_AUTO_CANCEL'
export const MANUAL_CANCEL = 'MANUAL_CANCEL'

const nextEffectId = autoInc()

export const CANCEL = Symbol('@@redux-saga/cancelPromise')

export class SagaCancellationException {
  constructor(type, saga, origin) {
    this.type = type
    this.saga = saga
    this.origin = origin
  }
}

export default function proc(
  iterator,
  subscribe = () => noop,
  dispatch = noop,
  monitor = noop,
  parentEffectId = 0,
  name = 'anonymous'
) {

  check(iterator, is.iterator, NOT_ITERATOR_ERROR)

  const deferredInputs = []
  const canThrow = is.throw(iterator)
  const deferredEnd = deferred()

  const unsubscribe = subscribe(input => {
   deferredInputs.forEach( def => {
     if(def.match(input))
       def.resolve(input)
   })
 })

  iterator._isRunning = true
  next()

  return newTask(
    parentEffectId, name, iterator, deferredEnd.promise
  )

  function next(arg, isError) {
    if(!iterator._isRunning)
      return
    try {
      if(isError && !canThrow)
        throw arg
      const result = isError ? iterator.throw(arg) : iterator.next(arg)
      if(!result.done) {
        const currentEffect = runEffect(result.value, parentEffectId)
        deferredEnd.promise[CANCEL] = currentEffect[CANCEL]
        currentEffect.then(next, err => next(err, true))
      } else {
        end(result.value)
      }
    } catch(error) {
      /*eslint-disable no-console*/
      console.warn(`${name}: uncaught`, error )
      end(error, true)
    }
  }

  function end(result, isError) {
    iterator._isRunning = false
    if(!isError) {
      iterator._result = result
      deferredEnd.resolve(result)
    } else {
      iterator._error = result
      deferredEnd.reject(result)
    }
    unsubscribe()
  }

  function runEffect(effect, parentEffectId, label = '') {
    const effectId = nextEffectId()
    monitor( monitorActions.effectTriggered(effectId, parentEffectId, label, effect) )

    let data
    const promise = (
        is.array(effect)           ? runParallelEffect(effect, effectId)
      : is.iterator(effect)        ? proc(effect, subscribe, dispatch, monitor, effectId).done

      : (data = as.take(effect))   ? runTakeEffect(data)
      : (data = as.put(effect))    ? runPutEffect(data)
      : (data = as.race(effect))   ? runRaceEffect(data, effectId)
      : (data = as.call(effect))   ? runCallEffect(data, effectId)
      : (data = as.cps(effect))    ? runCPSEffect(data)
      : (data = as.fork(effect))   ? runForkEffect(data, effectId)
      : (data = as.join(effect))   ? runJoinEffect(data)
      : (data = as.cancel(effect)) ? runCancelEffect(data)

      : /* resolve anything else  */ Promise.resolve(effect)
    )

    const def = deferred()
    let isRunning = true
    const completeWith = fn => outcome => {
      if(isRunning) {
        isRunning = false
        fn(outcome)
      }
    }
    promise.then(completeWith(def.resolve), completeWith(def.reject))
    def.promise[CANCEL] = ({type, origin}) => {
      if(isRunning) {
        isRunning = false
        const error = new SagaCancellationException(type, name, origin)
        cancelPromise(promise, error)
        def.reject(error)
      }

    }

    def.promise.then(
      result => monitor( monitorActions.effectResolved(effectId, result) ),
      error  => monitor( monitorActions.effectRejected(effectId, error) )
    )
    return def.promise
  }

  function runTakeEffect(pattern) {
    const def = deferred({ match : matcher(pattern), pattern })
    deferredInputs.push(def)
    const done = () => remove(deferredInputs, def)
    def.promise.then(done, done)
    def.promise[CANCEL] = done
    return def.promise
  }

  function runPutEffect(action) {
    return asap(() => dispatch(action) )
  }

  function runCallEffect({context, fn, args}, effectId) {
    const result = fn.apply(context, args)
    return !is.iterator(result)
      ? Promise.resolve(result)
      : proc(result, subscribe, dispatch, monitor, effectId, fn.name).done
  }

  function runCPSEffect({context, fn, args}) {
    return new Promise((resolve, reject) => {
      fn.apply(context, args.concat(
        (err, res) => is.undef(err) ? resolve(res) : reject(err)
      ))
    })
  }

  function runForkEffect({context, fn, args}, effectId) {
    let result, _iterator

    // we run the function, next we'll check if this is a generator function
    // (generator is a function that returns an iterator)
    result = fn.apply(context, args)

    // A generator function: i.e. returns an iterator
    if( is.iterator(result) ) {
      _iterator = result
    }

    //simple effect: wrap in a generator
    else {
      _iterator = function*() {
        return (yield result)
      }()
    }

    return Promise.resolve(
      proc(_iterator, subscribe, dispatch, monitor, effectId, fn.name, true)
    )
  }

  function runJoinEffect(task) {
    return task.done
  }

  function runCancelEffect(task) {
    task.done[CANCEL](
      new SagaCancellationException(MANUAL_CANCEL, '', name)
    )
    return Promise.resolve()
  }

  function runParallelEffect(effects, effectId) {
    const promises = effects.map(eff => runEffect(eff, effectId))
    const ret = Promise.all(promises)
    ret[CANCEL] = error => {
      promises.forEach(p => cancelPromise(p, error))
    }

    ret.catch(() => {
      ret[CANCEL](
        new SagaCancellationException(PARALLEL_AUTO_CANCEL, name, name)
      )
    })
    return ret
  }

  function runRaceEffect(effects, effectId) {
    const promises = []
    const retP = Promise.race(
      Object.keys(effects)
        .map(key => {
          const promise = runEffect(effects[key], effectId, key)
          promises.push(promise)
          return promise.then(
            result => ({[key]: result}),
            error => Promise.reject({[key]: error})
          )
        })
    )

    retP[CANCEL] = error => {
      promises.forEach(p => cancelPromise(p, error))
    }

    const done = () => retP[CANCEL](
      new SagaCancellationException(RACE_AUTO_CANCEL, name, name)
    )
    retP.then(done, done)
    return retP
  }

  function newTask(id, name, iterator, done, forked) {
    return {
      [TASK]: true,
      id,
      name,
      done,
      forked,
      isRunning: () => iterator._isRunning,
      getResult: () => iterator._result,
      getError: () => iterator._error
    }
  }

  function cancelPromise(promise, error) {
    if(promise[CANCEL])
      promise[CANCEL](error)
  }
}
<commit_msg>Fix effect type value of 0 not running effect.<commit_after>import { noop, is, check, remove, deferred, autoInc, asap, TASK } from './utils'
import { as, matcher } from './io'
import * as monitorActions from './monitorActions'

export const NOT_ITERATOR_ERROR = 'proc first argument (Saga function result) must be an iterator'
export const PARALLEL_AUTO_CANCEL = 'PARALLEL_AUTO_CANCEL'
export const RACE_AUTO_CANCEL = 'RACE_AUTO_CANCEL'
export const MANUAL_CANCEL = 'MANUAL_CANCEL'

const nextEffectId = autoInc()

export const CANCEL = Symbol('@@redux-saga/cancelPromise')

export class SagaCancellationException {
  constructor(type, saga, origin) {
    this.type = type
    this.saga = saga
    this.origin = origin
  }
}

export default function proc(
  iterator,
  subscribe = () => noop,
  dispatch = noop,
  monitor = noop,
  parentEffectId = 0,
  name = 'anonymous'
) {

  check(iterator, is.iterator, NOT_ITERATOR_ERROR)

  const deferredInputs = []
  const canThrow = is.throw(iterator)
  const deferredEnd = deferred()

  const unsubscribe = subscribe(input => {
   deferredInputs.forEach( def => {
     if(def.match(input))
       def.resolve(input)
   })
 })

  iterator._isRunning = true
  next()

  return newTask(
    parentEffectId, name, iterator, deferredEnd.promise
  )

  function next(arg, isError) {
    if(!iterator._isRunning)
      return
    try {
      if(isError && !canThrow)
        throw arg
      const result = isError ? iterator.throw(arg) : iterator.next(arg)
      if(!result.done) {
        const currentEffect = runEffect(result.value, parentEffectId)
        deferredEnd.promise[CANCEL] = currentEffect[CANCEL]
        currentEffect.then(next, err => next(err, true))
      } else {
        end(result.value)
      }
    } catch(error) {
      /*eslint-disable no-console*/
      console.warn(`${name}: uncaught`, error )
      end(error, true)
    }
  }

  function end(result, isError) {
    iterator._isRunning = false
    if(!isError) {
      iterator._result = result
      deferredEnd.resolve(result)
    } else {
      iterator._error = result
      deferredEnd.reject(result)
    }
    unsubscribe()
  }

  function runEffect(effect, parentEffectId, label = '') {
    const effectId = nextEffectId()
    monitor( monitorActions.effectTriggered(effectId, parentEffectId, label, effect) )

    let data
    const promise = (
        is.array(effect)           ? runParallelEffect(effect, effectId)
      : is.iterator(effect)        ? proc(effect, subscribe, dispatch, monitor, effectId).done

      : (is.notUndef(data = as.take(effect)))   ? runTakeEffect(data)
      : (is.notUndef(data = as.put(effect)))    ? runPutEffect(data)
      : (is.notUndef(data = as.race(effect)))   ? runRaceEffect(data, effectId)
      : (is.notUndef(data = as.call(effect)))   ? runCallEffect(data, effectId)
      : (is.notUndef(data = as.cps(effect)))    ? runCPSEffect(data)
      : (is.notUndef(data = as.fork(effect)))   ? runForkEffect(data, effectId)
      : (is.notUndef(data = as.join(effect)))   ? runJoinEffect(data)
      : (is.notUndef(data = as.cancel(effect))) ? runCancelEffect(data)

      : /* resolve anything else  */ Promise.resolve(effect)
    )

    const def = deferred()
    let isRunning = true
    const completeWith = fn => outcome => {
      if(isRunning) {
        isRunning = false
        fn(outcome)
      }
    }
    promise.then(completeWith(def.resolve), completeWith(def.reject))
    def.promise[CANCEL] = ({type, origin}) => {
      if(isRunning) {
        isRunning = false
        const error = new SagaCancellationException(type, name, origin)
        cancelPromise(promise, error)
        def.reject(error)
      }

    }

    def.promise.then(
      result => monitor( monitorActions.effectResolved(effectId, result) ),
      error  => monitor( monitorActions.effectRejected(effectId, error) )
    )
    return def.promise
  }

  function runTakeEffect(pattern) {
    const def = deferred({ match : matcher(pattern), pattern })
    deferredInputs.push(def)
    const done = () => remove(deferredInputs, def)
    def.promise.then(done, done)
    def.promise[CANCEL] = done
    return def.promise
  }

  function runPutEffect(action) {
    return asap(() => dispatch(action) )
  }

  function runCallEffect({context, fn, args}, effectId) {
    const result = fn.apply(context, args)
    return !is.iterator(result)
      ? Promise.resolve(result)
      : proc(result, subscribe, dispatch, monitor, effectId, fn.name).done
  }

  function runCPSEffect({context, fn, args}) {
    return new Promise((resolve, reject) => {
      fn.apply(context, args.concat(
        (err, res) => is.undef(err) ? resolve(res) : reject(err)
      ))
    })
  }

  function runForkEffect({context, fn, args}, effectId) {
    let result, _iterator

    // we run the function, next we'll check if this is a generator function
    // (generator is a function that returns an iterator)
    result = fn.apply(context, args)

    // A generator function: i.e. returns an iterator
    if( is.iterator(result) ) {
      _iterator = result
    }

    //simple effect: wrap in a generator
    else {
      _iterator = function*() {
        return (yield result)
      }()
    }

    return Promise.resolve(
      proc(_iterator, subscribe, dispatch, monitor, effectId, fn.name, true)
    )
  }

  function runJoinEffect(task) {
    return task.done
  }

  function runCancelEffect(task) {
    task.done[CANCEL](
      new SagaCancellationException(MANUAL_CANCEL, '', name)
    )
    return Promise.resolve()
  }

  function runParallelEffect(effects, effectId) {
    const promises = effects.map(eff => runEffect(eff, effectId))
    const ret = Promise.all(promises)
    ret[CANCEL] = error => {
      promises.forEach(p => cancelPromise(p, error))
    }

    ret.catch(() => {
      ret[CANCEL](
        new SagaCancellationException(PARALLEL_AUTO_CANCEL, name, name)
      )
    })
    return ret
  }

  function runRaceEffect(effects, effectId) {
    const promises = []
    const retP = Promise.race(
      Object.keys(effects)
        .map(key => {
          const promise = runEffect(effects[key], effectId, key)
          promises.push(promise)
          return promise.then(
            result => ({[key]: result}),
            error => Promise.reject({[key]: error})
          )
        })
    )

    retP[CANCEL] = error => {
      promises.forEach(p => cancelPromise(p, error))
    }

    const done = () => retP[CANCEL](
      new SagaCancellationException(RACE_AUTO_CANCEL, name, name)
    )
    retP.then(done, done)
    return retP
  }

  function newTask(id, name, iterator, done, forked) {
    return {
      [TASK]: true,
      id,
      name,
      done,
      forked,
      isRunning: () => iterator._isRunning,
      getResult: () => iterator._result,
      getError: () => iterator._error
    }
  }

  function cancelPromise(promise, error) {
    if(promise[CANCEL])
      promise[CANCEL](error)
  }
}
<|endoftext|>


<commit_before>import fse from 'fs-extra';
import path from 'path';
import { Error } from '../constants';
import { spawnShell, winSpawn } from '../utils/spawnHelper';
import exec from '../utils/execHelper';

const IS_WINDOWS = process.platform === 'win32';
const ticks = IS_WINDOWS ? '"' : '\'';

const parseSize = (ptr) => {
  const idx = ptr.indexOf('size ') + 5;
  return Number(ptr.substring(idx).trim());
};

export default (crednetialsCallback) => {
  const clean = (to, from, source) => {
    const workdir = source.repo().workdir();
    const filePath = path.join(workdir, source.path());
    const command = `git lfs clean ${ticks}${source.path()}${ticks}`;

    return fse.readFile(filePath)
      .then(buf => exec(command, buf, { cwd: workdir }))
      .then(({ stdout }) => {
        const sha = new Buffer(stdout);
        return to.set(sha, sha.length).then(() => Error.CODE.OK);
      });
  };

  const smudge = (to, from, source) => {
    const workdir = source.repo().workdir();
    const parts = source.path().split('/');
    const filepath = parts[parts.length - 1];
    const ptr = from.ptr();
    const size = parseSize(ptr);
    const echo = IS_WINDOWS ? `echo|set /p="${ptr}"` : `echo -ne "${ptr}"`;

    const promise = IS_WINDOWS
      ? winSpawn(`git lfs smudge ${ticks}${filepath}${ticks}`, ptr, { cwd: workdir })
      : spawnShell(
        `${echo} | git lfs smudge ${ticks}${filepath}${ticks}`,
        { cwd: workdir },
        size,
        crednetialsCallback
      );

    return promise
      .then(({ stdout }) => to.set(stdout, stdout.length)
        .then(() => Error.CODE.OK));
  };

  let previousFilterPromise = Promise.resolve();

  return (to, from, source) => {
    const mode = source.mode();

    const runNextFilter = () => Promise.resolve()
      .then(() => {
        if (mode === 1) {
          return clean(to, from, source);
        }
        return smudge(to, from, source);
      })
      .then(
        () => Error.CODE.OK,
        () => Error.CODE.PASSTHROUGH
      );

    previousFilterPromise = previousFilterPromise
      .then(runNextFilter, runNextFilter);

    return previousFilterPromise;
  };
};
<commit_msg>Update uses of Buf.prototype.set to work with sync or async result<commit_after>import fse from 'fs-extra';
import path from 'path';
import { Error } from '../constants';
import { spawnShell, winSpawn } from '../utils/spawnHelper';
import exec from '../utils/execHelper';

const IS_WINDOWS = process.platform === 'win32';
const ticks = IS_WINDOWS ? '"' : '\'';

const parseSize = (ptr) => {
  const idx = ptr.indexOf('size ') + 5;
  return Number(ptr.substring(idx).trim());
};

export default (credentialsCallback) => {
  const clean = (to, from, source) => {
    const workdir = source.repo().workdir();
    const filePath = path.join(workdir, source.path());
    const command = `git lfs clean ${ticks}${source.path()}${ticks}`;

    return fse.readFile(filePath)
      .then(buf => exec(command, buf, { cwd: workdir }))
      .then(({ stdout }) => {
        const sha = new Buffer(stdout);
        return to.set(sha, sha.length);
      })
      .then(() => Error.CODE.OK);
  };

  const smudge = (to, from, source) => {
    const workdir = source.repo().workdir();
    const parts = source.path().split('/');
    const filepath = parts[parts.length - 1];
    const ptr = from.ptr();
    const size = parseSize(ptr);
    const echo = IS_WINDOWS ? `echo|set /p="${ptr}"` : `echo -ne "${ptr}"`;

    const promise = IS_WINDOWS
      ? winSpawn(`git lfs smudge ${ticks}${filepath}${ticks}`, ptr, { cwd: workdir })
      : spawnShell(
        `${echo} | git lfs smudge ${ticks}${filepath}${ticks}`,
        { cwd: workdir },
        size,
        credentialsCallback
      );

    return promise
      .then(({ stdout }) => to.set(stdout, stdout.length))
      .then(() => Error.CODE.OK);
  };

  let previousFilterPromise = Promise.resolve();

  return (to, from, source) => {
    const mode = source.mode();

    const runNextFilter = () => Promise.resolve()
      .then(() => {
        if (mode === 1) {
          return clean(to, from, source);
        }
        return smudge(to, from, source);
      })
      .then(
        () => Error.CODE.OK,
        () => Error.CODE.PASSTHROUGH
      );

    previousFilterPromise = previousFilterPromise
      .then(runNextFilter, runNextFilter);

    return previousFilterPromise;
  };
};
<|endoftext|>


<commit_before>/**
 * @fileOverview Brush
 */
import React, { Component, Children } from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';
import { scalePoint } from 'd3-scale';
import _ from 'lodash';
import { getValueByDataKey } from '../util/ChartUtils';
import pureRender from '../util/PureRender';
import Layer from '../container/Layer';
import Text from '../component/Text';
import { isNumber } from '../util/DataUtils';
import { generatePrefixStyle } from '../util/CssPrefixUtils';

@pureRender
class Brush extends Component {

  static displayName = 'Brush';

  static propTypes = {
    className: PropTypes.string,

    fill: PropTypes.string,
    stroke: PropTypes.string,
    x: PropTypes.number,
    y: PropTypes.number,
    width: PropTypes.number,
    height: PropTypes.number.isRequired,
    travellerWidth: PropTypes.number,
    gap: PropTypes.number,
    padding: PropTypes.shape({
      top: PropTypes.number,
      right: PropTypes.number,
      bottom: PropTypes.number,
      left: PropTypes.number,
    }),

    dataKey: PropTypes.oneOfType([PropTypes.string, PropTypes.number, PropTypes.func]),
    data: PropTypes.array,
    startIndex: PropTypes.number,
    endIndex: PropTypes.number,
    tickFormatter: PropTypes.func,

    children: PropTypes.node,

    onChange: PropTypes.func,
    updateId: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
  };

  static defaultProps = {
    height: 40,
    travellerWidth: 5,
    gap: 1,
    fill: '#fff',
    stroke: '#666',
    padding: { top: 1, right: 1, bottom: 1, left: 1 },
  };

  constructor(props) {
    super(props);

    this.travellerDragStartHandlers = {
      startX: this.handleTravellerDragStart.bind(this, 'startX'),
      endX: this.handleTravellerDragStart.bind(this, 'endX'),
    };

    this.state = props.data && props.data.length ? this.updateScale(props) : {};
  }

  componentWillReceiveProps(nextProps) {
    const { data, width, x, travellerWidth, updateId } = this.props;

    if (
      (nextProps.data !== data || nextProps.updateId !== updateId) &&
      nextProps.data &&
      nextProps.data.length
    ) {
      this.setState(this.updateScale(nextProps));
    } else if (
      nextProps.width !== width ||
      nextProps.x !== x ||
      nextProps.travellerWidth !== travellerWidth
    ) {
      this.scale.range([nextProps.x, nextProps.x + nextProps.width - nextProps.travellerWidth]);
      this.scaleValues = this.scale.domain().map(entry => this.scale(entry));

      this.setState({
        startX: this.scale(nextProps.startIndex),
        endX: this.scale(nextProps.endIndex),
      });
    }
  }

  componentWillUnmount() {
    this.scale = null;
    this.scaleValues = null;

    if (this.leaveTimer) {
      clearTimeout(this.leaveTimer);
      this.leaveTimer = null;
    }
  }

  static getIndexInRange(range, x) {
    const len = range.length;
    let start = 0;
    let end = len - 1;

    while (end - start > 1) {
      const middle = Math.floor((start + end) / 2);

      if (range[middle] > x) {
        end = middle;
      } else {
        start = middle;
      }
    }

    return x >= range[end] ? end : start;
  }

  getIndex({ startX, endX }) {
    const { gap, data } = this.props;
    const lastIndex = data.length - 1;
    const min = Math.min(startX, endX);
    const max = Math.max(startX, endX);
    const minIndex = this.constructor.getIndexInRange(this.scaleValues, min);
    const maxIndex = this.constructor.getIndexInRange(this.scaleValues, max);
    return {
      startIndex: minIndex - minIndex % gap,
      endIndex: maxIndex === lastIndex ? lastIndex : maxIndex - maxIndex % gap,
    };
  }

  getTextOfTick(index) {
    const { data, tickFormatter, dataKey } = this.props;
    const text = getValueByDataKey(data[index], dataKey, index);

    return _.isFunction(tickFormatter) ? tickFormatter(text) : text;
  }

  handleDrag = (e) => {
    if (this.leaveTimer) {
      clearTimeout(this.leaveTimer);
      this.leaveTimer = null;
    }

    if (this.state.isTravellerMoving) {
      this.handleTravellerMove(e);
    } else if (this.state.isSlideMoving) {
      this.handleSlideDrag(e);
    }
  };

  handleTouchMove = (e) => {
    if (e.changedTouches != null && e.changedTouches.length > 0) {
      this.handleDrag(e.changedTouches[0]);
    }
  };

  handleDragEnd = () => {
    this.setState({
      isTravellerMoving: false,
      isSlideMoving: false,
    });
  };

  handleLeaveWrapper = () => {
    if (this.state.isTravellerMoving || this.state.isSlideMoving) {
      this.leaveTimer = setTimeout(this.handleDragEnd, 1000);
    }
  };

  handleEnterSlideOrTraveller = () => {
    this.setState({
      isTextActive: true,
    });
  };

  handleLeaveSlideOrTraveller = () => {
    this.setState({
      isTextActive: false,
    });
  };

  handleSlideDragStart = (e) => {
    const event = e.changedTouches && e.changedTouches.length ? e.changedTouches[0] : e;

    this.setState({
      isTravellerMoving: false,
      isSlideMoving: true,
      slideMoveStartX: event.pageX,
    });
  };

  handleSlideDrag(e) {
    const { slideMoveStartX, startX, endX } = this.state;
    const { x, width, travellerWidth, startIndex, endIndex, onChange } = this.props;
    let delta = e.pageX - slideMoveStartX;

    if (delta > 0) {
      delta = Math.min(
        delta,
        x + width - travellerWidth - endX,
        x + width - travellerWidth - startX
      );
    } else if (delta < 0) {
      delta = Math.max(delta, x - startX, x - endX);
    }
    const newIndex = this.getIndex({
      startX: startX + delta,
      endX: endX + delta,
    });

    if ((newIndex.startIndex !== startIndex || newIndex.endIndex !== endIndex) && onChange) {
      onChange(newIndex);
    }

    this.setState({
      startX: startX + delta,
      endX: endX + delta,
      slideMoveStartX: e.pageX,
    });
  }

  handleTravellerDragStart(id, e) {
    const event = e.changedTouches && e.changedTouches.length ? e.changedTouches[0] : e;

    this.setState({
      isSlideMoving: false,
      isTravellerMoving: true,
      movingTravellerId: id,
      brushMoveStartX: event.pageX,
    });
  }

  handleTravellerMove(e) {
    const { brushMoveStartX, movingTravellerId, endX, startX } = this.state;
    const prevValue = this.state[movingTravellerId];

    const { x, width, travellerWidth, onChange, gap, data } = this.props;
    const params = { startX: this.state.startX, endX: this.state.endX };

    let delta = e.pageX - brushMoveStartX;
    if (delta > 0) {
      delta = Math.min(delta, x + width - travellerWidth - prevValue);
    } else if (delta < 0) {
      delta = Math.max(delta, x - prevValue);
    }

    params[movingTravellerId] = prevValue + delta;

    const newIndex = this.getIndex(params);
    const { startIndex, endIndex } = newIndex;
    const isFullGap = () => {
      const lastIndex = data.length - 1;
      if ((movingTravellerId === 'startX' &&
        (endX > startX ? startIndex % gap === 0 : endIndex % gap === 0)) ||
        (endX < startX && endIndex === lastIndex) ||
      (movingTravellerId === 'endX' &&
        (endX > startX ? endIndex % gap === 0 : startIndex % gap === 0) ||
        (endX > startX && endIndex === lastIndex))) {
        return true;
      }
      return false;
    };

    this.setState({
      [movingTravellerId]: prevValue + delta,
      brushMoveStartX: e.pageX,
    }, () => {
      if (onChange) {
        if (isFullGap()) {
          onChange(newIndex);
        }
      }
    });
  }

  updateScale(props) {
    const { data, startIndex, endIndex, x, width, travellerWidth } = props;
    const len = data.length;
    this.scale = scalePoint()
      .domain(_.range(0, len))
      .range([x, x + width - travellerWidth]);
    this.scaleValues = this.scale.domain().map(entry => this.scale(entry));
    return {
      isTextActive: false,
      isSlideMoving: false,
      isTravellerMoving: false,
      startX: this.scale(startIndex),
      endX: this.scale(endIndex),
    };
  }

  renderBackground() {
    const { x, y, width, height, fill, stroke } = this.props;

    return (
      <rect
        stroke={stroke}
        fill={fill}
        x={x}
        y={y}
        width={width}
        height={height}
      />
    );
  }

  renderPanorama() {
    const { x, y, width, height, data, children, padding } = this.props;
    const chartElement = Children.only(children);

    if (!chartElement) { return null; }

    return React.cloneElement(chartElement, {
      x,
      y,
      width,
      height,
      margin: padding,
      compact: true,
      data,
    });
  }

  renderTraveller(travellerX, id) {
    const { y, travellerWidth, height, stroke } = this.props;
    const lineY = Math.floor(y + height / 2) - 1;
    const x = Math.max(travellerX, this.props.x);

    return (
      <Layer
        className="recharts-brush-traveller"
        onMouseEnter={this.handleEnterSlideOrTraveller}
        onMouseLeave={this.handleLeaveSlideOrTraveller}
        onMouseDown={this.travellerDragStartHandlers[id]}
        onTouchStart={this.travellerDragStartHandlers[id]}
        style={{ cursor: 'col-resize' }}
      >
        <rect
          x={x}
          y={y}
          width={travellerWidth}
          height={height}
          fill={stroke}
          stroke="none"
        />
        <line
          x1={x + 1}
          y1={lineY}
          x2={x + travellerWidth - 1}
          y2={lineY}
          fill="none"
          stroke="#fff"
        />
        <line
          x1={x + 1}
          y1={lineY + 2}
          x2={x + travellerWidth - 1}
          y2={lineY + 2}
          fill="none"
          stroke="#fff"
        />
      </Layer>
    );
  }

  renderSlide(startX, endX) {
    const { y, height, stroke } = this.props;

    return (
      <rect
        className="recharts-brush-slide"
        onMouseEnter={this.handleEnterSlideOrTraveller}
        onMouseLeave={this.handleLeaveSlideOrTraveller}
        onMouseDown={this.handleSlideDragStart}
        onTouchStart={this.handleSlideDragStart}
        style={{ cursor: 'move' }}
        stroke="none"
        fill={stroke}
        fillOpacity={0.2}
        x={Math.min(startX, endX)}
        y={y}
        width={Math.abs(endX - startX)}
        height={height}
      />
    );
  }

  renderText() {
    const { startIndex, endIndex, y, height, travellerWidth,
      stroke } = this.props;
    const { startX, endX } = this.state;
    const offset = 5;
    const attrs = {
      pointerEvents: 'none',
      fill: stroke,
    };

    return (
      <Layer className="recharts-brush-texts">
        <Text
          textAnchor="end"
          verticalAnchor="middle"
          x={Math.min(startX, endX) - offset}
          y={y + height / 2}
          {...attrs}
        >
          {this.getTextOfTick(startIndex)}
        </Text>
        <Text
          textAnchor="start"
          verticalAnchor="middle"
          x={Math.max(startX, endX) + travellerWidth + offset}
          y={y + height / 2}
          {...attrs}
        >
          {this.getTextOfTick(endIndex)}
        </Text>
      </Layer>
    );
  }

  render() {
    const { data, className, children, x, y, width, height } = this.props;
    const { startX, endX, isTextActive, isSlideMoving, isTravellerMoving } = this.state;

    if (!data || !data.length || !isNumber(x) || !isNumber(y) || !isNumber(width) ||
      !isNumber(height) || width <= 0 || height <= 0) { return null; }

    const layerClass = classNames('recharts-brush', className);
    const isPanoramic = React.Children.count(children) === 1;
    const style = generatePrefixStyle('userSelect', 'none');

    return (
      <Layer
        className={layerClass}
        onMouseMove={this.handleDrag}
        onMouseLeave={this.handleLeaveWrapper}
        onMouseUp={this.handleDragEnd}
        onTouchEnd={this.handleDragEnd}
        onTouchMove={this.handleTouchMove}
        style={style}
      >
        {this.renderBackground()}
        {isPanoramic && this.renderPanorama()}
        {this.renderSlide(startX, endX)}
        {this.renderTraveller(startX, 'startX')}
        {this.renderTraveller(endX, 'endX')}
        {(isTextActive || isSlideMoving || isTravellerMoving) && this.renderText()}
      </Layer>
    );
  }
}

export default Brush;
<commit_msg>Make the tiemOut timer for the brush configurable through props<commit_after>/**
 * @fileOverview Brush
 */
import React, { Component, Children } from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';
import { scalePoint } from 'd3-scale';
import _ from 'lodash';
import { getValueByDataKey } from '../util/ChartUtils';
import pureRender from '../util/PureRender';
import Layer from '../container/Layer';
import Text from '../component/Text';
import { isNumber } from '../util/DataUtils';
import { generatePrefixStyle } from '../util/CssPrefixUtils';

@pureRender
class Brush extends Component {

  static displayName = 'Brush';

  static propTypes = {
    className: PropTypes.string,

    fill: PropTypes.string,
    stroke: PropTypes.string,
    x: PropTypes.number,
    y: PropTypes.number,
    width: PropTypes.number,
    height: PropTypes.number.isRequired,
    travellerWidth: PropTypes.number,
    gap: PropTypes.number,
    padding: PropTypes.shape({
      top: PropTypes.number,
      right: PropTypes.number,
      bottom: PropTypes.number,
      left: PropTypes.number,
    }),

    dataKey: PropTypes.oneOfType([PropTypes.string, PropTypes.number, PropTypes.func]),
    data: PropTypes.array,
    startIndex: PropTypes.number,
    endIndex: PropTypes.number,
    tickFormatter: PropTypes.func,

    children: PropTypes.node,

    onChange: PropTypes.func,
    updateId: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
    leaveTimeOut: PropTypes.number,
  };

  static defaultProps = {
    height: 40,
    travellerWidth: 5,
    gap: 1,
    fill: '#fff',
    stroke: '#666',
    padding: { top: 1, right: 1, bottom: 1, left: 1 },
    leaveTimeOut: 1000,
  };

  constructor(props) {
    super(props);

    this.travellerDragStartHandlers = {
      startX: this.handleTravellerDragStart.bind(this, 'startX'),
      endX: this.handleTravellerDragStart.bind(this, 'endX'),
    };

    this.state = props.data && props.data.length ? this.updateScale(props) : {};
  }

  componentWillReceiveProps(nextProps) {
    const { data, width, x, travellerWidth, updateId } = this.props;

    if (
      (nextProps.data !== data || nextProps.updateId !== updateId) &&
      nextProps.data &&
      nextProps.data.length
    ) {
      this.setState(this.updateScale(nextProps));
    } else if (
      nextProps.width !== width ||
      nextProps.x !== x ||
      nextProps.travellerWidth !== travellerWidth
    ) {
      this.scale.range([nextProps.x, nextProps.x + nextProps.width - nextProps.travellerWidth]);
      this.scaleValues = this.scale.domain().map(entry => this.scale(entry));

      this.setState({
        startX: this.scale(nextProps.startIndex),
        endX: this.scale(nextProps.endIndex),
      });
    }
  }

  componentWillUnmount() {
    this.scale = null;
    this.scaleValues = null;

    if (this.leaveTimer) {
      clearTimeout(this.leaveTimer);
      this.leaveTimer = null;
    }
  }

  static getIndexInRange(range, x) {
    const len = range.length;
    let start = 0;
    let end = len - 1;

    while (end - start > 1) {
      const middle = Math.floor((start + end) / 2);

      if (range[middle] > x) {
        end = middle;
      } else {
        start = middle;
      }
    }

    return x >= range[end] ? end : start;
  }

  getIndex({ startX, endX }) {
    const { gap, data } = this.props;
    const lastIndex = data.length - 1;
    const min = Math.min(startX, endX);
    const max = Math.max(startX, endX);
    const minIndex = this.constructor.getIndexInRange(this.scaleValues, min);
    const maxIndex = this.constructor.getIndexInRange(this.scaleValues, max);
    return {
      startIndex: minIndex - minIndex % gap,
      endIndex: maxIndex === lastIndex ? lastIndex : maxIndex - maxIndex % gap,
    };
  }

  getTextOfTick(index) {
    const { data, tickFormatter, dataKey } = this.props;
    const text = getValueByDataKey(data[index], dataKey, index);

    return _.isFunction(tickFormatter) ? tickFormatter(text) : text;
  }

  handleDrag = (e) => {
    if (this.leaveTimer) {
      clearTimeout(this.leaveTimer);
      this.leaveTimer = null;
    }

    if (this.state.isTravellerMoving) {
      this.handleTravellerMove(e);
    } else if (this.state.isSlideMoving) {
      this.handleSlideDrag(e);
    }
  };

  handleTouchMove = (e) => {
    if (e.changedTouches != null && e.changedTouches.length > 0) {
      this.handleDrag(e.changedTouches[0]);
    }
  };

  handleDragEnd = () => {
    this.setState({
      isTravellerMoving: false,
      isSlideMoving: false,
    });
  };

  handleLeaveWrapper = () => {
    if (this.state.isTravellerMoving || this.state.isSlideMoving) {
      this.leaveTimer = setTimeout(this.handleDragEnd, this.props.leaveTimeOut);
    }
  };

  handleEnterSlideOrTraveller = () => {
    this.setState({
      isTextActive: true,
    });
  };

  handleLeaveSlideOrTraveller = () => {
    this.setState({
      isTextActive: false,
    });
  };

  handleSlideDragStart = (e) => {
    const event = e.changedTouches && e.changedTouches.length ? e.changedTouches[0] : e;

    this.setState({
      isTravellerMoving: false,
      isSlideMoving: true,
      slideMoveStartX: event.pageX,
    });
  };

  handleSlideDrag(e) {
    const { slideMoveStartX, startX, endX } = this.state;
    const { x, width, travellerWidth, startIndex, endIndex, onChange } = this.props;
    let delta = e.pageX - slideMoveStartX;

    if (delta > 0) {
      delta = Math.min(
        delta,
        x + width - travellerWidth - endX,
        x + width - travellerWidth - startX
      );
    } else if (delta < 0) {
      delta = Math.max(delta, x - startX, x - endX);
    }
    const newIndex = this.getIndex({
      startX: startX + delta,
      endX: endX + delta,
    });

    if ((newIndex.startIndex !== startIndex || newIndex.endIndex !== endIndex) && onChange) {
      onChange(newIndex);
    }

    this.setState({
      startX: startX + delta,
      endX: endX + delta,
      slideMoveStartX: e.pageX,
    });
  }

  handleTravellerDragStart(id, e) {
    const event = e.changedTouches && e.changedTouches.length ? e.changedTouches[0] : e;

    this.setState({
      isSlideMoving: false,
      isTravellerMoving: true,
      movingTravellerId: id,
      brushMoveStartX: event.pageX,
    });
  }

  handleTravellerMove(e) {
    const { brushMoveStartX, movingTravellerId, endX, startX } = this.state;
    const prevValue = this.state[movingTravellerId];

    const { x, width, travellerWidth, onChange, gap, data } = this.props;
    const params = { startX: this.state.startX, endX: this.state.endX };

    let delta = e.pageX - brushMoveStartX;
    if (delta > 0) {
      delta = Math.min(delta, x + width - travellerWidth - prevValue);
    } else if (delta < 0) {
      delta = Math.max(delta, x - prevValue);
    }

    params[movingTravellerId] = prevValue + delta;

    const newIndex = this.getIndex(params);
    const { startIndex, endIndex } = newIndex;
    const isFullGap = () => {
      const lastIndex = data.length - 1;
      if ((movingTravellerId === 'startX' &&
        (endX > startX ? startIndex % gap === 0 : endIndex % gap === 0)) ||
        (endX < startX && endIndex === lastIndex) ||
      (movingTravellerId === 'endX' &&
        (endX > startX ? endIndex % gap === 0 : startIndex % gap === 0) ||
        (endX > startX && endIndex === lastIndex))) {
        return true;
      }
      return false;
    };

    this.setState({
      [movingTravellerId]: prevValue + delta,
      brushMoveStartX: e.pageX,
    }, () => {
      if (onChange) {
        if (isFullGap()) {
          onChange(newIndex);
        }
      }
    });
  }

  updateScale(props) {
    const { data, startIndex, endIndex, x, width, travellerWidth } = props;
    const len = data.length;
    this.scale = scalePoint()
      .domain(_.range(0, len))
      .range([x, x + width - travellerWidth]);
    this.scaleValues = this.scale.domain().map(entry => this.scale(entry));
    return {
      isTextActive: false,
      isSlideMoving: false,
      isTravellerMoving: false,
      startX: this.scale(startIndex),
      endX: this.scale(endIndex),
    };
  }

  renderBackground() {
    const { x, y, width, height, fill, stroke } = this.props;

    return (
      <rect
        stroke={stroke}
        fill={fill}
        x={x}
        y={y}
        width={width}
        height={height}
      />
    );
  }

  renderPanorama() {
    const { x, y, width, height, data, children, padding } = this.props;
    const chartElement = Children.only(children);

    if (!chartElement) { return null; }

    return React.cloneElement(chartElement, {
      x,
      y,
      width,
      height,
      margin: padding,
      compact: true,
      data,
    });
  }

  renderTraveller(travellerX, id) {
    const { y, travellerWidth, height, stroke } = this.props;
    const lineY = Math.floor(y + height / 2) - 1;
    const x = Math.max(travellerX, this.props.x);

    return (
      <Layer
        className="recharts-brush-traveller"
        onMouseEnter={this.handleEnterSlideOrTraveller}
        onMouseLeave={this.handleLeaveSlideOrTraveller}
        onMouseDown={this.travellerDragStartHandlers[id]}
        onTouchStart={this.travellerDragStartHandlers[id]}
        style={{ cursor: 'col-resize' }}
      >
        <rect
          x={x}
          y={y}
          width={travellerWidth}
          height={height}
          fill={stroke}
          stroke="none"
        />
        <line
          x1={x + 1}
          y1={lineY}
          x2={x + travellerWidth - 1}
          y2={lineY}
          fill="none"
          stroke="#fff"
        />
        <line
          x1={x + 1}
          y1={lineY + 2}
          x2={x + travellerWidth - 1}
          y2={lineY + 2}
          fill="none"
          stroke="#fff"
        />
      </Layer>
    );
  }

  renderSlide(startX, endX) {
    const { y, height, stroke } = this.props;

    return (
      <rect
        className="recharts-brush-slide"
        onMouseEnter={this.handleEnterSlideOrTraveller}
        onMouseLeave={this.handleLeaveSlideOrTraveller}
        onMouseDown={this.handleSlideDragStart}
        onTouchStart={this.handleSlideDragStart}
        style={{ cursor: 'move' }}
        stroke="none"
        fill={stroke}
        fillOpacity={0.2}
        x={Math.min(startX, endX)}
        y={y}
        width={Math.abs(endX - startX)}
        height={height}
      />
    );
  }

  renderText() {
    const { startIndex, endIndex, y, height, travellerWidth,
      stroke } = this.props;
    const { startX, endX } = this.state;
    const offset = 5;
    const attrs = {
      pointerEvents: 'none',
      fill: stroke,
    };

    return (
      <Layer className="recharts-brush-texts">
        <Text
          textAnchor="end"
          verticalAnchor="middle"
          x={Math.min(startX, endX) - offset}
          y={y + height / 2}
          {...attrs}
        >
          {this.getTextOfTick(startIndex)}
        </Text>
        <Text
          textAnchor="start"
          verticalAnchor="middle"
          x={Math.max(startX, endX) + travellerWidth + offset}
          y={y + height / 2}
          {...attrs}
        >
          {this.getTextOfTick(endIndex)}
        </Text>
      </Layer>
    );
  }

  render() {
    const { data, className, children, x, y, width, height } = this.props;
    const { startX, endX, isTextActive, isSlideMoving, isTravellerMoving } = this.state;

    if (!data || !data.length || !isNumber(x) || !isNumber(y) || !isNumber(width) ||
      !isNumber(height) || width <= 0 || height <= 0) { return null; }

    const layerClass = classNames('recharts-brush', className);
    const isPanoramic = React.Children.count(children) === 1;
    const style = generatePrefixStyle('userSelect', 'none');

    return (
      <Layer
        className={layerClass}
        onMouseMove={this.handleDrag}
        onMouseLeave={this.handleLeaveWrapper}
        onMouseUp={this.handleDragEnd}
        onTouchEnd={this.handleDragEnd}
        onTouchMove={this.handleTouchMove}
        style={style}
      >
        {this.renderBackground()}
        {isPanoramic && this.renderPanorama()}
        {this.renderSlide(startX, endX)}
        {this.renderTraveller(startX, 'startX')}
        {this.renderTraveller(endX, 'endX')}
        {(isTextActive || isSlideMoving || isTravellerMoving) && this.renderText()}
      </Layer>
    );
  }
}

export default Brush;
<|endoftext|>


<commit_before>// Poly path support NaN point
define(function (require) {

    var Path = require('zrender/graphic/Path');
    var vec2 = require('zrender/core/vector');
    var bbox = require('zrender/core/bbox');

    var mathMin = Math.min;
    var mathMax = Math.max;
    var vec2Min = vec2.min;
    var vec2Max = vec2.max;

    var scaleAndAdd = vec2.scaleAndAdd;
    var v2Copy = vec2.copy;

    // Temporary variable
    var v = [];
    var cp0 = [];
    var cp1 = [];

    function drawSegment(
        ctx, points, start, allLen, segLen,
        dir, smoothMin, smoothMax, smooth
    ) {
        var idx = start;
        for (var k = 0; k < segLen; k++) {
            var p = points[idx];
            if (idx >= allLen || idx < 0 || isNaN(p[0]) || isNaN(p[1])) {
                break;
            }

            if (idx === start) {
                ctx[dir > 0 ? 'moveTo' : 'lineTo'](p[0], p[1]);
                v2Copy(cp0, p);
            }
            else {
                if (smooth > 0) {
                    var prevIdx = idx - dir;
                    var nextIdx = idx + dir;
                    if (dir > 0) {
                        prevIdx = mathMax(prevIdx, start);
                        nextIdx = mathMin(nextIdx, allLen - 1);
                    }
                    else {
                        nextIdx = mathMax(nextIdx, 0);
                        prevIdx = mathMin(prevIdx, start);
                    }
                    var prevP = points[prevIdx];
                    var nextP = points[nextIdx];
                    // If next data is null
                    if (isNaN(nextP[0]) || isNaN(nextP[1])) {
                        nextP = p;
                    }

                    vec2.sub(v, nextP, prevP);

                    scaleAndAdd(cp1, p, v, -smooth / 2);

                    ctx.bezierCurveTo(
                        cp0[0], cp0[1],
                        cp1[0], cp1[1],
                        p[0], p[1]
                    );
                    // Smooth constraint
                    vec2Min(cp0, cp0, smoothMin);
                    vec2Max(cp0, cp0, smoothMax);
                    vec2Min(cp1, cp1, smoothMin);
                    vec2Max(cp1, cp1, smoothMax);
                    // cp0 of next segment
                    scaleAndAdd(cp0, p, v, smooth / 2);
                }
                else {
                    ctx.lineTo(p[0], p[1]);
                }
            }

            idx += dir;
        }

        return k;
    }

    return {

        Polyline: Path.extend({

            type: 'ec-polyline',

            shape: {
                points: [],

                smooth: 0
            },

            style: {
                fill: null,

                stroke: '#000',

                smooth: 0
            },

            buildPath: function (ctx, shape) {
                var points = shape.points;

                var i = 0;
                var len = points.length;

                var ptMin = [];
                var ptMax = [];
                bbox.fromPoints(points, ptMin, ptMax);

                while (i < len) {
                    i += drawSegment(
                        ctx, points, i, len, len,
                        1, ptMin, ptMax, shape.smooth
                    ) + 1;
                }
            }
        }),

        Polygon: Path.extend({

            type: 'ec-polygon',

            shape: {
                points: [],
                // Offset between stacked base points and points
                stackedOnPoints: [],
                smooth: 0,
                stackedOnSmooth: 0
            },

            buildPath: function (ctx, shape) {
                var points = shape.points;
                var stackedOnPoints = shape.stackedOnPoints;

                var i = 0;
                var len = points.length;

                var ptMin = [];
                var ptMax = [];
                bbox.fromPoints(points, ptMin, ptMax);

                while (i < len) {
                    var k = drawSegment(
                        ctx, points, i, len, len,
                        1, ptMin, ptMax, shape.smooth
                    );
                    drawSegment(
                        ctx, stackedOnPoints, i + k - 1, len, k,
                        -1, ptMin, ptMax, shape.stackedOnSmooth
                    );
                    i += k + 1;

                    ctx.closePath();
                }
            }
        })
    };
});<commit_msg>Line smooth constraint fix<commit_after>// Poly path support NaN point
define(function (require) {

    var Path = require('zrender/graphic/Path');
    var vec2 = require('zrender/core/vector');
    var bbox = require('zrender/core/bbox');

    var mathMin = Math.min;
    var mathMax = Math.max;
    var vec2Min = vec2.min;
    var vec2Max = vec2.max;

    var scaleAndAdd = vec2.scaleAndAdd;
    var v2Copy = vec2.copy;

    // Temporary variable
    var v = [];
    var cp0 = [];
    var cp1 = [];

    function drawSegment(
        ctx, points, start, allLen, segLen,
        dir, smoothMin, smoothMax, smooth
    ) {
        var idx = start;
        for (var k = 0; k < segLen; k++) {
            var p = points[idx];
            if (idx >= allLen || idx < 0 || isNaN(p[0]) || isNaN(p[1])) {
                break;
            }

            if (idx === start) {
                ctx[dir > 0 ? 'moveTo' : 'lineTo'](p[0], p[1]);
                v2Copy(cp0, p);
            }
            else {
                if (smooth > 0) {
                    var prevIdx = idx - dir;
                    var nextIdx = idx + dir;
                    if (dir > 0) {
                        prevIdx = mathMax(prevIdx, start);
                        nextIdx = mathMin(nextIdx, allLen - 1);
                    }
                    else {
                        nextIdx = mathMax(nextIdx, 0);
                        prevIdx = mathMin(prevIdx, start);
                    }
                    var prevP = points[prevIdx];
                    var nextP = points[nextIdx];
                    // If next data is null
                    if (isNaN(nextP[0]) || isNaN(nextP[1])) {
                        nextP = p;
                    }

                    vec2.sub(v, nextP, prevP);

                    scaleAndAdd(cp1, p, v, -smooth / 2);

                    // Smooth constraint
                    vec2Min(cp0, cp0, smoothMax);
                    vec2Max(cp0, cp0, smoothMin);
                    vec2Min(cp1, cp1, smoothMax);
                    vec2Max(cp1, cp1, smoothMin);

                    ctx.bezierCurveTo(
                        cp0[0], cp0[1],
                        cp1[0], cp1[1],
                        p[0], p[1]
                    );
                    // cp0 of next segment
                    scaleAndAdd(cp0, p, v, smooth / 2);
                }
                else {
                    ctx.lineTo(p[0], p[1]);
                }
            }

            idx += dir;
        }

        return k;
    }

    return {

        Polyline: Path.extend({

            type: 'ec-polyline',

            shape: {
                points: [],

                smooth: 0
            },

            style: {
                fill: null,

                stroke: '#000',

                smooth: 0
            },

            buildPath: function (ctx, shape) {
                var points = shape.points;

                var i = 0;
                var len = points.length;

                var ptMin = [];
                var ptMax = [];
                bbox.fromPoints(points, ptMin, ptMax);

                while (i < len) {
                    i += drawSegment(
                        ctx, points, i, len, len,
                        1, ptMin, ptMax, shape.smooth
                    ) + 1;
                }
            }
        }),

        Polygon: Path.extend({

            type: 'ec-polygon',

            shape: {
                points: [],
                // Offset between stacked base points and points
                stackedOnPoints: [],
                smooth: 0,
                stackedOnSmooth: 0
            },

            buildPath: function (ctx, shape) {
                var points = shape.points;
                var stackedOnPoints = shape.stackedOnPoints;

                var i = 0;
                var len = points.length;

                var ptMin = [];
                var ptMax = [];
                bbox.fromPoints(points, ptMin, ptMax);

                while (i < len) {
                    var k = drawSegment(
                        ctx, points, i, len, len,
                        1, ptMin, ptMax, shape.smooth
                    );
                    drawSegment(
                        ctx, stackedOnPoints, i + k - 1, len, k,
                        -1, ptMin, ptMax, shape.stackedOnSmooth
                    );
                    i += k + 1;

                    ctx.closePath();
                }
            }
        })
    };
});<|endoftext|>


<commit_before>'use strict';

angular.module('app')
    .service('PlayerService', function($log, BoardService, GameService, DeckService, Values) {
        var service = {};

        service.resetPlayers = function resetPlayers() {
            DeckService.shuffle();

            var players =  [{
                name: Values.playerOne,
                color: 'red',
                position: 1,
                direction: 1,
                move: null,
                attack: [],
                hand: DeckService.deal(5)
            }, {
                name: Values.playerTwo,
                color: 'blue',
                position: 18,
                direction: -1,
                move: null,
                attack: [],
                hand: DeckService.deal(5)
            }];

            return players;
        };

        service.players = service.resetPlayers();

        var DealPlayerHand = function DealPlayerHand(player) {
          var missingCards = 5 - player.hand.length;

          for (var i = 0; i < missingCards; i++) {
            player.hand = player.hand.concat(DeckService.deal(1));
          }
          return player.hand;

        };

        service.move = function move(player, direction) {
          if (player.move === null || !direction) {
            return;
          }
          player.position = BoardService.actualMove(player, direction);
          GameService.changePlayer();

          DeckService.discardCards(player.hand.splice(player.move , 1));

          player.hand = DealPlayerHand(player);
          player.move = null; //reset move
        };

        var attackNumbersMatch = function attackNumbersMatch(player) {
          var attack = {
              number: 0,
              quantity: 0
          };
          for (var i = 0; i < player.attack.length; i++) {
            if (attack.number === 0 && player.attack[i] == true) {
              attack.number = player.hand[i];
            }
            if (player.attack[i] == true && attack.number == player.hand[i]) {
              attack.quantity = attack.quantity + 1;
            }
            if (attack.number != 0 && player.attack[i] == true && player.hand[i] != attack.number) {
              return 0;
            }
          }
          return attack;
        };

        service.attack = function attack(player) {
          $log.log('attack', player.attack, player.hand);

          var action = {
            attack: attackNumbersMatch(player),
          };

          if (action.attack.number == 0) {
              $log.log('no attack card selected');
              return {error: 'no attack card selected'};
          }

          action.targetLocation =  player.position + player.direction*action.attack.number;
          action.opponentPlayerIndex = BoardService.getPlayerByLocation(action.targetLocation);

          if (action.opponentPlayerIndex == '') {
              $log.log('cannot attack opponent with ', action.attack.number);
              return {error: 'cannot attack opponent with ' + action.attack.number};
          }

          $log.log('attacking opponent player with ', action.attack.number, ' quantity', action.attack.quantity);

          var opponentPlayer = service.players[parseInt(action.opponentPlayerIndex)];

          $log.log('opponentPlayer', opponentPlayer);

          for (var i = 0; i < action.attack.quantity; i++) {
            var opponentCanBlock = opponentPlayer.hand.indexOf(action.attack.number);
            if (opponentCanBlock == -1) {
              GameService.changePlayer();
              GameService.gameOver();
              $log.log('opponent cannot block');
              return {success: 'opponent cannot block'};
            }
            opponentPlayer.hand.splice(opponentCanBlock, 1);
            $log.log('opponent blocked 1 attack', opponentPlayer.hand);
            player.hand.splice(player.hand.indexOf(action.attack.number), 1);
          }

          GameService.changePlayer();
          player.hand = DealPlayerHand(player);
          service.players[parseInt(action.opponentPlayerIndex)] = opponentPlayer;
          $log.log('opponent blocked attack', opponentPlayer.hand);
          return {failed: 'opponent blocked attack'};

        };

        return service;
    });<commit_msg>refactoring attack into smaller functions<commit_after>'use strict';

angular.module('app')
    .service('PlayerService', function($log, BoardService, GameService, DeckService, Values) {
        var service = {};

        service.resetPlayers = function resetPlayers() {
            DeckService.shuffle();

            var players =  [{
                name: Values.playerOne,
                color: 'red',
                position: 1,
                direction: 1,
                move: null,
                attack: [],
                hand: DeckService.deal(5)
            }, {
                name: Values.playerTwo,
                color: 'blue',
                position: 18,
                direction: -1,
                move: null,
                attack: [],
                hand: DeckService.deal(5)
            }];

            return players;
        };

        service.players = service.resetPlayers();

        var DealPlayerHand = function DealPlayerHand(player) {
          var missingCards = 5 - player.hand.length;

          for (var i = 0; i < missingCards; i++) {
            player.hand = player.hand.concat(DeckService.deal(1));
          }
          return player.hand;

        };

        service.move = function move(player, direction) {
          if (player.move === null || !direction) {
            return;
          }
          player.position = BoardService.actualMove(player, direction);
          GameService.changePlayer();

          DeckService.discardCards(player.hand.splice(player.move , 1));

          player.hand = DealPlayerHand(player);
          player.move = null; //reset move
        };

        var attackNumbersMatch = function attackNumbersMatch(player) {
          var attack = {
              number: 0,
              quantity: 0
          };
          for (var i = 0; i < player.attack.length; i++) {
            if (attack.number === 0 && player.attack[i] == true) {
              attack.number = player.hand[i];
            }
            if (player.attack[i] == true && attack.number == player.hand[i]) {
              attack.quantity = attack.quantity + 1;
            }
            if (attack.number != 0 && player.attack[i] == true && player.hand[i] != attack.number) {
              return 0;
            }
          }
          return attack;
        };

        var attackOpponent = function attackOpponent(player, opponentPlayer, action) {
          for (var i = 0; i < action.attack.quantity; i++) {
            var opponentCanBlock = opponentPlayer.hand.indexOf(action.attack.number);
            if (opponentCanBlock == -1) {
              return {successful: 'opponent cannot block'};
            }
            opponentPlayer.hand.splice(opponentCanBlock, 1);
            $log.log('opponent blocked 1 of '+ action.attack.quantity + ' attack', opponentPlayer.hand);
            player.hand.splice(player.hand.indexOf(action.attack.number), 1);
          }
          $log.log('opponent blocked attack', opponentPlayer.hand);
          return {failed: 'opponent blocked attack'};
        };

        service.attack = function attack(player) {

          var action = {
            attack: attackNumbersMatch(player),
          };

          if (action.attack.number == 0) {
              $log.log('no attack card selected');
              return {error: 'no attack card selected'};
          }

          action.targetLocation =  player.position + player.direction*action.attack.number;
          action.opponentPlayerIndex = BoardService.getPlayerByLocation(action.targetLocation);

          if (action.opponentPlayerIndex == '') {
              $log.log('cannot attack opponent with ', action.attack.number);
              return {error: 'cannot attack opponent with ' + action.attack.number};
          }

          $log.log('attacking opponent player with ', action.attack.number, ' quantity', action.attack.quantity);

          var opponentPlayer = service.players[parseInt(action.opponentPlayerIndex)];

          var resolution = attackOpponent(player, opponentPlayer, action);

          if (resolution.successful) {
            $log.log('opponent cannot block');
            GameService.gameOver();
          };

          GameService.changePlayer();
          player.hand = DealPlayerHand(player);
          service.players[parseInt(action.opponentPlayerIndex)] = opponentPlayer;
        };

        return service;
    });<|endoftext|>


<commit_before>'use strict';

/**
 * @ngdoc function
 * @name groongaAdminApp.service:schemaLoader
 * @description
 * # schemaLoader
 * Groonga database schema loader.
 */
angular.module('groongaAdminApp')
  .factory('schemaLoader', [
    '$q', '$http', '$timeout',
    function ($q, $http, $timeout) {
      var fetching = false;
      var waitingDeferes = [];
      var fetched = false;
      var schema = {
        tables: {}
      };
      var client = new GroongaClient($http);

      function isTextType(typeName) {
        switch (typeName) {
        case 'ShortText':
        case 'Text':
        case 'LongText':
          return true;
        default:
          return false;
        }
      }

      function isReferenceType(typeName) {
        return typeName in schema.tables;
      }

      function resolveTable(table) {
        table.keyType = {
          name: table.domain,
          isTextType: isTextType(table.domain)
        };
      }

      function resolveTables() {
        angular.forEach(schema.tables, function(table) {
          resolveTable(table);
        });
      }

      function resolveColumn(column) {
        column.valueType = {
          name: column.range,
          isTextType: isTextType(column.range),
          isReferenceType: isReferenceType(column.range)
        };
      }

      function resolveColumns() {
        angular.forEach(schema.tables, function(table) {
          angular.forEach(table.columns, function(column) {
            resolveColumn(column);
          });
        });
      }

      function resolveIndex(column) {
        var table = schema.tables[column.range];
        column.sources.forEach(function(source) {
          var columnName;
          if (source.indexOf('.') === -1) {
            columnName = '_key';
          } else {
            columnName = source.split('.')[1];
          }
          var targetColumn = table.columns[columnName];
          targetColumn.indexes.push(column);
        });
      }

      function resolveIndexes() {
        angular.forEach(schema.tables, function(table) {
          angular.forEach(table.columns, function(column) {
            if (column.isIndex) {
              resolveIndex(column);
            }
          });
        });
      }

      function addColumn(table, column) {
        column.table = table;
        column.indexes = [];
        table.columns[column.name] = column;
      }

      function addIDColumn(table) {
        var properties = {
          name: '_id',
          type: 'fix',
          flags: ['COLUMN_SCALAR', 'PERSISTENT'],
          domain: table.name,
          range: 'UInt32',
          sources: []
        };

        var rawProperties = angular.copy(properties);
        rawProperties.source = rawProperties.sources;
        delete rawProperties.sources;
        rawProperties.flags = rawProperties.flags.join('|');

        var IDColumn = angular.copy(properties);
        IDColumn.rawProperties = rawProperties;
        IDColumn.properties = properties;

        addColumn(table, IDColumn);
      }

      function fetchColumns(table) {
        table.columns = {};

        addIDColumn(table);

        return client.execute('column_list', {table: table.name})
          .success(function(response) {
            var columns = response.columns();

            columns.forEach(function(column) {
              addColumn(table, column);
            });
          });
      }

      function fetchTables() {
        return client.execute('table_list')
          .success(function(response) {
            response.tables().forEach(function(table) {
              schema.tables[table.name] = table;
            });
            resolveTables();

            var fetchColumnsTasks = [];
            angular.forEach(schema.tables, function(table) {
              fetchColumnsTasks.push(fetchColumns(table));
            });

            return $q.all(fetchColumnsTasks)
              .then(function() {
                resolveColumns();
                resolveIndexes();
                fetched = true;
                fetching = false;
                waitingDeferes.forEach(function(defer) {
                  defer.resolve(schema);
                });
                waitingDeferes = [];
                return schema;
              });
          });
      }

      return function() {
        var defer;
        if (fetching) {
          defer = $q.defer();
          waitingDeferes.push(defer);
          return defer.promise;
        } else if (fetched) {
          defer = $q.defer();
          $timeout(function() {
            defer.resolve(schema);
          });
          return defer.promise;
        } else {
          fetching = true;
          return fetchTables();
        }
      };
    }]);
<commit_msg>Use table's ID for _id key ID<commit_after>'use strict';

/**
 * @ngdoc function
 * @name groongaAdminApp.service:schemaLoader
 * @description
 * # schemaLoader
 * Groonga database schema loader.
 */
angular.module('groongaAdminApp')
  .factory('schemaLoader', [
    '$q', '$http', '$timeout',
    function ($q, $http, $timeout) {
      var fetching = false;
      var waitingDeferes = [];
      var fetched = false;
      var schema = {
        tables: {}
      };
      var client = new GroongaClient($http);

      function isTextType(typeName) {
        switch (typeName) {
        case 'ShortText':
        case 'Text':
        case 'LongText':
          return true;
        default:
          return false;
        }
      }

      function isReferenceType(typeName) {
        return typeName in schema.tables;
      }

      function resolveTable(table) {
        table.keyType = {
          name: table.domain,
          isTextType: isTextType(table.domain)
        };
      }

      function resolveTables() {
        angular.forEach(schema.tables, function(table) {
          resolveTable(table);
        });
      }

      function resolveColumn(column) {
        column.valueType = {
          name: column.range,
          isTextType: isTextType(column.range),
          isReferenceType: isReferenceType(column.range)
        };
      }

      function resolveColumns() {
        angular.forEach(schema.tables, function(table) {
          angular.forEach(table.columns, function(column) {
            resolveColumn(column);
          });
        });
      }

      function resolveIndex(column) {
        var table = schema.tables[column.range];
        column.sources.forEach(function(source) {
          var columnName;
          if (source.indexOf('.') === -1) {
            columnName = '_key';
          } else {
            columnName = source.split('.')[1];
          }
          var targetColumn = table.columns[columnName];
          targetColumn.indexes.push(column);
        });
      }

      function resolveIndexes() {
        angular.forEach(schema.tables, function(table) {
          angular.forEach(table.columns, function(column) {
            if (column.isIndex) {
              resolveIndex(column);
            }
          });
        });
      }

      function addColumn(table, column) {
        column.table = table;
        column.indexes = [];
        table.columns[column.name] = column;
      }

      function addIDColumn(table) {
        var properties = {
          id: table.id,
          name: '_id',
          type: 'fix',
          flags: ['COLUMN_SCALAR', 'PERSISTENT'],
          domain: table.name,
          range: 'UInt32',
          sources: []
        };

        var rawProperties = angular.copy(properties);
        rawProperties.source = rawProperties.sources;
        delete rawProperties.sources;
        rawProperties.flags = rawProperties.flags.join('|');

        var IDColumn = angular.copy(properties);
        IDColumn.rawProperties = rawProperties;
        IDColumn.properties = properties;

        addColumn(table, IDColumn);
      }

      function fetchColumns(table) {
        table.columns = {};

        addIDColumn(table);

        return client.execute('column_list', {table: table.name})
          .success(function(response) {
            var columns = response.columns();

            columns.forEach(function(column) {
              addColumn(table, column);
            });
          });
      }

      function fetchTables() {
        return client.execute('table_list')
          .success(function(response) {
            response.tables().forEach(function(table) {
              schema.tables[table.name] = table;
            });
            resolveTables();

            var fetchColumnsTasks = [];
            angular.forEach(schema.tables, function(table) {
              fetchColumnsTasks.push(fetchColumns(table));
            });

            return $q.all(fetchColumnsTasks)
              .then(function() {
                resolveColumns();
                resolveIndexes();
                fetched = true;
                fetching = false;
                waitingDeferes.forEach(function(defer) {
                  defer.resolve(schema);
                });
                waitingDeferes = [];
                return schema;
              });
          });
      }

      return function() {
        var defer;
        if (fetching) {
          defer = $q.defer();
          waitingDeferes.push(defer);
          return defer.promise;
        } else if (fetched) {
          defer = $q.defer();
          $timeout(function() {
            defer.resolve(schema);
          });
          return defer.promise;
        } else {
          fetching = true;
          return fetchTables();
        }
      };
    }]);
<|endoftext|>


<commit_before>'use strict';

(function() {
  angular.module('ncsaas')
    .service('usersService', ['RawUser', 'RawKey', usersService]);

  function usersService(RawUser, RawKey) {
    /*jshint validthis: true */
    var vm = this;
    vm.getCurrentUser = getCurrentUser;
    vm.getCurrentUserWithKeys = getCurrentUserWithKeys;

    function getCurrentUser() {
      return RawUser.getCurrent();
    }

    function getCurrentUserWithKeys() {
      return RawUser.getCurrent(initKeys);

      function initKeys(user) {
        /*jshint camelcase: false */
        user.keys = RawKey.query({user_uuid: user.uuid});
      }
    }

  }

})();

(function() {
  angular.module('ncsaas')
    .factory('RawUser', ['ENV', '$resource', RawUser]);

    function RawUser(ENV, $resource) {
      return $resource(ENV.apiEndpoint + 'api/users/:userUUID/', {userUUID:'@uuid'},
        {
          getCurrent: {
              method: 'GET',
              transformResponse: function(data) {return angular.fromJson(data)[0];},
              params: {current:''}
          }
        }
      );
    }

})();
<commit_msg>Update userservice for get users list and single user.<commit_after>'use strict';

(function() {
  angular.module('ncsaas')
    .service('usersService', ['RawUser', 'RawKey', usersService]);

  function usersService(RawUser, RawKey) {
    /*jshint validthis: true */
    var vm = this;
    vm.getCurrentUser = getCurrentUser;
    vm.getCurrentUserWithKeys = getCurrentUserWithKeys;
    vm.getUser = getUser;
    vm.getRawUserList = getRawUserList;

    function getCurrentUser() {
      return RawUser.getCurrent();
    }

    function getCurrentUserWithKeys() {
      return RawUser.getCurrent(initKeys);

      function initKeys(user) {
        /*jshint camelcase: false */
        user.keys = RawKey.query({user_uuid: user.uuid});
      }
    }

    function getRawUserList() {
      return RawUser.query();
    }

    function getUser(uuid) {
      return RawUser.get({userUUID: uuid});
    }

  }

})();

(function() {
  angular.module('ncsaas')
    .factory('RawUser', ['ENV', '$resource', RawUser]);

    function RawUser(ENV, $resource) {
      return $resource(ENV.apiEndpoint + 'api/users/:userUUID/', {userUUID:'@uuid'},
        {
          getCurrent: {
              method: 'GET',
              transformResponse: function(data) {return angular.fromJson(data)[0];},
              params: {current:''}
          }
        }
      );
    }

})();
<|endoftext|>


<commit_before>Lizard.Dashboard = {};

Lizard.Dashboard.DefaultLayout = Backbone.Marionette.Layout.extend({
  template: '#dashboard-template',
  regions: {
    'sidebarRegion': '#sidebarRegion',
    'dashboardRegion': '#dashboardRegion'
  }
});

Lizard.Dashboard.Router = Backbone.Marionette.AppRouter.extend({
    appRoutes: {
      'dashboard': 'dashboard'
    }
});

Lizard.Dashboard.dashboard = function(){
  console.log('Lizard.Dashboard.overview()');

  // Instantiate Dashboard's default layout
  var dashboardView = new Lizard.Dashboard.DefaultLayout();
  Lizard.App.content.show(dashboardView);

  var widgetcollectionview = new Lizard.Views.WidgetCollection();

  var timeseries = [
    "https://api.ddsc.nl/api/v1/timeseries/9DFDC3F7-88F7-4FF0-A671-B4094AC12B7A",  // Waterkolom dijk rechts in mNAP
    "https://api.ddsc.nl/api/v1/timeseries/49108710-6C58-4E31-AC2D-3C4933040439",  // Waterkolom dijk links in mNAP
    "https://api.ddsc.nl/api/v1/timeseries/03073703-3509-40F2-BA89-D85361C4021B",  // Temperatuur Dijk Rechts
    "https://api.ddsc.nl/api/v1/timeseries/29119285-2428-4863-B630-9B5AA095DE13",  // Temperatuur Dijk Links
    "https://api.ddsc.nl/api/v1/timeseries/DD7A4DB5-4261-4AC4-9583-0572E7F39F66",  // Actueel Debiet Dijk Rechts
    "https://api.ddsc.nl/api/v1/timeseries/D856946F-FEB6-4536-A878-AF55C32CD96C",  // Actueel Debiet Dijk Links
    "https://api.ddsc.nl/api/v1/timeseries/5C8D7780-14C8-4237-9BCA-73849E7990B7"   // Buitendruk in kPa
  ];

  var dmcCollection = Backbone.Collection.extend({
    url: "https://api.ddsc.nl/api/v1/timeseries/?name=omzd_dmc",
    model: Lizard.Models.Timeserie
  });

  dmc = new dmcCollection();

  if (account.get('authenticated')) {
    dmc.fetch({
      cache: false,
      success: function(collection) {
        var values = new Backbone.Model({
          debiet_l: collection.get('D856946F-FEB6-4536-A878-AF55C32CD96C').get('latest_value'),
          debiet_r: collection.get('DD7A4DB5-4261-4AC4-9583-0572E7F39F66').get('latest_value'),
          temp_l: collection.get('29119285-2428-4863-B630-9B5AA095DE13').get('latest_value'),
          temp_r: collection.get('03073703-3509-40F2-BA89-D85361C4021B').get('latest_value'),
          waterst_l: collection.get('49108710-6C58-4E31-AC2D-3C4933040439').get('latest_value'),
          waterst_r: collection.get('9DFDC3F7-88F7-4FF0-A671-B4094AC12B7A').get('latest_value')
        });

        widgetcollectionview.collection.reset();
        widgetcollectionview.collection.add([
          new Lizard.Models.Widget({col:1,row:1,size_x:2,size_y:4,gaugeId:4,type:'template', template:'#dashboard-list'}),
          new Lizard.Models.Widget({col:1,row:5,size_x:2,size_y:3,gaugeId:6,type:'template', template:'#dmc-status'}),
          new Lizard.Models.Widget({col:2,row:1,size_x:7,size_y:4,gaugeId:3,type:'graph', timeseries: timeseries}),
          new Lizard.Models.Widget(_.extend({col:2,row:3,size_x:7,size_y:3,gaugeId:2,type:'template', template:'#dmc-overview'},values.attributes)),

          new Lizard.Models.Widget({col:3,row:1,size_x:3,size_y:2,gaugeId:4,type:'template', template:'#dashboard-logo'}),
          new Lizard.Models.Widget({col:3,row:3,size_x:3,size_y:2,gaugeId:5,title:'Debiet links',label:'liter',
            value: values.get('debiet_l') , max: 5000}),
          new Lizard.Models.Widget({col:3,row:5,size_x:3,size_y:2,gaugeId:7,title:'Debiet rechts',label:'liter',
            value: values.get('debiet_r'), max: 5000}),
          new Lizard.Models.Widget({col:3,row:7,size_x:3,size_y:1,gaugeId:8,type:'template', template:'#settings-button'}),
          new Lizard.Models.Widget({col:3,row:8,size_x:7,size_y:4,gaugeId:9,type:'template', template:'#image-dmc'})
        ]);

        dashboardView.dashboardRegion.show(widgetcollectionview.render());
      }
    } else {
      // dashboardView.dashboardRegion.show('login');

    }

  });

  Backbone.history.navigate('dashboard');
};

Lizard.App.addInitializer(function(){
  Lizard.Dashboard.router = new Lizard.Dashboard.Router({
    controller: Lizard.Dashboard
  });
});

<commit_msg>syntax error<commit_after>Lizard.Dashboard = {};

Lizard.Dashboard.DefaultLayout = Backbone.Marionette.Layout.extend({
  template: '#dashboard-template',
  regions: {
    'sidebarRegion': '#sidebarRegion',
    'dashboardRegion': '#dashboardRegion'
  }
});

Lizard.Dashboard.Router = Backbone.Marionette.AppRouter.extend({
    appRoutes: {
      'dashboard': 'dashboard'
    }
});

Lizard.Dashboard.dashboard = function() {
  console.log('Lizard.Dashboard.overview()');

  // Instantiate Dashboard's default layout
  var dashboardView = new Lizard.Dashboard.DefaultLayout();
  Lizard.App.content.show(dashboardView);

  var widgetcollectionview = new Lizard.Views.WidgetCollection();

  var timeseries = [
    "https://api.ddsc.nl/api/v1/timeseries/9DFDC3F7-88F7-4FF0-A671-B4094AC12B7A",  // Waterkolom dijk rechts in mNAP
    "https://api.ddsc.nl/api/v1/timeseries/49108710-6C58-4E31-AC2D-3C4933040439",  // Waterkolom dijk links in mNAP
    "https://api.ddsc.nl/api/v1/timeseries/03073703-3509-40F2-BA89-D85361C4021B",  // Temperatuur Dijk Rechts
    "https://api.ddsc.nl/api/v1/timeseries/29119285-2428-4863-B630-9B5AA095DE13",  // Temperatuur Dijk Links
    "https://api.ddsc.nl/api/v1/timeseries/DD7A4DB5-4261-4AC4-9583-0572E7F39F66",  // Actueel Debiet Dijk Rechts
    "https://api.ddsc.nl/api/v1/timeseries/D856946F-FEB6-4536-A878-AF55C32CD96C",  // Actueel Debiet Dijk Links
    "https://api.ddsc.nl/api/v1/timeseries/5C8D7780-14C8-4237-9BCA-73849E7990B7"   // Buitendruk in kPa
  ];

  var dmcCollection = Backbone.Collection.extend({
    url: "https://api.ddsc.nl/api/v1/timeseries/?name=omzd_dmc",
    model: Lizard.Models.Timeserie
  });

  dmc = new dmcCollection();

  if (account.get('authenticated')) {
    dmc.fetch({
      cache: false,
      success: function(collection) {
        var values = new Backbone.Model({
          debiet_l: collection.get('D856946F-FEB6-4536-A878-AF55C32CD96C').get('latest_value'),
          debiet_r: collection.get('DD7A4DB5-4261-4AC4-9583-0572E7F39F66').get('latest_value'),
          temp_l: collection.get('29119285-2428-4863-B630-9B5AA095DE13').get('latest_value'),
          temp_r: collection.get('03073703-3509-40F2-BA89-D85361C4021B').get('latest_value'),
          waterst_l: collection.get('49108710-6C58-4E31-AC2D-3C4933040439').get('latest_value'),
          waterst_r: collection.get('9DFDC3F7-88F7-4FF0-A671-B4094AC12B7A').get('latest_value')
        });

        widgetcollectionview.collection.reset();
        widgetcollectionview.collection.add([
          new Lizard.Models.Widget({col:1,row:1,size_x:2,size_y:4,gaugeId:4,type:'template', template:'#dashboard-list'}),
          new Lizard.Models.Widget({col:1,row:5,size_x:2,size_y:3,gaugeId:6,type:'template', template:'#dmc-status'}),
          new Lizard.Models.Widget({col:2,row:1,size_x:7,size_y:4,gaugeId:3,type:'graph', timeseries: timeseries}),
          new Lizard.Models.Widget(_.extend({col:2,row:3,size_x:7,size_y:3,gaugeId:2,type:'template', template:'#dmc-overview'},values.attributes)),

          new Lizard.Models.Widget({col:3,row:1,size_x:3,size_y:2,gaugeId:4,type:'template', template:'#dashboard-logo'}),
          new Lizard.Models.Widget({col:3,row:3,size_x:3,size_y:2,gaugeId:5,title:'Debiet links',label:'liter',
            value: values.get('debiet_l') , max: 5000}),
          new Lizard.Models.Widget({col:3,row:5,size_x:3,size_y:2,gaugeId:7,title:'Debiet rechts',label:'liter',
            value: values.get('debiet_r'), max: 5000}),
          new Lizard.Models.Widget({col:3,row:7,size_x:3,size_y:1,gaugeId:8,type:'template', template:'#settings-button'}),
          new Lizard.Models.Widget({col:3,row:8,size_x:7,size_y:4,gaugeId:9,type:'template', template:'#image-dmc'})
        ]);

        dashboardView.dashboardRegion.show(widgetcollectionview.render());
      }
    });
  }

  Backbone.history.navigate('dashboard');
};

Lizard.App.addInitializer(function(){
  Lizard.Dashboard.router = new Lizard.Dashboard.Router({
    controller: Lizard.Dashboard
  });
});

<|endoftext|>