<commit_before>'use strict';

const {
  GraphQLString,
  GraphQLNonNull,
  GraphQLList,
} = require('graphql');
const { chain, mapValues, pickBy } = require('lodash');

const { isMultiple, getSubDef } = require('./utilities');

// Retrieves all resolver arguments, before resolve function is fired
const getArguments = function (def, opts) {
	// Builds inputObject types
  const subDef = getSubDef(def);
	const inputObjectOpts = Object.assign({}, opts, { inputObjectType: 'input' });
	const inputObjectType = opts.getType(subDef, inputObjectOpts);
	const filterObjectOpts = Object.assign({}, opts, { inputObjectType: 'filter' });
  const filterObjectType = opts.getType(subDef, filterObjectOpts);

  opts = Object.assign({}, opts, {
    multiple: isMultiple(def),
    isTopLevel: def.isTopLevel,
    inputObjectType,
    filterObjectType,
  });

  const args = Object.assign(
    {},
    getIdArgument(opts),
		getDataArgument(opts),
		getFilterArgument(opts),
    getOrderArgument(opts)
  );
  return args;
};

// Add resolver arguments, while resolve function is fired
// As opposed to `getArguments`, those arguments depend on current query resolution, e.g. on parent value
const addArguments = function (def, opts) {
};

// order_by argument, i.e. used for sorting results
const getOrderArgument = function ({ opType, multiple }) {
  // Only with *Many methods, except DeleteMany (since it does not return anything)
  if (!multiple || opType === 'delete') { return; }

  return {
    order_by: {
      type: GraphQLString,
      description: `Sort results according to this attribute.
Specify ascending or descending order by appending + or - (default is ascending)`,
      defaultValue: 'id+',
    },
  };
};

// Data argument, i.e. payload used by mutation operations
const dataOpTypes = ['create', 'upsert', 'replace', 'update'];
const multipleDataOpTypes = ['create', 'upsert', 'replace'];
const getDataArgument = function ({ multiple, opType, inputObjectType }) {
	// Only for mutation operations, but not delete
	if (!dataOpTypes.includes(opType)) { return; }

	// Retrieves description before wrapping in modifers
	const description = inputObjectType.description;

	// Add required and array modifiers
	inputObjectType = new GraphQLNonNull(inputObjectType);
  // Only multiple with createMany or upsertMany or replaceMany
	if (multiple && multipleDataOpTypes.includes(opType)) {
		inputObjectType = new GraphQLNonNull(new GraphQLList(inputObjectType));
	}

	return {
		data: {
			type: inputObjectType,
			description,
		},
	};
};

// Filters argument, i.e. only queries entities that match specified attributes
const filterOpTypes = ['find', 'delete', 'update'];
const getFilterArgument = function ({ multiple, opType, filterObjectType }) {
  const fieldsArgs = getFieldsArgs({ filterObjectType });
  // Only for findMany, deleteMany and updateMany
  if (!multiple || !filterOpTypes.includes(opType)) { return; }
  // Exclude `id` argument, as it handled by getIdArgument()
  const filterIdArgs = pickBy(fieldsArgs, (_, fieldName) => fieldName !== 'id');
  return filterIdArgs;
};

// id argument, used to query, and (with create|replace|upsert) also mutate
const optionalIdOpTypes = ['create'];
const getIdArgument = function ({ multiple, opType, filterObjectType, isTopLevel }) {
  // Nested types do not get id argument, as it is guessed from parent value
  // Exception: findMany, deleteMany and updateMany, where it is merged (intersected) with parent value
  if (!isTopLevel && !(multiple && filterOpTypes.includes(opType))) { return; }

  const fieldsArgs = getFieldsArgs({ filterObjectType });
  const dataIdArgs = chain(fieldsArgs)
    .pickBy((_, fieldName) => fieldName === 'id')
    .mapValues(field => {
      let idType = field.type;
      // createOne and createMany do not require ids
      const isOptional = optionalIdOpTypes.includes(opType)
      // nor can findMany, deleteMany or updateMany (since it is used as an optional filter)
        || (filterOpTypes.includes(opType) && multiple);
      if (!isOptional) {
        idType = new GraphQLNonNull(idType);
      }
      if (multiple) {
        idType = new GraphQLList(idType);
        if (!isOptional) {
          idType = new GraphQLNonNull(idType);
        }
      }
      field.type = idType;
      return field;
    })
    // `id` argument is `ids` instead in *Many operations
    .mapKeys(() => multiple ? 'ids' : 'id')
    .value();
  return dataIdArgs;
};

// Retrieve model fields, so they can be used as arguments
const getFieldsArgs = function ({ filterObjectType }) {
  const fields = filterObjectType.getFields();
  return mapValues(fields, field => ({
    type: field.type,
    description: field.description,
  }));
};

module.exports = {
  getArguments,
  addArguments,
};<commit_msg>Add comments<commit_after>'use strict';

const {
  GraphQLString,
  GraphQLNonNull,
  GraphQLList,
} = require('graphql');
const { chain, mapValues, pickBy } = require('lodash');

const { isMultiple, getSubDef } = require('./utilities');

/**
 * Summary of arguments:
 *  - {any|any[]} id|ids     - Filter the operation by id
 *                             For createOne:
 *                              - it is the id the newly created instance
 *                              - it is optional, unless there is another nested operation on a submodel
 *                             Operations on submodels will automatically get filtered by id.
 *                             If an id is then specified, both filters will be used
 *  - {object|object[]} data - Attributes to update or create
 *                             Is an array with createMany, replaceMany or upsertMany
 *  - {any} filter           - Filter the operation by a specific attribute.
 *                             The argument name is that attribute name, not `filter`
 *  - {string} order_by      - Sort results.
 *                             Value is attribute name, followed by optional + or - for ascending|descending order (default: +)
 *
 * Summary of operations:
 *   findOne(id)
 *   findMany([filter...])
 *   deleteOne(id)
 *   deleteMany([filter...])
 *   updateOne(data, id)
 *   updateMany(data[, filter...])
 *   createOne(data[, id])
 *   createMany(data[][, ids])
 *   replaceOne(data, id)
 *   replaceMany(data[], ids)
 *   upsertOne(data, id)
 *   upsertMany(data[], ids)
 **/

// Retrieves all resolver arguments, before resolve function is fired
const getArguments = function (def, opts) {
	// Builds inputObject types
  const subDef = getSubDef(def);
	const inputObjectOpts = Object.assign({}, opts, { inputObjectType: 'input' });
	const inputObjectType = opts.getType(subDef, inputObjectOpts);
	const filterObjectOpts = Object.assign({}, opts, { inputObjectType: 'filter' });
  const filterObjectType = opts.getType(subDef, filterObjectOpts);

  opts = Object.assign({}, opts, {
    multiple: isMultiple(def),
    isTopLevel: def.isTopLevel,
    inputObjectType,
    filterObjectType,
  });

  const args = Object.assign(
    {},
    getIdArgument(opts),
		getDataArgument(opts),
		getFilterArgument(opts),
    getOrderArgument(opts)
  );
  return args;
};

// Add resolver arguments, while resolve function is fired
// As opposed to `getArguments`, those arguments depend on current query resolution, e.g. on parent value
const addArguments = function (def, opts) {
};

// order_by argument, i.e. used for sorting results
const getOrderArgument = function ({ opType, multiple }) {
  // Only with *Many methods, except DeleteMany (since it does not return anything)
  if (!multiple || opType === 'delete') { return; }

  return {
    order_by: {
      type: GraphQLString,
      description: `Sort results according to this attribute.
Specify ascending or descending order by appending + or - (default is ascending)`,
      defaultValue: 'id+',
    },
  };
};

// Data argument, i.e. payload used by mutation operations
const dataOpTypes = ['create', 'upsert', 'replace', 'update'];
const multipleDataOpTypes = ['create', 'upsert', 'replace'];
const getDataArgument = function ({ multiple, opType, inputObjectType }) {
	// Only for mutation operations, but not delete
	if (!dataOpTypes.includes(opType)) { return; }

	// Retrieves description before wrapping in modifers
	const description = inputObjectType.description;

	// Add required and array modifiers
	inputObjectType = new GraphQLNonNull(inputObjectType);
  // Only multiple with createMany or upsertMany or replaceMany
	if (multiple && multipleDataOpTypes.includes(opType)) {
		inputObjectType = new GraphQLNonNull(new GraphQLList(inputObjectType));
	}

	return {
		data: {
			type: inputObjectType,
			description,
		},
	};
};

// Filters argument, i.e. only queries entities that match specified attributes
const filterOpTypes = ['find', 'delete', 'update'];
const getFilterArgument = function ({ multiple, opType, filterObjectType }) {
  const fieldsArgs = getFieldsArgs({ filterObjectType });
  // Only for findMany, deleteMany and updateMany
  if (!multiple || !filterOpTypes.includes(opType)) { return; }
  // Exclude `id` argument, as it handled by getIdArgument()
  const filterIdArgs = pickBy(fieldsArgs, (_, fieldName) => fieldName !== 'id');
  return filterIdArgs;
};

// id argument, used to query, and (with create|replace|upsert) also mutate
const optionalIdOpTypes = ['create'];
const getIdArgument = function ({ multiple, opType, filterObjectType, isTopLevel }) {
  // Nested types do not get id argument, as it is guessed from parent value
  // Exception: findMany, deleteMany and updateMany, where it is merged (intersected) with parent value
  if (!isTopLevel && !(multiple && filterOpTypes.includes(opType))) { return; }

  const fieldsArgs = getFieldsArgs({ filterObjectType });
  const dataIdArgs = chain(fieldsArgs)
    .pickBy((_, fieldName) => fieldName === 'id')
    .mapValues(field => {
      let idType = field.type;
      // createOne and createMany do not require ids
      const isOptional = optionalIdOpTypes.includes(opType)
      // nor can findMany, deleteMany or updateMany (since it is used as an optional filter)
        || (filterOpTypes.includes(opType) && multiple);
      if (!isOptional) {
        idType = new GraphQLNonNull(idType);
      }
      if (multiple) {
        idType = new GraphQLList(idType);
        if (!isOptional) {
          idType = new GraphQLNonNull(idType);
        }
      }
      field.type = idType;
      return field;
    })
    // `id` argument is `ids` instead in *Many operations
    .mapKeys(() => multiple ? 'ids' : 'id')
    .value();
  return dataIdArgs;
};

// Retrieve model fields, so they can be used as arguments
const getFieldsArgs = function ({ filterObjectType }) {
  const fields = filterObjectType.getFields();
  return mapValues(fields, field => ({
    type: field.type,
    description: field.description,
  }));
};

module.exports = {
  getArguments,
  addArguments,
};<|endoftext|>


<commit_before>/**
 * @license
 * Copyright 2015 Google Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// TODO: Create a Range Model?
/*
MODEL({
  package: 'foam.demos.sevenguis',
  name: 'CellParser',
  extendsModel: 'foam.parse.Grammar',

  methods: {
*/

var CellParser = {
  __proto__: grammar,

  START: alt(
    sym('number'),
    sym('formula'),
    sym('string')
  ),

  formula: seq1(1, '=', sym('expr')),

  expr: alt(
    sym('number'),
    sym('cell'),
    sym('add'),
    sym('sub'),
    sym('mul'),
    sym('div'),
    sym('mod'),
    sym('sum'),
    sym('prod')
  ),

  add:  seq(literal_ic('add('),  sym('expr'), ',', sym('expr'), ')'),
  sub:  seq(literal_ic('sub('),  sym('expr'), ',', sym('expr'), ')'),
  mul:  seq(literal_ic('mul('),  sym('expr'), ',', sym('expr'), ')'),
  div:  seq(literal_ic('div('),  sym('expr'), ',', sym('expr'), ')'),
  mod:  seq(literal_ic('mod('),  sym('expr'), ',', sym('expr'), ')'),
  sum:  seq(literal_ic('sum('),  sym('range'), ')'),
  prod: seq(literal_ic('prod('), sym('range'), ')'),

  range: seq(sym('col'), sym('row'), ',', sym('col'), sym('row')),

  digit: range('0', '9'),

  number: str(seq(
    optional('-'),
    str(alt(
      seq(str(repeat(sym('digit'))), '.', str(plus(sym('digit')))),
      plus(sym('digit')))))),

  cell: seq(sym('col'), sym('row')),

  col: alt(sym('az'), sym('AZ')),

  az: range('a', 'z'),

  AZ: range('A', 'Z'),

  row: str(repeat(sym('digit'), null, 1, 2)),

  string: str(repeat(anyChar))
}.addActions({
  add: function(a) { return function(cs) { return a[1](cs) + a[3](cs); }; },
  sub: function(a) { return function(cs) { return a[1](cs) - a[3](cs); }; },
  mul: function(a) { return function(cs) { return a[1](cs) * a[3](cs); }; },
  div: function(a) { return function(cs) { return a[1](cs) / a[3](cs); }; },
  mod: function(a) { return function(cs) { return a[1](cs) % a[3](cs); }; },
  sum: function(a) { return function(cs) {
    var arr = a[1](cs);
    var sum = 0;
    for ( var i = 0 ; i < arr.length ; i++ ) sum += arr[i];
    return sum;
  }; },
  prod: function(a) { return function(cs) {
    var arr = a[1](cs);
    var prod = 1;
    for ( var i = 0 ; i < arr.length ; i++ ) prod *= arr[i];
    return prod;
  }; },
  az:  function(c) { return c.charCodeAt(0) - 'a'.charCodeAt(0); },
  AZ:  function(c) { return c.charCodeAt(0) - 'A'.charCodeAt(0); },
  row: function(c) { return parseInt(c); },
  number: function(s) { var f = parseFloat(s); return function() { return f; }; },
  cell: function(a) { return function(cs) { return cs.cell(a[1], a[0]).value; }; },
  range: function(a) {
    var c1 = a[0];
    var r1 = a[1];
    var c2 = a[3];
    var r2 = a[4];
    return function(cs) {
      var ret = [];
      for ( var c = c1 ; c <= c2; c++ )
        for ( var r = r1 ; r <= r2 ; r++ )
          ret.push(cs.cell(r, c).value);
      return ret;
    }
  },
  string: function(s) { return function() { return s; }; }
});
//});

// https://www.artima.com/pins1ed/the-scells-spreadsheet.html
MODEL({
  package: 'foam.demos.sevenguis',
  name: 'Cell',
  extendsModel: 'foam.ui.View',
  imports: [ 'cells' ],
  properties: [
    {
      name: 'formula',
      displayWidth: 10
    },
    {
      name: 'value',
      defaultValue: ' ',
      displayWidth: 12
    }
  ],
  methods: [
    function initHTML() {
      this.SUPER();

      this.valueView.$.addEventListener('click',  this.onClick);
      this.formulaView.$.addEventListener('blur', this.onBlur);
      this.formula$.addListener(this.onBlur);
    }
  ],
  listeners: [
    {
      name: 'onClick',
      code: function() {
        DOM.setClass(this.$, 'formula', true);
        this.formulaView.$.focus();
      }
    },
    {
      name: 'onBlur',
      code: function() {
        DOM.setClass(this.$, 'formula', false);
      }
    }
  ],
  templates: [
    function CSS() {/*
      .cellView > span {
        display: block;
        padding: 2px;
        width: 100%;
      }
      .cellView > input {
        border:  none;
        display: none;
        margin-left: 2px;
        outline: none;
      }
      .cellView {
        outline: 1px solid white;
      }
      .cellView.formula {
        outline: 1px solid blue;
      }
      .cellView.formula > input {
        display: inherit;
      }
      .cellView.formula > span {
        display: none;
      }
    */},
    function toHTML() {/*

$$formula $$value{mode: 'read-only', escapeHTML: false}

    */}
  ]
});

MODEL({
  package: 'foam.demos.sevenguis',
  name: 'Cells',
  extendsModel: 'foam.ui.View',
  requires: [
//    'foam.demos.sevenguis.CellParser',
    'foam.demos.sevenguis.Cell'
  ],
  imports: [ 'dynamic' ],
  exports: [ 'as cells' ], // Would 'sheet' be a better name?
  constants: {
    ROWS: 20 /* 99 */
  },
  properties: [
    {
      name: 'cells',
      factory: function() { return {}; }
    },
    {
      name: 'parser',
      factory: function() { return /*this.*/CellParser/*.create()*/; }
    }
  ],
  methods: [
    function init() {
      this.SUPER();

      // Load a Test Spreadsheet
      var row = 1;
      var self = this;
      function t(s) {
        try {
          var r = row++;
          self.cell(r, 0).formula = ' ' + s;
          self.cell(r, 1).formula = s;
        } catch (x) {
        }
      }

      this.cell(0,0).formula = 'Formulas';
      this.cell(0,1).formula = 'Values';

      t('1');
      t('10');
      t('10.12');
      t('-10.1');
      t('foobar');
      t('=add(1,2)');
      t('=sub(2,1)');
      t('=mul(2,3)');
      t('=div(9,3)');
      t('=mod(8,3)');
      t('=add(mul(2,3),div(3,2))');
      t('=A1');
      t('=add(A1,B1)');
      t('=sum(B6,B10)');
      t('=prod(B6,B10)');
    },
    function cell(r, c) {
      var self = this;
      var row  = this.cells[r] || ( this.cells[r] = {} );
      var cell = row[c];
      if ( ! cell ) {
        cell = row[c] = this.Cell.create();
        cell.formula$.addListener(function(_, _, _, formula) {
//          console.log('formula: ', r, c, formula);
          var f = self.parser.parseString(formula);
          self.dynamic(f.bind(null, self), function(v) {
            cell.value = v;
//            console.log('v:', v);
          });
        });
      }
      return cell;
    }
  ],
  templates: [
    function CSS() {/*
      .cells tr, .cells td, .cells th, .cells input {
        color: #333;
        font: 13px roboto, arial, sans-serif;
      }
      .cells tr { height: 26px; }
      .cells { overflow: auto; }
      .cell { min-width: 100px; }
      table.cells, .cells th, .cells td {
        border: 1px solid #ccc;
        border-right: none;
        border-bottom: none;
      }
      .cells td {
        height: 100%;
      }
      .cells th {
        background: #eee;
        color: #333;
        padding: 2px 18px;
      }
    */},
    function toHTML() {/*

          <% for ( var i = 65 ; i <= 90 ; i++ ) { %>
            <%= String.fromCharCode(i) %>
          <% } %>

        <% for ( i = 0 ; i <= this.ROWS ; i++ ) { %>

            <%= i %>
            <% for ( var j = 0 ; j <= 25 ; j++ ) { %>
              <%= this.cell(i, j) %>
            <% } %>

        <% } %>

    */}
  ]
});
<commit_msg>Cleanup.<commit_after>/**
 * @license
 * Copyright 2015 Google Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// TODO: Create a Range Model?
/*
MODEL({
  package: 'foam.demos.sevenguis',
  name: 'CellParser',
  extendsModel: 'foam.parse.Grammar',

  methods: {
*/

var CellParser = {
  __proto__: grammar,

  START: alt(
    sym('number'),
    sym('formula'),
    sym('string')
  ),

  formula: seq1(1, '=', sym('expr')),

  expr: alt(
    sym('number'),
    sym('cell'),
    sym('add'),
    sym('sub'),
    sym('mul'),
    sym('div'),
    sym('mod'),
    sym('sum'),
    sym('prod')
  ),

  add:  seq(literal_ic('add('),  sym('expr'), ',', sym('expr'), ')'),
  sub:  seq(literal_ic('sub('),  sym('expr'), ',', sym('expr'), ')'),
  mul:  seq(literal_ic('mul('),  sym('expr'), ',', sym('expr'), ')'),
  div:  seq(literal_ic('div('),  sym('expr'), ',', sym('expr'), ')'),
  mod:  seq(literal_ic('mod('),  sym('expr'), ',', sym('expr'), ')'),
  sum:  seq(literal_ic('sum('),  sym('range'), ')'),
  prod: seq(literal_ic('prod('), sym('range'), ')'),

  range: seq(sym('col'), sym('row'), ',', sym('col'), sym('row')),

  digit: range('0', '9'),

  number: str(seq(
    optional('-'),
    str(alt(
      seq(str(repeat(sym('digit'))), '.', str(plus(sym('digit')))),
      plus(sym('digit')))))),

  cell: seq(sym('col'), sym('row')),

  col: alt(sym('az'), sym('AZ')),

  az: range('a', 'z'),

  AZ: range('A', 'Z'),

  row: str(repeat(sym('digit'), null, 1, 2)),

  string: str(repeat(anyChar))
}.addActions({
  add: function(a) { return function(cs) { return a[1](cs) + a[3](cs); }; },
  sub: function(a) { return function(cs) { return a[1](cs) - a[3](cs); }; },
  mul: function(a) { return function(cs) { return a[1](cs) * a[3](cs); }; },
  div: function(a) { return function(cs) { return a[1](cs) / a[3](cs); }; },
  mod: function(a) { return function(cs) { return a[1](cs) % a[3](cs); }; },
  sum: function(a) { return function(cs) {
    var arr = a[1](cs), sum = 0;
    for ( var i = 0 ; i < arr.length ; i++ ) sum += arr[i];
    return sum;
  }; },
  prod: function(a) { return function(cs) {
    var arr = a[1](cs), prod = 1;
    for ( var i = 0 ; i < arr.length ; i++ ) prod *= arr[i];
    return prod;
  }; },
  az:  function(c) { return c.charCodeAt(0) - 'a'.charCodeAt(0); },
  AZ:  function(c) { return c.charCodeAt(0) - 'A'.charCodeAt(0); },
  row: function(c) { return parseInt(c); },
  number: function(s) { var f = parseFloat(s); return function() { return f; }; },
  cell: function(a) { return function(cs) { return cs.cell(a[1], a[0]).value; }; },
  range: function(a) {
    var c1 = a[0], r1 = a[1], c2 = a[3], r2 = a[4];
    return function(cs) {
      var ret = [];
      for ( var c = c1 ; c <= c2; c++ )
        for ( var r = r1 ; r <= r2 ; r++ )
          ret.push(cs.cell(r, c).value);
      return ret;
    }
  },
  string: function(s) { return function() { return s; }; }
});
//});

// https://www.artima.com/pins1ed/the-scells-spreadsheet.html
MODEL({
  package: 'foam.demos.sevenguis',
  name: 'Cell',
  extendsModel: 'foam.ui.View',
  imports: [ 'cells' ],
  properties: [
    {
      name: 'formula',
      displayWidth: 10
    },
    {
      name: 'value',
      defaultValue: ' ',
      displayWidth: 12
    }
  ],
  methods: [
    function initHTML() {
      this.SUPER();

      this.valueView.$.addEventListener('click',  this.onClick);
      this.formulaView.$.addEventListener('blur', this.onBlur);
      this.formula$.addListener(this.onBlur);
    }
  ],
  listeners: [
    {
      name: 'onClick',
      code: function() {
        DOM.setClass(this.$, 'formula', true);
        this.formulaView.$.focus();
      }
    },
    {
      name: 'onBlur',
      code: function() {
        DOM.setClass(this.$, 'formula', false);
      }
    }
  ],
  templates: [
    function CSS() {/*
      .cellView > span {
        display: block;
        padding: 2px;
        width: 100%;
      }
      .cellView > input {
        border:  none;
        display: none;
        margin-left: 2px;
        outline: none;
      }
      .cellView {
        outline: 1px solid white;
      }
      .cellView.formula {
        outline: 1px solid blue;
      }
      .cellView.formula > input {
        display: inherit;
      }
      .cellView.formula > span {
        display: none;
      }
    */},
    function toHTML() {/*

$$formula $$value{mode: 'read-only', escapeHTML: false}

    */}
  ]
});

MODEL({
  package: 'foam.demos.sevenguis',
  name: 'Cells',
  extendsModel: 'foam.ui.View',
  requires: [
//    'foam.demos.sevenguis.CellParser',
    'foam.demos.sevenguis.Cell'
  ],
  imports: [ 'dynamic' ],
  exports: [ 'as cells' ],
  constants: {
    ROWS: 20 /* 99 */
  },
  properties: [
    {
      name: 'cells',
      factory: function() { return {}; }
    },
    {
      name: 'parser',
      factory: function() { return /*this.*/CellParser/*.create()*/; }
    }
  ],
  methods: [
    function init() {
      this.SUPER();

      // Load a Test Spreadsheet
      var row = 1;
      var self = this;
      function t(s) {
        try {
          var r = row++;
          self.cell(r, 0).formula = ' ' + s;
          self.cell(r, 1).formula = s;
        } catch (x) {
        }
      }

      this.cell(0,0).formula = 'Formulas';
      this.cell(0,1).formula = 'Values';

      t('1');
      t('10');
      t('10.12');
      t('-10.1');
      t('foobar');
      t('=add(1,2)');
      t('=sub(2,1)');
      t('=mul(2,3)');
      t('=div(9,3)');
      t('=mod(8,3)');
      t('=add(mul(2,3),div(3,2))');
      t('=A1');
      t('=add(A1,B1)');
      t('=sum(B6,B10)');
      t('=prod(B6,B10)');
    },
    function cell(r, c) {
      var self = this;
      var row  = this.cells[r] || ( this.cells[r] = {} );
      var cell = row[c];
      if ( ! cell ) {
        cell = row[c] = this.Cell.create();
        cell.formula$.addListener(function(_, _, _, formula) {
//          console.log('formula: ', r, c, formula);
          var f = self.parser.parseString(formula);
          self.dynamic(f.bind(null, self), function(v) {
            cell.value = v;
//            console.log('v:', v);
          });
        });
      }
      return cell;
    }
  ],
  templates: [
    function CSS() {/*
      .cells tr, .cells td, .cells th, .cells input {
        color: #333;
        font: 13px roboto, arial, sans-serif;
      }
      .cells tr { height: 26px; }
      .cells { overflow: auto; }
      .cell { min-width: 100px; }
      table.cells, .cells th, .cells td {
        border: 1px solid #ccc;
        border-right: none;
        border-bottom: none;
      }
      .cells td {
        height: 100%;
      }
      .cells th {
        background: #eee;
        color: #333;
        padding: 2px 18px;
      }
    */},
    function toHTML() {/*

          <% for ( var i = 65 ; i <= 90 ; i++ ) { %>
            <%= String.fromCharCode(i) %>
          <% } %>

        <% for ( i = 0 ; i <= this.ROWS ; i++ ) { %>

            <%= i %>
            <% for ( var j = 0 ; j <= 25 ; j++ ) { %>
              <%= this.cell(i, j) %>
            <% } %>

        <% } %>

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


<commit_before>/**
 * Licensed under the Apache License, Version 2.0 (the 'License');
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an 'AS IS' BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

goog.provide('org.apache.flex.binding.WatcherBase');

/**
 * @constructor
 */
org.apache.flex.binding.WatcherBase = function() {

  /**
     * @protected
     * @type {Object}
     */
  this.listeners;

  /**
     * @protected
     * @type {Object}
     * Children of this watcher are watching sub values.
     */
  this.children;
};

/**
 *  @expose
 *  The value itself.
 */
org.apache.flex.binding.WatcherBase.prototype.value;

/**
 *  @expose
 *  This is an abstract method that subclasses implement.
 *  @this {org.apache.flex.binding.WatcherBase}
 *  @param {Object} parent The new parent.
 */
org.apache.flex.binding.WatcherBase.prototype.parentChanged =
    function(parent) {
};

/**
 *  @expose
 *  Add a child to this watcher, meaning that the child
 *  is watching a sub value of ours.
 *  @this {org.apache.flex.binding.WatcherBase}
 *  @param {Object} child The new child.
 */
org.apache.flex.binding.WatcherBase.prototype.addChild =
    function(child) {
  if (!this.children)
    this.children = [child];
  else
    this.children.push(child);

  child.parentChanged(this);
};

/**
 *  @expose
 *  Add a binding to this watcher, meaning that the binding
 *  is notified when our value changes.
 *  @this {org.apache.flex.binding.WatcherBase}
 *  @param {Object} binding The new binding.
 */
org.apache.flex.binding.WatcherBase.prototype.addBinding =
    function(binding) {
  if (!this.listeners)
    this.listeners = [binding];
  else
    this.listeners.push(binding);

  binding.valueChanged(this.value);
};

/**
 *  @expose
 *  @this {org.apache.flex.binding.WatcherBase}
 *  We have probably changed, so go through
 *  and make sure our children are updated.
 */
org.apache.flex.binding.WatcherBase.prototype.updateChildren = function() {
  if (this.children)
  {
    var n = this.children.length;
    for (var i = 0; i < n; ++i)
    {
      this.children[i].parentChanged(this);
    }
  }
};

/**
 *  @protected
 *  @this {org.apache.flex.binding.WatcherBase}
 *  @param {Object} oldValue The prior value.
 *  @return {boolean} True if value changed.
 */
org.apache.flex.binding.WatcherBase.prototype.valueChanged =
    function(oldValue) {

  if (oldValue == null && this.value == null)
    return false;

  var valType = typeof(this.value);

  // The first check is meant to catch the delayed instantiation case
  // where a control comes into existence but its value is still
  // the equivalent of not having been filled in.
  // Otherwise we simply return whether the value has changed.

  if (valType == 'string')
  {
    if (oldValue == null && this.value == '')
      return false;
    else
      return oldValue != this.value;
  }

  if (valType == 'number')
  {
    if (oldValue == null && this.value == 0)
      return false;
    else
      return oldValue != this.value;
  }

  if (valType == 'boolean')
  {
    if (oldValue == null && this.value == false)
      return false;
    else
      return oldValue != this.value;
  }

  return true;
};

/**
 *  @protected
 *  @this {org.apache.flex.binding.WatcherBase}
 *  @param {function} wrappedFunction The function to call.
 */
org.apache.flex.binding.WatcherBase.prototype.wrapUpdate =
    function(wrappedFunction) {
  try
  {
    wrappedFunction.apply(this);
  }
  catch (error)
  {
    var staticClass = org.apache.flex.binding.WatcherBase;
    var n = this.allowedErrorTypes.length;
    for (var i = 0; i < n; i++)
    {
      if (error.constructor == allowedErrorTypes[i].type)
      {
        var handler = staticClass.allowedErrorTypes[i].handler;
        if (handler != null)
          this.value = handler(this, wrappedFunction);
        else
          this.value = null;
      }
    }

    if (staticClass.allowedErrors.indexOf(error.errorID) == -1)
      throw error;
  }
};

/**
 * Certain errors are normal when executing an update, so we swallow them:
 */
org.apache.flex.binding.WatcherBase.allowedErrors = [
  1006, //   Error #1006: Call attempted on an object
  //                that is not a function.
  1009, //   Error #1009: null has no properties.
  1010, //   Error #1010: undefined has no properties.
  1055, //   Error #1055: - has no properties.
  1069, //   Error #1069: Property - not found on - and
  //                there is no default value
  1507 //   Error #1507: - invalid null argument.
];

/**
 * Certain types of errors are normal when executing an update,
 * so we custom handle them or swallow them:
 */
org.apache.flex.binding.WatcherBase.allowedErrorTypes = [
  { type: RangeError /*,
              handler: function(w:WatcherBase,
                    wrappedFunction:Function):Object { return null }*/
  }
];

/**
 *  @protected
 *  @this {org.apache.flex.binding.WatcherBase}
 */
org.apache.flex.binding.WatcherBase.prototype.notifyListeners = function()
    {
  if (this.listeners)
  {
    var n = this.listeners.length;

    for (var i = 0; i < n; i++)
    {
      this.listeners[i].valueChanged(this.value);
    }
  }
};
<commit_msg>JSHint: fixed 'implied global' error.<commit_after>/**
 * Licensed under the Apache License, Version 2.0 (the 'License');
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an 'AS IS' BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

goog.provide('org.apache.flex.binding.WatcherBase');

/**
 * @constructor
 */
org.apache.flex.binding.WatcherBase = function() {

  /**
     * @protected
     * @type {Object}
     */
  this.listeners;

  /**
     * @protected
     * @type {Object}
     * Children of this watcher are watching sub values.
     */
  this.children;
};

/**
 *  @expose
 *  The value itself.
 */
org.apache.flex.binding.WatcherBase.prototype.value;

/**
 *  @expose
 *  This is an abstract method that subclasses implement.
 *  @this {org.apache.flex.binding.WatcherBase}
 *  @param {Object} parent The new parent.
 */
org.apache.flex.binding.WatcherBase.prototype.parentChanged =
    function(parent) {
};

/**
 *  @expose
 *  Add a child to this watcher, meaning that the child
 *  is watching a sub value of ours.
 *  @this {org.apache.flex.binding.WatcherBase}
 *  @param {Object} child The new child.
 */
org.apache.flex.binding.WatcherBase.prototype.addChild =
    function(child) {
  if (!this.children)
    this.children = [child];
  else
    this.children.push(child);

  child.parentChanged(this);
};

/**
 *  @expose
 *  Add a binding to this watcher, meaning that the binding
 *  is notified when our value changes.
 *  @this {org.apache.flex.binding.WatcherBase}
 *  @param {Object} binding The new binding.
 */
org.apache.flex.binding.WatcherBase.prototype.addBinding =
    function(binding) {
  if (!this.listeners)
    this.listeners = [binding];
  else
    this.listeners.push(binding);

  binding.valueChanged(this.value);
};

/**
 *  @expose
 *  @this {org.apache.flex.binding.WatcherBase}
 *  We have probably changed, so go through
 *  and make sure our children are updated.
 */
org.apache.flex.binding.WatcherBase.prototype.updateChildren = function() {
  if (this.children)
  {
    var n = this.children.length;
    for (var i = 0; i < n; ++i)
    {
      this.children[i].parentChanged(this);
    }
  }
};

/**
 *  @protected
 *  @this {org.apache.flex.binding.WatcherBase}
 *  @param {Object} oldValue The prior value.
 *  @return {boolean} True if value changed.
 */
org.apache.flex.binding.WatcherBase.prototype.valueChanged =
    function(oldValue) {

  if (oldValue == null && this.value == null)
    return false;

  var valType = typeof(this.value);

  // The first check is meant to catch the delayed instantiation case
  // where a control comes into existence but its value is still
  // the equivalent of not having been filled in.
  // Otherwise we simply return whether the value has changed.

  if (valType == 'string')
  {
    if (oldValue == null && this.value == '')
      return false;
    else
      return oldValue != this.value;
  }

  if (valType == 'number')
  {
    if (oldValue == null && this.value == 0)
      return false;
    else
      return oldValue != this.value;
  }

  if (valType == 'boolean')
  {
    if (oldValue == null && this.value == false)
      return false;
    else
      return oldValue != this.value;
  }

  return true;
};

/**
 *  @protected
 *  @this {org.apache.flex.binding.WatcherBase}
 *  @param {function} wrappedFunction The function to call.
 */
org.apache.flex.binding.WatcherBase.prototype.wrapUpdate =
    function(wrappedFunction) {
  try
  {
    wrappedFunction.apply(this);
  }
  catch (error)
  {
    var staticClass = org.apache.flex.binding.WatcherBase;
    var n = this.allowedErrorTypes.length;
    for (var i = 0; i < n; i++)
    {
      if (error.constructor == this.allowedErrorTypes[i].type)
      {
        var handler = staticClass.allowedErrorTypes[i].handler;
        if (handler != null)
          this.value = handler(this, wrappedFunction);
        else
          this.value = null;
      }
    }

    if (staticClass.allowedErrors.indexOf(error.errorID) == -1)
      throw error;
  }
};

/**
 * Certain errors are normal when executing an update, so we swallow them:
 */
org.apache.flex.binding.WatcherBase.allowedErrors = [
  1006, //   Error #1006: Call attempted on an object
  //                that is not a function.
  1009, //   Error #1009: null has no properties.
  1010, //   Error #1010: undefined has no properties.
  1055, //   Error #1055: - has no properties.
  1069, //   Error #1069: Property - not found on - and
  //                there is no default value
  1507 //   Error #1507: - invalid null argument.
];

/**
 * Certain types of errors are normal when executing an update,
 * so we custom handle them or swallow them:
 */
org.apache.flex.binding.WatcherBase.allowedErrorTypes = [
  { type: RangeError /*,
              handler: function(w:WatcherBase,
                    wrappedFunction:Function):Object { return null }*/
  }
];

/**
 *  @protected
 *  @this {org.apache.flex.binding.WatcherBase}
 */
org.apache.flex.binding.WatcherBase.prototype.notifyListeners = function()
    {
  if (this.listeners)
  {
    var n = this.listeners.length;

    for (var i = 0; i < n; i++)
    {
      this.listeners[i].valueChanged(this.value);
    }
  }
};
<|endoftext|>


<commit_before>import THREE from 'three';
import PropTypes from 'react/lib/ReactPropTypes';

import Object3DDescriptor from '../Object3DDescriptor';
import propTypeInstanceOf from '../../../utils/propTypeInstanceOf';

class GridHelperDescriptor extends Object3DDescriptor {
  constructor(react3Instance) {
    super(react3Instance);

    this.hasProp('size', {
      type: PropTypes.number.isRequired,
      update: this.triggerRemount,
      default: 1,
    });

    this.hasProp('step', {
      type: PropTypes.number,
      update: this.triggerRemount,
      default: 1,
    });

    this.hasProp('colorCenterLine', {
      type: PropTypes.oneOfType([
        propTypeInstanceOf(THREE.Color),
        PropTypes.number,
        PropTypes.string,
      ]),
      update: (grid, color) => {
        grid.setColors(color, grid.color2);
      },
      default: 0x444444,
      updateInitial: true,
    });

    this.hasProp('colorGrid', {
      type: PropTypes.oneOfType([
        propTypeInstanceOf(THREE.Color),
        PropTypes.number,
        PropTypes.string,
      ]),
      update: (grid, color) => {
        grid.setColors(grid.color1, color);
      },
      default: 0x888888,
      updateInitial: true,
    });
  }

  applyInitialProps(threeObject: THREE.Object3D, props) {
    super.applyInitialProps(threeObject, props);
  }

  construct(props) {
    const {
      size,
      step,
    } = props;
    return new THREE.GridHelper(size, step);
  }

  unmount(threeObject) {
    threeObject.geometry.dispose();
    threeObject.material.dispose();

    super.unmount(threeObject);
  }
}

module.exports = GridHelperDescriptor;
<commit_msg>[components] Fix bug that would use deprecated function for setColors for gridHelper<commit_after>import THREE from 'three';
import PropTypes from 'react/lib/ReactPropTypes';

import Object3DDescriptor from '../Object3DDescriptor';
import propTypeInstanceOf from '../../../utils/propTypeInstanceOf';

class GridHelperDescriptor extends Object3DDescriptor {
  constructor(react3Instance) {
    super(react3Instance);

    this.hasProp('size', {
      type: PropTypes.number.isRequired,
      update: this.triggerRemount,
      default: 1,
    });

    this.hasProp('step', {
      type: PropTypes.number,
      update: this.triggerRemount,
      default: 1,
    });

    this.hasProp('colorCenterLine', {
      type: PropTypes.oneOfType([
        propTypeInstanceOf(THREE.Color),
        PropTypes.number,
        PropTypes.string,
      ]),
      update: this.triggerRemount,
      default: 0x444444,
    });

    this.hasProp('colorGrid', {
      type: PropTypes.oneOfType([
        propTypeInstanceOf(THREE.Color),
        PropTypes.number,
        PropTypes.string,
      ]),
      update: this.triggerRemount,
      default: 0x888888,
    });
  }

  applyInitialProps(threeObject: THREE.Object3D, props) {
    super.applyInitialProps(threeObject, props);
  }

  construct(props) {
    const {
      size,
      step,
    } = props;
    return new THREE.GridHelper(size, step);
  }

  unmount(threeObject) {
    threeObject.geometry.dispose();
    threeObject.material.dispose();

    super.unmount(threeObject);
  }
}

module.exports = GridHelperDescriptor;
<|endoftext|>


<commit_before>/**
 * @license
 * Blockly Tests
 *
 * Copyright 2017 Google Inc.
 * https://developers.google.com/blockly/
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
'use strict';

goog.require('goog.testing');
goog.require('goog.testing.MockControl');

var workspace;
//var mockControl_;

function procedureTest_setUp() {
  Blockly.Blocks['procedure_callnoreturn'] = {
    init: function() {
      this.procCode_ = '';
      this.setPreviousStatement(true);
      this.setNextStatement(true);
    },
    getProcCode: function() {
      return this.procCode_;
    }
  };
  Blockly.Blocks['foo'] = {
    init: function() {
      this.jsonInit({
        "message0": "foo",
        "previousStatement": null,
        "nextStatement": null
      });
      this.setNextStatement(true);
    }
  };
  Blockly.Blocks['loop'] = {
    init: function() {
      this.jsonInit({ message0: 'forever %1',
      "args0": [
        {
          "type": "input_statement",
          "name": "SUBSTACK"
        }
      ]});
    }
  };

  workspace = new Blockly.Workspace();
  //mockControl_ = new goog.testing.MockControl();
}

function procedureTest_tearDown() {
  delete Blockly.Blocks['procedure_callnoreturn'];
  delete Blockly.Blocks['foo'];
  delete Blockly.Blocks['loop'];
  //mockControl_.$tearDown();
  workspace.dispose();
}

function test_findCallers_simple_oneCaller() {
  var xml = '<xml xmlns="http://www.w3.org/1999/xhtml">' +
    '<variables></variables>' +
    '<block type="procedure_callnoreturn" id="test_1" x="301" y="516">' +
    '</block>' +
  '</xml>';
  procedureTest_setUp();
  try {
    Blockly.Xml.domToWorkspace(Blockly.Xml.textToDom(xml), workspace);
    workspace.getBlockById('test_1').procCode_ = 'test_procedure';
    var callers = Blockly.Procedures.getCallers('test_procedure', workspace,
        {id: ''}, false);
    assertEquals(1, callers.length);
    assertEquals('test_1', callers[0].id);
  }
  finally {
    procedureTest_tearDown();
  }
}

function test_findCallers_noRecursion() {
  var xml = '<xml xmlns="http://www.w3.org/1999/xhtml">' +
    '<variables></variables>' +
    '<block type="procedure_callnoreturn" id="test_1" x="301" y="516">' +
    '</block>' +
  '</xml>';
  procedureTest_setUp();
  try {
    Blockly.Xml.domToWorkspace(Blockly.Xml.textToDom(xml), workspace);
    workspace.getBlockById('test_1').procCode_ = 'test_procedure';
    var rootBlock = workspace.getBlockById('test_1');
    var callers = Blockly.Procedures.getCallers('test_procedure', workspace,
        rootBlock, false /* allowRecursion */);

    // There was a single call to this function, but it was in a stack that
    // should be ignored.
    assertEquals(0, callers.length);
  }
  finally {
    procedureTest_tearDown();
  }
}

function test_findCallers_allowRecursion() {
  var xml = '<xml xmlns="http://www.w3.org/1999/xhtml">' +
    '<variables></variables>' +
    '<block type="procedure_callnoreturn" id="test_1" x="301" y="516">' +
    '</block>' +
  '</xml>';
  procedureTest_setUp();
  try {
    Blockly.Xml.domToWorkspace(Blockly.Xml.textToDom(xml), workspace);
    workspace.getBlockById('test_1').procCode_ = 'test_procedure';
    var rootBlock = workspace.getBlockById('test_1');
    var callers = Blockly.Procedures.getCallers('test_procedure', workspace,
        rootBlock, true /* allowRecursion */);

    // There was a single call to this function, in the same stack as the
    // definition root.  Recursion is allowed, so it should be found.
    assertEquals(1, callers.length);
    assertEquals('test_1', callers[0].id);
  }
  finally {
    procedureTest_tearDown();
  }
}

function test_findCallers_simple_noCallers() {
  var xml = '<xml xmlns="http://www.w3.org/1999/xhtml">' +
    '<variables></variables>' +
    '<block type="foo" id="test_1" x="301" y="516">' +
    '</block>' +
  '</xml>';
  procedureTest_setUp();
  try {
    Blockly.Xml.domToWorkspace(Blockly.Xml.textToDom(xml), workspace);
    var callers = Blockly.Procedures.getCallers('test_procedure', workspace,
        {id: ''}, false);

    // There weren't even blocks of type procedure_callnoreturn.
    assertEquals(0, callers.length);
  }
  finally {
    procedureTest_tearDown();
  }
}

function test_findCallers_wrongProcCode() {
  var xml = '<xml xmlns="http://www.w3.org/1999/xhtml">' +
    '<variables></variables>' +
    '<block type="procedure_callnoreturn" id="test_1" x="301" y="516">' +
    '</block>' +
  '</xml>';
  procedureTest_setUp();
  try {
    Blockly.Xml.domToWorkspace(Blockly.Xml.textToDom(xml), workspace);
    workspace.getBlockById('test_1').procCode_ = 'wrong procedure';
    var callers = Blockly.Procedures.getCallers('test_procedure', workspace,
        {id: ''}, false);

    // There was a procedure_callnoreturn call, but it had the wrong procCode.
    assertEquals(0, callers.length);
  }
  finally {
    procedureTest_tearDown();
  }
}

function test_findCallers_onStatementInput() {
  var xml = '<xml xmlns="http://www.w3.org/1999/xhtml">' +
    '<block type="loop" id="test_1">' +
      '<statement name="SUBSTACK">' +
        '<block type="foo" id="test_2">' +
          '<next>' +
            '<block type="procedure_callnoreturn" id="test_3"></block>' +
          '</next></block>' +
      '</statement>' +
    '</block>' +
  '</xml>';
  procedureTest_setUp();
  try {
    Blockly.Xml.domToWorkspace(Blockly.Xml.textToDom(xml), workspace);
    workspace.getBlockById('test_3').procCode_ = 'test_procedure';
    var callers = Blockly.Procedures.getCallers('test_procedure', workspace,
        {id: ''}, false);

    // There should be one caller, connected to a stack on a statement input.
    assertEquals(1, callers.length);
    assertEquals('test_3', callers[0].id);
  }
  finally {
    procedureTest_tearDown();
  }
}

function test_findCallers_multipleStacks() {
  var xml = '<xml xmlns="http://www.w3.org/1999/xhtml">' +
    '<block type="foo" id="test_1"></block>' +
    '<block type="procedure_callnoreturn" id="test_2"></block>'+
    '<block type="foo" id="test_1"></block>' +
  '</xml>';
  procedureTest_setUp();
  try {
    Blockly.Xml.domToWorkspace(Blockly.Xml.textToDom(xml), workspace);
    workspace.getBlockById('test_2').procCode_ = 'test_procedure';
    var callers = Blockly.Procedures.getCallers('test_procedure', workspace,
        {id: ''}, false);

    // There should be one caller, but multiple stacks in the workspace.
    assertEquals(1, callers.length);
    assertEquals('test_2', callers[0].id);
  }
  finally {
    procedureTest_tearDown();
  }
}

function test_findCallers_multipleCallers() {
  var xml = '<xml xmlns="http://www.w3.org/1999/xhtml">' +
    '<block type="procedure_callnoreturn" id="test_1"></block>' +
    '<block type="procedure_callnoreturn" id="test_2"></block>'+
  '</xml>';
  procedureTest_setUp();
  try {
    Blockly.Xml.domToWorkspace(Blockly.Xml.textToDom(xml), workspace);
    workspace.getBlockById('test_2').procCode_ = 'test_procedure';
    workspace.getBlockById('test_1').procCode_ = 'test_procedure';
    var callers = Blockly.Procedures.getCallers('test_procedure', workspace,
        {id: ''}, false);

    // There should be two callers, on two different stacks.
    assertEquals(2, callers.length);
    // Order doesn't matter.
    assertTrue(callers[0].id == 'test_1' || callers[0].id == 'test_2');
    assertTrue(callers[1].id == 'test_1' || callers[1].id == 'test_2');
  }
  finally {
    procedureTest_tearDown();
  }
}
<commit_msg>Fix spelling in test<commit_after>/**
 * @license
 * Blockly Tests
 *
 * Copyright 2017 Google Inc.
 * https://developers.google.com/blockly/
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
'use strict';

goog.require('goog.testing');
goog.require('goog.testing.MockControl');

var workspace;
//var mockControl_;

function procedureTest_setUp() {
  Blockly.Blocks['procedures_callnoreturn'] = {
    init: function() {
      this.procCode_ = '';
      this.setPreviousStatement(true);
      this.setNextStatement(true);
    },
    getProcCode: function() {
      return this.procCode_;
    }
  };
  Blockly.Blocks['foo'] = {
    init: function() {
      this.jsonInit({
        "message0": "foo",
        "previousStatement": null,
        "nextStatement": null
      });
      this.setNextStatement(true);
    }
  };
  Blockly.Blocks['loop'] = {
    init: function() {
      this.jsonInit({ message0: 'forever %1',
      "args0": [
        {
          "type": "input_statement",
          "name": "SUBSTACK"
        }
      ]});
    }
  };

  workspace = new Blockly.Workspace();
  //mockControl_ = new goog.testing.MockControl();
}

function procedureTest_tearDown() {
  delete Blockly.Blocks['procedures_callnoreturn'];
  delete Blockly.Blocks['foo'];
  delete Blockly.Blocks['loop'];
  //mockControl_.$tearDown();
  workspace.dispose();
}

function test_findCallers_simple_oneCaller() {
  var xml = '<xml xmlns="http://www.w3.org/1999/xhtml">' +
    '<variables></variables>' +
    '<block type="procedures_callnoreturn" id="test_1" x="301" y="516">' +
    '</block>' +
  '</xml>';
  procedureTest_setUp();
  try {
    Blockly.Xml.domToWorkspace(Blockly.Xml.textToDom(xml), workspace);
    workspace.getBlockById('test_1').procCode_ = 'test_procedure';
    var callers = Blockly.Procedures.getCallers('test_procedure', workspace,
        {id: ''}, false);
    assertEquals(1, callers.length);
    assertEquals('test_1', callers[0].id);
  }
  finally {
    procedureTest_tearDown();
  }
}

function test_findCallers_noRecursion() {
  var xml = '<xml xmlns="http://www.w3.org/1999/xhtml">' +
    '<variables></variables>' +
    '<block type="procedures_callnoreturn" id="test_1" x="301" y="516">' +
    '</block>' +
  '</xml>';
  procedureTest_setUp();
  try {
    Blockly.Xml.domToWorkspace(Blockly.Xml.textToDom(xml), workspace);
    workspace.getBlockById('test_1').procCode_ = 'test_procedure';
    var rootBlock = workspace.getBlockById('test_1');
    var callers = Blockly.Procedures.getCallers('test_procedure', workspace,
        rootBlock, false /* allowRecursion */);

    // There was a single call to this function, but it was in a stack that
    // should be ignored.
    assertEquals(0, callers.length);
  }
  finally {
    procedureTest_tearDown();
  }
}

function test_findCallers_allowRecursion() {
  var xml = '<xml xmlns="http://www.w3.org/1999/xhtml">' +
    '<variables></variables>' +
    '<block type="procedures_callnoreturn" id="test_1" x="301" y="516">' +
    '</block>' +
  '</xml>';
  procedureTest_setUp();
  try {
    Blockly.Xml.domToWorkspace(Blockly.Xml.textToDom(xml), workspace);
    workspace.getBlockById('test_1').procCode_ = 'test_procedure';
    var rootBlock = workspace.getBlockById('test_1');
    var callers = Blockly.Procedures.getCallers('test_procedure', workspace,
        rootBlock, true /* allowRecursion */);

    // There was a single call to this function, in the same stack as the
    // definition root.  Recursion is allowed, so it should be found.
    assertEquals(1, callers.length);
    assertEquals('test_1', callers[0].id);
  }
  finally {
    procedureTest_tearDown();
  }
}

function test_findCallers_simple_noCallers() {
  var xml = '<xml xmlns="http://www.w3.org/1999/xhtml">' +
    '<variables></variables>' +
    '<block type="foo" id="test_1" x="301" y="516">' +
    '</block>' +
  '</xml>';
  procedureTest_setUp();
  try {
    Blockly.Xml.domToWorkspace(Blockly.Xml.textToDom(xml), workspace);
    var callers = Blockly.Procedures.getCallers('test_procedure', workspace,
        {id: ''}, false);

    // There weren't even blocks of type procedures_callnoreturn.
    assertEquals(0, callers.length);
  }
  finally {
    procedureTest_tearDown();
  }
}

function test_findCallers_wrongProcCode() {
  var xml = '<xml xmlns="http://www.w3.org/1999/xhtml">' +
    '<variables></variables>' +
    '<block type="procedures_callnoreturn" id="test_1" x="301" y="516">' +
    '</block>' +
  '</xml>';
  procedureTest_setUp();
  try {
    Blockly.Xml.domToWorkspace(Blockly.Xml.textToDom(xml), workspace);
    workspace.getBlockById('test_1').procCode_ = 'wrong procedure';
    var callers = Blockly.Procedures.getCallers('test_procedure', workspace,
        {id: ''}, false);

    // There was a procedure_callnoreturn call, but it had the wrong procCode.
    assertEquals(0, callers.length);
  }
  finally {
    procedureTest_tearDown();
  }
}

function test_findCallers_onStatementInput() {
  var xml = '<xml xmlns="http://www.w3.org/1999/xhtml">' +
    '<block type="loop" id="test_1">' +
      '<statement name="SUBSTACK">' +
        '<block type="foo" id="test_2">' +
          '<next>' +
            '<block type="procedures_callnoreturn" id="test_3"></block>' +
          '</next></block>' +
      '</statement>' +
    '</block>' +
  '</xml>';
  procedureTest_setUp();
  try {
    Blockly.Xml.domToWorkspace(Blockly.Xml.textToDom(xml), workspace);
    workspace.getBlockById('test_3').procCode_ = 'test_procedure';
    var callers = Blockly.Procedures.getCallers('test_procedure', workspace,
        {id: ''}, false);

    // There should be one caller, connected to a stack on a statement input.
    assertEquals(1, callers.length);
    assertEquals('test_3', callers[0].id);
  }
  finally {
    procedureTest_tearDown();
  }
}

function test_findCallers_multipleStacks() {
  var xml = '<xml xmlns="http://www.w3.org/1999/xhtml">' +
    '<block type="foo" id="test_1"></block>' +
    '<block type="procedures_callnoreturn" id="test_2"></block>'+
    '<block type="foo" id="test_1"></block>' +
  '</xml>';
  procedureTest_setUp();
  try {
    Blockly.Xml.domToWorkspace(Blockly.Xml.textToDom(xml), workspace);
    workspace.getBlockById('test_2').procCode_ = 'test_procedure';
    var callers = Blockly.Procedures.getCallers('test_procedure', workspace,
        {id: ''}, false);

    // There should be one caller, but multiple stacks in the workspace.
    assertEquals(1, callers.length);
    assertEquals('test_2', callers[0].id);
  }
  finally {
    procedureTest_tearDown();
  }
}

function test_findCallers_multipleCallers() {
  var xml = '<xml xmlns="http://www.w3.org/1999/xhtml">' +
    '<block type="procedures_callnoreturn" id="test_1"></block>' +
    '<block type="procedures_callnoreturn" id="test_2"></block>'+
  '</xml>';
  procedureTest_setUp();
  try {
    Blockly.Xml.domToWorkspace(Blockly.Xml.textToDom(xml), workspace);
    workspace.getBlockById('test_2').procCode_ = 'test_procedure';
    workspace.getBlockById('test_1').procCode_ = 'test_procedure';
    var callers = Blockly.Procedures.getCallers('test_procedure', workspace,
        {id: ''}, false);

    // There should be two callers, on two different stacks.
    assertEquals(2, callers.length);
    // Order doesn't matter.
    assertTrue(callers[0].id == 'test_1' || callers[0].id == 'test_2');
    assertTrue(callers[1].id == 'test_1' || callers[1].id == 'test_2');
  }
  finally {
    procedureTest_tearDown();
  }
}
<|endoftext|>


<commit_before>function IntroGameState(){

	var logo1, anim1_up, anim1_down, logo2, anim2_up, anim2_down, waitTimer;

	this.setup = function(){

		//DACKMIN logo
		logo1 = new FF.Sprite({ image : "res/img/logos/dackmin.png" });
		logo1.x = FF.Render.getWidth() / 2  - logo1.rect().width / 2;
		logo1.y = FF.Render.getHeight() / 2  - logo1.rect().height / 2;
		logo1.alpha = 0;

		anim1_up = new FF.Animation(logo1, 500, { opacity : 1 });
		anim1_up.addEventListener("end", function(){
			setTimeout(function(){ anim1_down.start(); }, 2000);
		});

		anim1_down = new FF.Animation(logo1, 500, { opacity:0 });
		anim1_down.addEventListener("end", function(){
			anim2_up.start();
		});

		//FRESHFLESH LOGO
		logo2 = new FF.Sprite({ image : "res/img/logos/freshflesh.png" });
		logo2.x = FF.Render.getWidth() / 2  - logo2.rect().width / 2;
		logo2.y = FF.Render.getHeight() / 2  - logo2.rect().height / 2;
		logo2.alpha = 0;

		anim2_up = new FF.Animation(logo2, 500, { opacity : 1 });
		anim2_up.addEventListener("end", function(){
			setTimeout(function(){ anim2_down.start(); }, 2000);
		});

		anim2_down = new FF.Animation(logo2, 500, { opacity:0 });
		anim2_down.addEventListener("end", function(){
		});

		anim1_up.start();
	};

	this.update = function(){
		anim1_up.update();
		anim1_down.update();
		anim2_up.update();
		anim2_down.update();
	};

	this.draw = function(){
		logo1.draw();
		logo2.draw();
	};

};
<commit_msg>Update positions using built-in function<commit_after>function IntroGameState(){

	var logo1, anim1_up, anim1_down, logo2, anim2_up, anim2_down, waitTimer;

	this.setup = function(){

		//DACKMIN logo
		logo1 = new FF.Sprite({ image : "res/img/logos/dackmin.png" });
		logo1.x = FF.Util.getCenterFromItem(logo1);
		logo1.y = FF.Util.getCenterFromItem(logo1, true);
		logo1.alpha = 0;

		anim1_up = new FF.Animation(logo1, 500, { opacity : 1 });
		anim1_up.addEventListener("end", function(){
			setTimeout(function(){ anim1_down.start(); }, 2000);
		});

		anim1_down = new FF.Animation(logo1, 500, { opacity:0 });
		anim1_down.addEventListener("end", function(){
			anim2_up.start();
		});

		//FRESHFLESH LOGO
		logo2 = new FF.Sprite({ image : "res/img/logos/freshflesh.png" });
		logo2.x = FF.Util.getCenterFromItem(logo2);
		logo2.y = FF.Util.getCenterFromItem(logo2, true);
		logo2.alpha = 0;

		anim2_up = new FF.Animation(logo2, 500, { opacity : 1 });
		anim2_up.addEventListener("end", function(){
			setTimeout(function(){ anim2_down.start(); }, 2000);
		});

		anim2_down = new FF.Animation(logo2, 500, { opacity:0 });
		anim2_down.addEventListener("end", function(){
			GAME.switchGameState(GS_MENU);
		});

		anim1_up.start();
	};

	this.update = function(){
		anim1_up.update();
		anim1_down.update();
		anim2_up.update();
		anim2_down.update();
	};

	this.draw = function(){
		logo1.draw();
		logo2.draw();
	};

};
<|endoftext|>


<commit_before>/**
 * Developer: Stepan Burguchev
 * Date: 12/3/2014
 * Copyright: 2009-2016 Comindware®
 *       All Rights Reserved
 * Published under the MIT license
 */

"use strict";

import '../../../../../libApi';
import { htmlHelpers } from '../../../../../utils/utilsApi';
import template from '../templates/listItem.hbs';
import list from '../../../../../list/listApi';

export default Marionette.ItemView.extend({
    initialize: function (options) {
        this.reqres = options.reqres;
    },

    behaviors: {
        ListItemViewBehavior: {
            behaviorClass: list.views.behaviors.ListItemViewBehavior
        }
    },

    className: 'dd-list__i',

    template: template,

    ui: {
        fullName: '.js-fullName'
    },

    templateHelpers: function () {
        return {
            text: this.__getText()
        };
    },

    __getText: function () {
        return this.model.get('fullName') || this.model.get('name');
    },

    onHighlighted: function (fragment)
    {
        var text = htmlHelpers.highlightText(this.__getText(), fragment);
        this.ui.fullName.html(text);
    },

    onUnhighlighted: function ()
    {
        this.ui.fullName.text(this.__getText());
    },

    events: {
        'click': '__select'
    },

    __select: function () {
        this.reqres.request('value:set', this.model.id);
    }
});
<commit_msg>fix member select<commit_after>/**
 * Developer: Stepan Burguchev
 * Date: 12/3/2014
 * Copyright: 2009-2016 Comindware®
 *       All Rights Reserved
 * Published under the MIT license
 */

"use strict";

import '../../../../../libApi';
import { htmlHelpers } from '../../../../../utils/utilsApi';
import template from '../templates/listItem.hbs';
import list from '../../../../../list/listApi';

export default Marionette.ItemView.extend({
    initialize: function (options) {
        this.reqres = options.reqres;
    },

    behaviors: {
        ListItemViewBehavior: {
            behaviorClass: list.views.behaviors.ListItemViewBehavior
        }
    },

    className: 'dd-list__i',

    template: template,

    ui: {
        fullName: '.js-fullName'
    },

    templateHelpers: function () {
        return {
            text: this.__getText()
        };
    },

    __getText: function () {
        return this.model.get('name') || this.model.get('userName');
    },

    onHighlighted: function (fragment)
    {
        var text = htmlHelpers.highlightText(this.__getText(), fragment);
        this.ui.fullName.html(text);
    },

    onUnhighlighted: function ()
    {
        this.ui.fullName.text(this.__getText());
    },

    events: {
        'click': '__select'
    },

    __select: function () {
        this.reqres.request('value:set', this.model.id);
    }
});
<|endoftext|>


<commit_before>/**
 * Module dependencies.
 */

var path = require('path');
var _ = require('lodash');
var express = require('express');

module.exports = function(sails) {

  var initialize = require('./initialize')(sails);

  /**
   * Expose `http` hook definition
   */

  return {

    defaults: function(config) {
      return {

        // Self-awareness: the host the server *thinks it is*
        // host: 'localhost',

        // Port to run this app on
        port: 1337,

        // Users' SSL cert settings end up here
        ssl: {},

        // HTTP cache configuration
        cache: {
          maxAge: config.environment === 'development' ? 1 : 31557600000
        },

        // Path static files will be served from
        // Uses `path.resolve()` to accept either:
        //  • an absolute path
        //  • a relative path from the app root (sails.config.appPath)
        paths: {
          public: '.tmp/public'
        },

        // New http-only middleware config
        // (provides default middleware)
        http: {
          middleware: {
            order: [
              'startRequestTimer',
              'cookieParser',
              'session',
              'bodyParser',
              'handleBodyParserError',
              'compress',
              'methodOverride',
              'poweredBy',
              '$custom',
              'router',
              'www',
              'favicon',
              '404',
              '500'
            ],

            // Default middleware definitions are injected
            // after the `app` object is available.
            // (see `loadMiddleware.js` and `middleware.js`)
            // e.g.:
            // session: {
            //   options: {},
            //   fn: function (req, res, next) { ... }
            // }

          },

          // Extra options to pass directly into the Express server
          // when it is instantiated
          //      (or false to disable)
          //
          // This is the options object for the `createServer` method, as discussed here:
          // http://nodejs.org/docs/v0.10.20/api/https.html#https_class_https_server
          serverOptions: undefined,

          // Custom express middleware function to use
          customMiddleware: undefined,

          // Configures the middleware function used for parsing the HTTP request body
          // Defaults to the Formidable-based version built into Express/Connect
          //
          // To enable streaming file uploads (to disk or somewhere else)
          // you'll want to set this option to `false` to disable the body parser.
          //
          // Alternatively, if you're comfortable with the bleeding edge,
          // check out: https://github.com/balderdashy/skipper
          bodyParser: undefined,

          // Cookie parser middleware to use
          //      (or false to disable)
          //
          // Defaults to `express.cookieParser`
          //
          // Example override:
          // cookieParser: (function cookieParser (req, res, next) {})(),
          cookieParser: express.cookieParser,

          // HTTP method override middleware
          //      (or false to disable)
          //
          // This option allows artificial query params to be passed to trick
          // Express into thinking a different HTTP verb was used.
          // Useful when supporting an API for user-agents which don't allow
          // PUT or DELETE requests
          //
          // Defaults to `express.methodOverride`
          //
          // Example override:
          // methodOverride: (function customMethodOverride (req, res, next) {})()
          methodOverride: express.methodOverride

        }

      };
    },

    configure: function() {

      // If one piece of the ssl config is specified, ensure the other required piece is there
      if (sails.config.ssl && (
        sails.config.ssl.cert && !sails.config.ssl.key
      ) || (!sails.config.ssl.cert && sails.config.ssl.key)) {
        throw new Error('Invalid SSL config object!  Must include cert and key!');
      }

      if (sails.config.host) {
        sails.config.explicitHost = sails.config.host;
      }

      if (sails.config.express) {
        sails.log.warn('`sails.config.express` is deprecated; use `sails.config.http` instead.');
      }

      // Path static files will be served from
      //
      // Uses `path.resolve()` to accept either:
      //  • an absolute path
      //  • a relative path from the app root (sails.config.appPath)
      sails.config.paths.public = path.resolve(sails.config.appPath, sails.config.paths.public);

      // Merge in legacy `sails.config.express` object for backwards-compat.
      sails.util.defaultsDeep(sails.config.http, sails.config.express||{});

      // If no custom middleware order is specified, make sure the default one is used.
      // This lets you override default middleware without having to explicitly include the
      // "order" array in your http.js config file.
      sails.config.http.middleware.order = sails.config.http.middleware.order || sails.hooks.http.defaults(sails.config).http.middleware.order;

    },

    /**
     * Initialize is fired first thing when the hook is loaded
     * but after waiting for user config (if applicable)
     *
     * @api public
     */

    initialize: function(cb) {

      // Wait until after session hook has initialized (if applicable)
      // so that the session config is available.
      if ( sails.hooks.session ) {
        sails.after('hook:session:loaded', function () {
          return initialize(cb);
        });
      }

      // If the session hook is not available:
      else {

        // Don't use the cookieParser or session middleware
        _.remove(sails.config.http.middleware.order, function (mwr){
          return mwr === 'session' || mwr === 'cookieParser';
        });

        return initialize(cb);
      }

    }
  };
};
<commit_msg>use www folder in production mode<commit_after>/**
 * Module dependencies.
 */

var path    = require('path');
var _       = require('lodash');
var express = require('express');
var fs      = require ('fs');

module.exports = function(sails) {

  var initialize = require('./initialize')(sails);

  /**
   * Expose `http` hook definition
   */

  return {

    defaults: function(config) {
      return {

        // Self-awareness: the host the server *thinks it is*
        // host: 'localhost',

        // Port to run this app on
        port: 1337,

        // Users' SSL cert settings end up here
        ssl: {},

        // HTTP cache configuration
        cache: {
          maxAge: config.environment === 'development' ? 1 : 31557600000
        },

        // Path static files will be served from
        // Uses `path.resolve()` to accept either:
        //  • an absolute path
        //  • a relative path from the app root (sails.config.appPath)
        paths: {
          public: config.environment === 'production' && fs.existsSync('www') ? 'www' : '.tmp/public'
        },

        // New http-only middleware config
        // (provides default middleware)
        http: {
          middleware: {
            order: [
              'startRequestTimer',
              'cookieParser',
              'session',
              'bodyParser',
              'handleBodyParserError',
              'compress',
              'methodOverride',
              'poweredBy',
              '$custom',
              'router',
              'www',
              'favicon',
              '404',
              '500'
            ],

            // Default middleware definitions are injected
            // after the `app` object is available.
            // (see `loadMiddleware.js` and `middleware.js`)
            // e.g.:
            // session: {
            //   options: {},
            //   fn: function (req, res, next) { ... }
            // }

          },

          // Extra options to pass directly into the Express server
          // when it is instantiated
          //      (or false to disable)
          //
          // This is the options object for the `createServer` method, as discussed here:
          // http://nodejs.org/docs/v0.10.20/api/https.html#https_class_https_server
          serverOptions: undefined,

          // Custom express middleware function to use
          customMiddleware: undefined,

          // Configures the middleware function used for parsing the HTTP request body
          // Defaults to the Formidable-based version built into Express/Connect
          //
          // To enable streaming file uploads (to disk or somewhere else)
          // you'll want to set this option to `false` to disable the body parser.
          //
          // Alternatively, if you're comfortable with the bleeding edge,
          // check out: https://github.com/balderdashy/skipper
          bodyParser: undefined,

          // Cookie parser middleware to use
          //      (or false to disable)
          //
          // Defaults to `express.cookieParser`
          //
          // Example override:
          // cookieParser: (function cookieParser (req, res, next) {})(),
          cookieParser: express.cookieParser,

          // HTTP method override middleware
          //      (or false to disable)
          //
          // This option allows artificial query params to be passed to trick
          // Express into thinking a different HTTP verb was used.
          // Useful when supporting an API for user-agents which don't allow
          // PUT or DELETE requests
          //
          // Defaults to `express.methodOverride`
          //
          // Example override:
          // methodOverride: (function customMethodOverride (req, res, next) {})()
          methodOverride: express.methodOverride

        }

      };
    },

    configure: function() {

      // If one piece of the ssl config is specified, ensure the other required piece is there
      if (sails.config.ssl && (
        sails.config.ssl.cert && !sails.config.ssl.key
      ) || (!sails.config.ssl.cert && sails.config.ssl.key)) {
        throw new Error('Invalid SSL config object!  Must include cert and key!');
      }

      if (sails.config.host) {
        sails.config.explicitHost = sails.config.host;
      }

      if (sails.config.express) {
        sails.log.warn('`sails.config.express` is deprecated; use `sails.config.http` instead.');
      }

      // Path static files will be served from
      //
      // Uses `path.resolve()` to accept either:
      //  • an absolute path
      //  • a relative path from the app root (sails.config.appPath)
      sails.config.paths.public = path.resolve(sails.config.appPath, sails.config.paths.public);

      // Merge in legacy `sails.config.express` object for backwards-compat.
      sails.util.defaultsDeep(sails.config.http, sails.config.express||{});

      // If no custom middleware order is specified, make sure the default one is used.
      // This lets you override default middleware without having to explicitly include the
      // "order" array in your http.js config file.
      sails.config.http.middleware.order = sails.config.http.middleware.order || sails.hooks.http.defaults(sails.config).http.middleware.order;

    },

    /**
     * Initialize is fired first thing when the hook is loaded
     * but after waiting for user config (if applicable)
     *
     * @api public
     */

    initialize: function(cb) {

      // Wait until after session hook has initialized (if applicable)
      // so that the session config is available.
      if ( sails.hooks.session ) {
        sails.after('hook:session:loaded', function () {
          return initialize(cb);
        });
      }

      // If the session hook is not available:
      else {

        // Don't use the cookieParser or session middleware
        _.remove(sails.config.http.middleware.order, function (mwr){
          return mwr === 'session' || mwr === 'cookieParser';
        });

        return initialize(cb);
      }

    }
  };
};
<|endoftext|>


<commit_before>/**
 * Created by King Lee on 2014/9/16.
 */
var handlerMgr = require("./../handlerMgr");
var consts = require("../../../util/consts");
var pomelo = require('pomelo');
var gacha_json = require('../../../../config/gacha.json');
var gacha_replace_json = require('../../../../config/gacha_replace.json');

handlerMgr.handler(consts.TYPE_MSG.TYPE_RANDOM_PRIZE, function(msg, session, next) {
    var channel = msg.channel;
    var version = msg.version;
    var device_guid = msg.player_guid;
    var single_gacha = msg.single_gacha;
    var random_prize_wrapper = pomelo.app.get('random_prize_wrapper');
    var count = 0;
    var gacha_result = [];
    if(single_gacha == "true" ){
        count = 1;
    }
    else{
        count = 12;
    }
    var current_card = 0;
    var last_current_card = 0;
    var reward_car = 0;
    var activity = {};
    var activity_wrapper = pomelo.app.get('activity_wrapper');
    activity_wrapper.get(channel,version,function(activity_json) {
        for (var v in activity_json) {
            if (consts.TYPE_ACTIVITY.TYPE_RANDOM_PRIZE == parseInt(activity_json[v].type)) {
                activity = activity_json[v];
                break;
            }
        }
        //  random prize
        random_prize_wrapper.get(device_guid,function(reply){
            if(null != reply){
                current_card = JSON.parse(reply).current_card;
                last_current_card = current_card;
            }
            for(var i = 0; i < count; ++i){
                var gacha_array = new Array();
                for(var j = 0; j < activity.gacha_random_num; ++j){
                    //  random a card when first
                    if(0 == current_card){
                        current_card += gacha_json[0].number;
                        gacha_array.push(gacha_json[0]);
                        continue;
                    }
                    var prize = random_prize_wrapper.random();
                    if(!prize){
                        break;
                    }
                    if(prize.type == "TICKET"){
                        //  if the current card is more than total_card, give something instead of card
                        if(current_card < activity.total_card){
                            current_card += prize.number;
                            if(current_card > activity.total_card){
                                current_card = activity.total_card;
                            }
                            //  then the current card is equal total_card,give a car as award
                            if(current_card == activity.total_card){
                                reward_car = activity.reward_car;
                            }
                        }else{
                            // give something other(use gacha_replace_json 1,2,3 instead gacha_json 1,2,3)
                            prize = gacha_replace_json[prize.id - 1];
                        }
                    }
                    gacha_array.push(prize);
                }
                for(var j = 0; j < activity.gacha2_random_num; ++j){
                    var prize = random_prize_wrapper.random2();
                    if(prize){
                        gacha_array.push(prize);
                    }
                }
                gacha_result.push(gacha_array);
            }
            if(current_card <= activity.total_card && last_current_card != current_card){
                random_prize_wrapper.set(device_guid,current_card);
            }
            next(null, {
                code: 0,
                msg_id : msg.msg_id,
                flowid : msg.flowid,
                time:Math.floor(Date.now()/1000),
                gacha_result : gacha_result,
                current_card : current_card,
                reward_car : reward_car
            });
        });

    });
});
<commit_msg>random prize use replace item when card is enough,out of range<commit_after>/**
 * Created by King Lee on 2014/9/16.
 */
var handlerMgr = require("./../handlerMgr");
var consts = require("../../../util/consts");
var pomelo = require('pomelo');
var gacha_json = require('../../../../config/gacha.json');
var gacha_replace_json = require('../../../../config/gacha_replace.json');

handlerMgr.handler(consts.TYPE_MSG.TYPE_RANDOM_PRIZE, function(msg, session, next) {
    var channel = msg.channel;
    var version = msg.version;
    var device_guid = msg.player_guid;
    var single_gacha = msg.single_gacha;
    var random_prize_wrapper = pomelo.app.get('random_prize_wrapper');
    var count = 0;
    var gacha_result = [];
    if(single_gacha == "true" ){
        count = 1;
    }
    else{
        count = 12;
    }
    var current_card = 0;
    var last_current_card = 0;
    var reward_car = 0;
    var activity = {};
    var activity_wrapper = pomelo.app.get('activity_wrapper');
    activity_wrapper.get(channel,version,function(activity_json) {
        for (var v in activity_json) {
            if (consts.TYPE_ACTIVITY.TYPE_RANDOM_PRIZE == parseInt(activity_json[v].type)) {
                activity = activity_json[v];
                break;
            }
        }
        //  random prize
        random_prize_wrapper.get(device_guid,function(reply){
            if(null != reply){
                current_card = JSON.parse(reply).current_card;
                last_current_card = current_card;
            }
            for(var i = 0; i < count; ++i){
                var gacha_array = new Array();
                for(var j = 0; j < activity.gacha_random_num; ++j){
                    //  random a card when first
                    if(0 == current_card){
                        current_card += gacha_json[0].number;
                        gacha_array.push(gacha_json[0]);
                        continue;
                    }
                    var prize = random_prize_wrapper.random();
                    if(!prize){
                        continue;
                    }
                    if(prize.type == "TICKET"){
                        //  if the current card is more than total_card, give something instead of card
                        if(current_card < activity.total_card){
                            current_card += prize.number;
                            if(current_card > activity.total_card){
                                current_card = activity.total_card;
                            }
                            //  then the current card is equal total_card,give a car as award
                            if(current_card == activity.total_card){
                                reward_car = activity.reward_car;
                            }
                        }else{
                            // give something other(use gacha_replace_json 1,2,3 instead gacha_json 1,2,3)
                            prize = gacha_replace_json[prize.id - 1];
                        }
                    }
                    gacha_array.push(prize);
                }
                for(var j = 0; j < activity.gacha2_random_num; ++j){
                    var prize = random_prize_wrapper.random2();
                    if(prize){
                        gacha_array.push(prize);
                    }
                }
                gacha_result.push(gacha_array);
            }
            if(current_card <= activity.total_card && last_current_card != current_card){
                random_prize_wrapper.set(device_guid,current_card);
            }
            next(null, {
                code: 0,
                msg_id : msg.msg_id,
                flowid : msg.flowid,
                time:Math.floor(Date.now()/1000),
                gacha_result : gacha_result,
                current_card : current_card,
                reward_car : reward_car
            });
        });

    });
});
<|endoftext|>


<commit_before>import React from 'react'

import Panel from 'components/Panel'
import Button from 'components/Button'

import './sandbox.css'

const Sandbox = ({ children }) => (

{'<Button />'}

      <Panel between="m" inline wrap align="flex-start">
        <Button>
          button
        </Button>
        <Button to="/sandbox">
          internal link
        </Button>
        <Button href="/sandbox">
          external link
        </Button>
        <Button ghost>
          ghost
        </Button>
        <Button small>
          small
        </Button>
        <Button disabled>
          disabled
        </Button>
      </Panel>

{'<Panel column />'}

      <Panel column>
        <Panel className="sandbox__sample-box" inset="xxs">
          <samp>{'<Panel inset="xxs" />'}</samp>
        </Panel>
        <Panel className="sandbox__sample-box" inset="xs">
          <samp>{'<Panel inset="xs" />'}</samp>
        </Panel>
        <Panel className="sandbox__sample-box" inset="s">
          <samp>{'<Panel inset="s" />'}</samp>
        </Panel>
        <Panel className="sandbox__sample-box" inset="m">
          <samp>{'<Panel inset="m" />'}</samp>
        </Panel>
        <Panel className="sandbox__sample-box" inset="l">
          <samp>{'<Panel inset="l" />'}</samp>
        </Panel>
        <Panel className="sandbox__sample-box" x="l">
          <samp>{'<Panel x="l" />'}</samp>
        </Panel>
        <Panel className="sandbox__sample-box" y="l">
          <samp>{'<Panel y="l" />'}</samp>
        </Panel>
        <Panel className="sandbox__sample-box" inset="xl">
          <samp>{'<Panel inset="xl" />'}</samp>
        </Panel>
        <Panel className="sandbox__sample-box" inset="xxl">
          <samp>{'<Panel inset="xxl" />'}</samp>
        </Panel>
      </Panel>

{'<Panel row />'}

      <Panel row>
        <Panel className="sandbox__sample-box" inset="xxs">
          <samp>inset="xxs"</samp>
        </Panel>
        <Panel className="sandbox__sample-box" inset="xs">
          <samp>inset="xs"</samp>
        </Panel>
        <Panel className="sandbox__sample-box" inset="s">
          <samp>inset="s"</samp>
        </Panel>
        <Panel className="sandbox__sample-box" inset="m">
          <samp>inset="m"</samp>
        </Panel>
        <Panel className="sandbox__sample-box" inset="l">
          <samp>inset="l"</samp>
        </Panel>
        <Panel className="sandbox__sample-box" inset="xl">
          <samp>inset="xl"</samp>
        </Panel>
        <Panel className="sandbox__sample-box" inset="xxl">
          <samp>inset="xxl"</samp>
        </Panel>
      </Panel>

{'<Panel row />'}

      <Panel row>
        <Panel className="sandbox__sample-box" flex="2" inset="m">
          <samp>{'<Panel flex="2" inset="s" />'}</samp>
        </Panel>
        <Panel className="sandbox__sample-box" flex="1" inset="m">
          <samp>{'<Panel flex="1" inset="s" />'}</samp>
        </Panel>
      </Panel>

{'<Panel wrap />'}

      <Panel row wrap>
        <Panel className="sandbox__sample-box" inset="xxs">
          <samp>inset="xxs"</samp>
        </Panel>
        <Panel className="sandbox__sample-box" inset="xs">
          <samp>inset="xs"</samp>
        </Panel>
        <Panel className="sandbox__sample-box" inset="s">
          <samp>inset="s"</samp>
        </Panel>
        <Panel className="sandbox__sample-box" inset="m">
          <samp>inset="m"</samp>
        </Panel>
        <Panel className="sandbox__sample-box" inset="l">
          <samp>inset="l"</samp>
        </Panel>
        <Panel className="sandbox__sample-box" inset="xl">
          <samp>inset="xl"</samp>
        </Panel>
        <Panel className="sandbox__sample-box" inset="xl">
          <samp>inset="xl"</samp>
        </Panel>
        <Panel className="sandbox__sample-box" inset="xxl">
          <samp>inset="xxl"</samp>
        </Panel>
        <Panel className="sandbox__sample-box" inset="xl">
          <samp>inset="xxl"</samp>
        </Panel>
        <Panel className="sandbox__sample-box" inset="xs">
          <samp>inset="xs"</samp>
        </Panel>
        <Panel className="sandbox__sample-box" inset="xs">
          <samp>inset="xs"</samp>
        </Panel>
      </Panel>

{'<Panel between="l" row />'}

      <Panel between="l" row>
        <Panel className="sandbox__sample-box" inset="xxs">
          <samp>inset="xxs"</samp>
        </Panel>
        <Panel className="sandbox__sample-box" inset="xs">
          <samp>inset="xs"</samp>
        </Panel>
        <Panel className="sandbox__sample-box" inset="s">
          <samp>inset="s"</samp>
        </Panel>
        <Panel className="sandbox__sample-box" inset="m">
          <samp>inset="m"</samp>
        </Panel>
      </Panel>

{'<Panel between="l" column />'}

    <Panel between="l" column>
      <Panel className="sandbox__sample-box" inset="xxs">
        <samp>inset="xxs"</samp>
      </Panel>
      <Panel className="sandbox__sample-box" inset="xs">
        <samp>inset="xs"</samp>
      </Panel>
      <Panel className="sandbox__sample-box" inset="s">
        <samp>inset="s"</samp>
      </Panel>
      <Panel className="sandbox__sample-box" inset="m">
        <samp>inset="m"</samp>
      </Panel>
    </Panel>

{'<Panel row centered />'}

      <Panel row centered>
        <Panel className="sandbox__sample-box" inset="xxs">
          <samp>inset="xxs"</samp>
        </Panel>
        <Panel className="sandbox__sample-box" inset="xs">
          <samp>inset="xs"</samp>
        </Panel>
        <Panel className="sandbox__sample-box" inset="s">
          <samp>inset="s"</samp>
        </Panel>
        <Panel className="sandbox__sample-box" inset="m">
          <samp>inset="m"</samp>
        </Panel>
      </Panel>

{'<Panel column centered />'}

      <Panel column centered>
        <Panel className="sandbox__sample-box" inset="xxs">
          <samp>inset="xxs"</samp>
        </Panel>
        <Panel className="sandbox__sample-box" inset="xs">
          <samp>inset="xs"</samp>
        </Panel>
        <Panel className="sandbox__sample-box" inset="s">
          <samp>inset="s"</samp>
        </Panel>
        <Panel className="sandbox__sample-box" inset="m">
          <samp>inset="m"</samp>
        </Panel>
      </Panel>

)

export default Sandbox
<commit_msg>add Input samples on Sandbox<commit_after>import React from 'react'

import Panel from 'components/Panel'
import Button from 'components/Button'
import Input from 'components/Input'

import './sandbox.css'

const Sandbox = ({ children }) => (

{'<Button />'}

      <Panel between="m" inline wrap align="flex-start">
        <Button>
          button
        </Button>
        <Button to="/sandbox">
          internal link
        </Button>
        <Button href="/sandbox">
          external link
        </Button>
        <Button ghost>
          ghost
        </Button>
        <Button small>
          small
        </Button>
        <Button disabled>
          disabled
        </Button>
      </Panel>

{'<Panel column />'}

      <Panel column>
        <Panel className="sandbox__sample-box" inset="xxs">
          <samp>{'<Panel inset="xxs" />'}</samp>
        </Panel>
        <Panel className="sandbox__sample-box" inset="xs">
          <samp>{'<Panel inset="xs" />'}</samp>
        </Panel>
        <Panel className="sandbox__sample-box" inset="s">
          <samp>{'<Panel inset="s" />'}</samp>
        </Panel>
        <Panel className="sandbox__sample-box" inset="m">
          <samp>{'<Panel inset="m" />'}</samp>
        </Panel>
        <Panel className="sandbox__sample-box" inset="l">
          <samp>{'<Panel inset="l" />'}</samp>
        </Panel>
        <Panel className="sandbox__sample-box" x="l">
          <samp>{'<Panel x="l" />'}</samp>
        </Panel>
        <Panel className="sandbox__sample-box" y="l">
          <samp>{'<Panel y="l" />'}</samp>
        </Panel>
        <Panel className="sandbox__sample-box" inset="xl">
          <samp>{'<Panel inset="xl" />'}</samp>
        </Panel>
        <Panel className="sandbox__sample-box" inset="xxl">
          <samp>{'<Panel inset="xxl" />'}</samp>
        </Panel>
      </Panel>

{'<Panel row />'}

      <Panel row>
        <Panel className="sandbox__sample-box" inset="xxs">
          <samp>inset="xxs"</samp>
        </Panel>
        <Panel className="sandbox__sample-box" inset="xs">
          <samp>inset="xs"</samp>
        </Panel>
        <Panel className="sandbox__sample-box" inset="s">
          <samp>inset="s"</samp>
        </Panel>
        <Panel className="sandbox__sample-box" inset="m">
          <samp>inset="m"</samp>
        </Panel>
        <Panel className="sandbox__sample-box" inset="l">
          <samp>inset="l"</samp>
        </Panel>
        <Panel className="sandbox__sample-box" inset="xl">
          <samp>inset="xl"</samp>
        </Panel>
        <Panel className="sandbox__sample-box" inset="xxl">
          <samp>inset="xxl"</samp>
        </Panel>
      </Panel>

{'<Panel row />'}

      <Panel row>
        <Panel className="sandbox__sample-box" flex="2" inset="m">
          <samp>{'<Panel flex="2" inset="s" />'}</samp>
        </Panel>
        <Panel className="sandbox__sample-box" flex="1" inset="m">
          <samp>{'<Panel flex="1" inset="s" />'}</samp>
        </Panel>
      </Panel>

{'<Panel wrap />'}

      <Panel row wrap>
        <Panel className="sandbox__sample-box" inset="xxs">
          <samp>inset="xxs"</samp>
        </Panel>
        <Panel className="sandbox__sample-box" inset="xs">
          <samp>inset="xs"</samp>
        </Panel>
        <Panel className="sandbox__sample-box" inset="s">
          <samp>inset="s"</samp>
        </Panel>
        <Panel className="sandbox__sample-box" inset="m">
          <samp>inset="m"</samp>
        </Panel>
        <Panel className="sandbox__sample-box" inset="l">
          <samp>inset="l"</samp>
        </Panel>
        <Panel className="sandbox__sample-box" inset="xl">
          <samp>inset="xl"</samp>
        </Panel>
        <Panel className="sandbox__sample-box" inset="xl">
          <samp>inset="xl"</samp>
        </Panel>
        <Panel className="sandbox__sample-box" inset="xxl">
          <samp>inset="xxl"</samp>
        </Panel>
        <Panel className="sandbox__sample-box" inset="xl">
          <samp>inset="xxl"</samp>
        </Panel>
        <Panel className="sandbox__sample-box" inset="xs">
          <samp>inset="xs"</samp>
        </Panel>
        <Panel className="sandbox__sample-box" inset="xs">
          <samp>inset="xs"</samp>
        </Panel>
      </Panel>

{'<Panel between="l" row />'}

      <Panel between="l" row>
        <Panel className="sandbox__sample-box" inset="xxs">
          <samp>inset="xxs"</samp>
        </Panel>
        <Panel className="sandbox__sample-box" inset="xs">
          <samp>inset="xs"</samp>
        </Panel>
        <Panel className="sandbox__sample-box" inset="s">
          <samp>inset="s"</samp>
        </Panel>
        <Panel className="sandbox__sample-box" inset="m">
          <samp>inset="m"</samp>
        </Panel>
      </Panel>

{'<Panel between="l" column />'}

    <Panel between="l" column>
      <Panel className="sandbox__sample-box" inset="xxs">
        <samp>inset="xxs"</samp>
      </Panel>
      <Panel className="sandbox__sample-box" inset="xs">
        <samp>inset="xs"</samp>
      </Panel>
      <Panel className="sandbox__sample-box" inset="s">
        <samp>inset="s"</samp>
      </Panel>
      <Panel className="sandbox__sample-box" inset="m">
        <samp>inset="m"</samp>
      </Panel>
    </Panel>

{'<Panel row centered />'}

      <Panel row centered>
        <Panel className="sandbox__sample-box" inset="xxs">
          <samp>inset="xxs"</samp>
        </Panel>
        <Panel className="sandbox__sample-box" inset="xs">
          <samp>inset="xs"</samp>
        </Panel>
        <Panel className="sandbox__sample-box" inset="s">
          <samp>inset="s"</samp>
        </Panel>
        <Panel className="sandbox__sample-box" inset="m">
          <samp>inset="m"</samp>
        </Panel>
      </Panel>

{'<Panel column centered />'}

      <Panel column centered>
        <Panel className="sandbox__sample-box" inset="xxs">
          <samp>inset="xxs"</samp>
        </Panel>
        <Panel className="sandbox__sample-box" inset="xs">
          <samp>inset="xs"</samp>
        </Panel>
        <Panel className="sandbox__sample-box" inset="s">
          <samp>inset="s"</samp>
        </Panel>
        <Panel className="sandbox__sample-box" inset="m">
          <samp>inset="m"</samp>
        </Panel>
      </Panel>

{'<Button />'}

      <Panel column centered>
        <form>
          <Input type="text" placeholder="text" />
          <Input type="number" placeholder="number" required />
          <Input type="submit">Submit</Input>
        </form>
      </Panel>

)

export default Sandbox
<|endoftext|>