<commit_before>
import {PostController} from './PostController'
import {PostListController} from './PostListController'
import {TopicListController} from './TopicListController'
import {ChatController} from './ChatController'
import {ChatDetailController} from './ChatDetailController'
import {TabController} from './TabController'
import {AuthController} from './AuthController'
import {NotificationController} from './NotificationController'
import {FindMessageController} from './FindMessageController'

export var tab = {
  action: TabController,
  state:'tab',
  name : "TabCtrl",
  config: {
    url: '/tab',
    abstract: true,
    templateUrl: 'templates/tabs.html',
    controller: 'TabCtrl',
    controllerAs: 'vm'
  }
}

export var topics = {
  action: TopicListController,
  state:'tab.topics',
  name : "TopicCtrl",
  config: {
    url: '/topics',
    views: {
      'tab-topics': {
        templateUrl: 'templates/tab-topics.html',
        controller: "TopicCtrl",
        controllerAs: 'vm'
      }
    }
  }
}

export var posts = {
  action: PostListController,
  state:'tab.topics-posts',
  name:"PostsCtrl",
  config: {
    url: '/topics/:topicId/page/:page',
    views: {
      'tab-topics': {
        templateUrl: 'templates/topic-posts.html',
        controller: 'PostsCtrl',
        controllerAs: 'vm'
      }
    }
  }
}

export var post = {
  action: PostController,
  state: 'tab.topics-posts-detail',
  name: "PostDetailCtrl",
  config:{
    cache: false,
    url: '/topics/:topicId/posts/:postId/page/:page',
    views: {
      'tab-topics': {
        templateUrl: 'templates/post-detail.html',
        controller: 'PostDetailCtrl',
        controllerAs: 'vm'
      }
    }
  }
}

export var chats = {
  action: ChatController,
  state: 'tab.chats',
  name: "ChatCtrl",
  config:{
    cache: true,
    url: '/chats',
    views: {
      'tab-chats': {
        templateUrl: 'templates/tab-chats.html',
        controller: 'ChatCtrl',
        controllerAs: 'vm'
      }
    }
  }
}

export var chat = {
  action: ChatDetailController,
  state: 'tab.chat-detail',
  name: "ChatDetailCtrl",
  config:{
    cache: false,
    url: '/chats/:id',
    views: {
      'tab-chats': {
        templateUrl: 'templates/chat-detail.html',
        controller: 'ChatDetailCtrl',
        controllerAs: 'vm'
      }
    }
  }
}

export var auth = {
  action: AuthController,
  state: 'tab.account',
  name: 'AuthCtrl',
  config: {
    url: '/account',
    views: {
      'tab-account': {
        templateUrl: 'templates/tab-account.html',
        controller: 'AuthCtrl',
        controllerAs: 'vm'
      }
    }
  }
}

export var notification = {
  action: NotificationController,
  state: 'tab.notifications',
  name: 'NotificationCtrl',
  config: {
    url: '/notifications',
    views: {
      'tab-notifications': {
        templateUrl: 'templates/tab-notifications.html',
        controller: 'NotificationCtrl',
        controllerAs: 'vm'
      }
    }
  }
}

export var findMesssage = {
  action: FindMessageController,
  state: 'tab.findMesssage',
  name: 'FindMessageCtrl',
  config: {
    url: '/topics/findMessage/:postId/:messageId',
    views: {
      'tab-topics': {
        templateUrl: 'templates/post-detail.html',
        controller: 'FindMessageCtrl',
        controllerAs: 'vm'
      }
    }
  }
}<commit_msg>upgraded to wkwebview, should use a more cache aggressively<commit_after>
import {PostController} from './PostController'
import {PostListController} from './PostListController'
import {TopicListController} from './TopicListController'
import {ChatController} from './ChatController'
import {ChatDetailController} from './ChatDetailController'
import {TabController} from './TabController'
import {AuthController} from './AuthController'
import {NotificationController} from './NotificationController'
import {FindMessageController} from './FindMessageController'

export var tab = {
  action: TabController,
  state:'tab',
  name : "TabCtrl",
  config: {
    url: '/tab',
    abstract: true,
    templateUrl: 'templates/tabs.html',
    controller: 'TabCtrl',
    controllerAs: 'vm'
  }
}

export var topics = {
  action: TopicListController,
  state:'tab.topics',
  name : "TopicCtrl",
  config: {
    url: '/topics',
    views: {
      'tab-topics': {
        templateUrl: 'templates/tab-topics.html',
        controller: "TopicCtrl",
        controllerAs: 'vm'
      }
    }
  }
}

export var posts = {
  action: PostListController,
  state:'tab.topics-posts',
  name:"PostsCtrl",
  config: {
    url: '/topics/:topicId/page/:page',
    views: {
      'tab-topics': {
        templateUrl: 'templates/topic-posts.html',
        controller: 'PostsCtrl',
        controllerAs: 'vm'
      }
    }
  }
}

export var post = {
  action: PostController,
  state: 'tab.topics-posts-detail',
  name: "PostDetailCtrl",
  config:{
    url: '/topics/:topicId/posts/:postId/page/:page',
    views: {
      'tab-topics': {
        templateUrl: 'templates/post-detail.html',
        controller: 'PostDetailCtrl',
        controllerAs: 'vm'
      }
    }
  }
}

export var chats = {
  action: ChatController,
  state: 'tab.chats',
  name: "ChatCtrl",
  config:{
    url: '/chats',
    views: {
      'tab-chats': {
        templateUrl: 'templates/tab-chats.html',
        controller: 'ChatCtrl',
        controllerAs: 'vm'
      }
    }
  }
}

export var chat = {
  action: ChatDetailController,
  state: 'tab.chat-detail',
  name: "ChatDetailCtrl",
  config:{
    url: '/chats/:id',
    views: {
      'tab-chats': {
        templateUrl: 'templates/chat-detail.html',
        controller: 'ChatDetailCtrl',
        controllerAs: 'vm'
      }
    }
  }
}

export var auth = {
  action: AuthController,
  state: 'tab.account',
  name: 'AuthCtrl',
  config: {
    url: '/account',
    views: {
      'tab-account': {
        templateUrl: 'templates/tab-account.html',
        controller: 'AuthCtrl',
        controllerAs: 'vm'
      }
    }
  }
}

export var notification = {
  action: NotificationController,
  state: 'tab.notifications',
  name: 'NotificationCtrl',
  config: {
    url: '/notifications',
    views: {
      'tab-notifications': {
        templateUrl: 'templates/tab-notifications.html',
        controller: 'NotificationCtrl',
        controllerAs: 'vm'
      }
    }
  }
}

export var findMesssage = {
  action: FindMessageController,
  state: 'tab.findMesssage',
  name: 'FindMessageCtrl',
  config: {
    url: '/topics/findMessage/:postId/:messageId',
    views: {
      'tab-topics': {
        templateUrl: 'templates/post-detail.html',
        controller: 'FindMessageCtrl',
        controllerAs: 'vm'
      }
    }
  }
}<|endoftext|>


<commit_before>var React                                    = require("react")
var cx                                       = require("classnames")

var {errorList, sizeClassNames, formGroupCx} = require("../util.js")

var {div, span, label, input}                = React.DOM

/*
 * Example 1) Using a switch for one input:
 *
 *   data = allIsWell: true
 *
 *   this.frig ref: "ex1", data: data ->
 *     f.input "allIsWell", template: "switch"

 * Example 2) Using switches as the default for all boolean inputs in a form:
 *
 *   data = allIsWell: true
 *
 *   this.frig ref: "ex2", data: data, typeMapping: {boolean: "switch"}, ->
 *     f.input "allisWell"

 * Example 3) Using switches as the default for all boolean inputs in all forms:
 *
 *   Frig.typeMapping.boolean.template = "switch"
 *
 *   data = allIsWell: true
 *
 *   this.frig ref: "ex2", data: data, ->
 *     f.input "allisWell"

 * This optional add-on component depends on BootstrapSwitch and jQuery
*/

export default class extends React.Component {

  static displayName = "Frig.friggingBootstrap.Switch"

  static defaultProps = Object.assign(require("../default_props.js"))

  constructor(props) {
    super(props)

    this.state = {
      errors: undefined,
      checked: true,
    }
  }

  isChecked() {
    return this.state.checked
  }

  _inputHtml() {
    return div({
        className: `bootstrap-switch-container`,
        ref: "switchContainer",
        onClick: this._onClick.bind(this),
      },
      span({className: `bootstrap-switch-handle-on bootstrap-switch-primary`}, "ON"),
      span({className: `bootstrap-switch-label`}, "\u00a0"),
      span({className: `bootstrap-switch-handle-off bootstrap-switch-default`}, "OFF"),
    )
  }

  _onClick() {
    React.findDOMNode(this.refs.switchContainer).style.marginLeft = (this.state.checked === true) ? "-50px" : "0"
    this.setState({ checked: !this.state.checked })
  }

  _labelContainerCx() {
    return cx({
      "pull-left": this.props.layout === "horizontal",
    })
  }

  _inputContainerCx() {
    return cx({
      "pull-right": this.props.layout === "horizontal",
      "controls": this.props.layout === "vertical",
    })
  }

  _label() {
    if (this.props.label === null) return ""
    return label(this.props.labelHtml, this.props.label)
  }

  _errorList() {
    if (this.state.errors === null) return ""
    return errorList(this.state.errors)
  }

  render() {
    return div({className: cx(sizeClassNames(this.props))},
      div({className: this._labelContainerCx()},
        this._label(),
      ),
      div({className: this._inputContainerCx()},
        div({className: `bootstrap-switch bootstrap-switch-wrapper bootstrap-switch-on bootstrap-switch-id-switch-state bootstrap-switch-animate`},
          this._inputHtml(),
          this._errorList(),
        )
      )
    )
  }

}
<commit_msg>Add Change ON & OFF Text On Switch Component<commit_after>var React                                    = require("react")
var cx                                       = require("classnames")

var {errorList, sizeClassNames, formGroupCx} = require("../util.js")

var {div, span, label, input}                = React.DOM

/*
 * Example 1) Using a switch for one input:
 *
 *   data = allIsWell: true
 *
 *   this.frig ref: "ex1", data: data ->
 *     f.input "allIsWell", template: "switch"

 * Example 2) Using switches as the default for all boolean inputs in a form:
 *
 *   data = allIsWell: true
 *
 *   this.frig ref: "ex2", data: data, typeMapping: {boolean: "switch"}, ->
 *     f.input "allisWell"

 * Example 3) Using switches as the default for all boolean inputs in all forms:
 *
 *   Frig.typeMapping.boolean.template = "switch"
 *
 *   data = allIsWell: true
 *
 *   this.frig ref: "ex2", data: data, ->
 *     f.input "allisWell"

 * This optional add-on component depends on BootstrapSwitch and jQuery
*/

export default class extends React.Component {

  static displayName = "Frig.friggingBootstrap.Switch"

  static defaultProps = Object.assign(require("../default_props.js"), {
    onText:   "ON",
    offText:  "OFF",
  })

  constructor(props) {
    super(props)

    this.state = {
      errors: undefined,
      checked: true,
    }
  }

  isChecked() {
    return this.state.checked
  }

  _inputHtml() {
    return div({
        className: `bootstrap-switch-container`,
        ref: "switchContainer",
        onClick: this._onClick.bind(this),
      },
      span({className: `bootstrap-switch-handle-on bootstrap-switch-primary`}, this.props.onText),
      span({className: `bootstrap-switch-label`}, "\u00a0"),
      span({className: `bootstrap-switch-handle-off bootstrap-switch-default`}, this.props.offText),
    )
  }

  _onClick() {
    React.findDOMNode(this.refs.switchContainer).style.marginLeft = (this.state.checked === true) ? "-50px" : "0"
    this.setState({ checked: !this.state.checked })
  }

  _labelContainerCx() {
    return cx({
      "pull-left": this.props.layout === "horizontal",
    })
  }

  _inputContainerCx() {
    return cx({
      "pull-right": this.props.layout === "horizontal",
      "controls": this.props.layout === "vertical",
    })
  }

  _label() {
    if (this.props.label === null) return ""
    return label(this.props.labelHtml, this.props.label)
  }

  _errorList() {
    if (this.state.errors === null) return ""
    return errorList(this.state.errors)
  }

  render() {
    return div({className: cx(sizeClassNames(this.props))},
      div({className: this._labelContainerCx()},
        this._label(),
      ),
      div({className: this._inputContainerCx()},
        div({className: `bootstrap-switch bootstrap-switch-wrapper bootstrap-switch-on bootstrap-switch-id-switch-state bootstrap-switch-animate`},
          this._inputHtml(),
          this._errorList(),
        )
      )
    )
  }

}
<|endoftext|>


<commit_before>/*
 * The contents of this file are subject to the OpenMRS Public 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://license.openmrs.org
 *
 * Software distributed under the License is distributed on an "AS IS"
 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
 * License for the specific language governing rights and limitations
 * under the License.
 *
 * Copyright (C) OpenMRS, LLC.  All Rights Reserved.
 */
define(
	[
			openhmis.url.backboneBase + 'js/model/generic',
			openhmis.url.backboneBase + 'js/lib/i18n',
			openhmis.url.backboneBase + 'js/model/fieldGenHandler'
	],
	function(openhmis, __) {
		openhmis.AttributeTypeBase = openhmis.GenericModel.extend({
			meta: {},
			schema: {},

			initialize: function (attributes, options) {
				openhmis.GenericModel.prototype.initialize.call(this, attributes, options);

				// All instance attribute types are metadata
				this.meta.openmrsType = "metadata";

				// Add default names if not defined
				if (this.meta === undefined || this.meta.name === undefined) {
					this.meta.name = "Attribute Type";
				}
				if (this.meta === undefined || this.meta.namePlural === undefined) {
					this.meta.namePlural = "Attribute Types";
				}

				// Add default schema fields
				this.schema.name = { type: 'Text' };
				this.schema.format = {
					type: 'Select',
					options: new openhmis.FieldFormatCollection()
				};
				this.schema.foreignKey = { type: 'BasicNumber' };
				this.schema.regExp = { type: 'Text' };
				this.schema.required = { type: 'Checkbox' };
                this.schema.attributeOrder = {type: 'Hidden'};
			},

			validate: function (attrs, options) {
				if (!attrs.name) {
					return { name: __("A name is required") }
				}
				return null;
			},

			toString: function () {
				return this.get('name');
			}
		});

        openhmis.AttributeBase = openhmis.GenericModel.extend({
            schema: {},

            attributeTypeClass: null,
            attributeTypeEditor: null,

            initialize: function(attributes, options) {
                openhmis.GenericModel.prototype.initialize.call(this, attributes, options);

                var temp = new this.attributeTypeClass();

                this.schema.attributeType = {
                    type: this.attributeTypeEditor,
                    title: temp.meta.name,
                    options: new openhmis.GenericCollection(null, {
                        model: this.attributeTypeClass,
                        url: temp.meta.restUrl
                    }),
                    objRef: true
                };
                this.schema.value = {
                    type: "Text"
                };
            },

            parse: function(resp) {
                if (resp.attributeType) {
                    resp.attributeType = new this.attributeTypeClass(resp.attributeType, { parse: true });
                }

                return resp;
            }
        });

		openhmis.CustomizableInstanceTypeBase = openhmis.GenericModel.extend({
            meta: {},
            schema: {},

            attributeTypeClass: null,

			initialize: function(attributes, options) {
                openhmis.GenericModel.prototype.initialize.call(this, attributes, options);

				this.schema.attributeTypes = {
					type: 'List',
					itemType: 'NestedModel',
					model: this.attributeTypeClass,
                    subResource: true
				};
			},

			parse: function(resp) {
				if (resp.attributeTypes) {
					var attributeTypes = resp.attributeTypes;
					resp.attributeTypes = [];

					for (var attrType in attributeTypes) {
						var type = new this.attributeTypeClass(attributeTypes[attrType], { parse: true });
						if (attributeTypes[attrType].order !== undefined) {
							resp.attributeTypes[attributeTypes[attrType].order] = type;
						} else {
							resp.attributeTypes.push(type);
						}
					}
				}
				return resp;
			}
		});

        openhmis.CustomizableBase = openhmis.GenericModel.extend({
            meta: {},
            schema: {},

            attributeClass: null,

            initialize: function(attributes, options) {
                openhmis.GenericModel.prototype.initialize.call(this, attributes, options);

                this.schema.attributes = {
                    type: 'List',
                    itemType: 'NestedModel',
                    model: this.attributeClass,
                    subResource: true
                }
            },

            parse: function(resp) {
                if (resp.attributes) {
                    var attributes = resp.attributes;
                    resp.attributes = [];

                    for (var attribute in attributes) {
                        var instance = new this.attributeClass(attributes[attribute], { parse: true });
                        if (attributes[attribute].order !== undefined) {
                            resp.attributes[attributes[attribute].order] = instance;
                        } else {
                            resp.attributes.push(instance);
                        }
                    }
                }

                return resp;
            }
        });
	}
);
<commit_msg>Updated attribute order to be enterable by default.<commit_after>/*
 * The contents of this file are subject to the OpenMRS Public 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://license.openmrs.org
 *
 * Software distributed under the License is distributed on an "AS IS"
 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
 * License for the specific language governing rights and limitations
 * under the License.
 *
 * Copyright (C) OpenMRS, LLC.  All Rights Reserved.
 */
define(
	[
			openhmis.url.backboneBase + 'js/model/generic',
			openhmis.url.backboneBase + 'js/lib/i18n',
			openhmis.url.backboneBase + 'js/model/fieldGenHandler'
	],
	function(openhmis, __) {
		openhmis.AttributeTypeBase = openhmis.GenericModel.extend({
			meta: {},
			schema: {},

			initialize: function(attributes, options) {
				openhmis.GenericModel.prototype.initialize.call(this, attributes, options);

				// All instance attribute types are metadata
				this.meta.openmrsType = "metadata";

				// Add default names if not defined
				if (this.meta === undefined || this.meta.name === undefined) {
					this.meta.name = "Attribute Type";
				}
				if (this.meta === undefined || this.meta.namePlural === undefined) {
					this.meta.namePlural = "Attribute Types";
				}

				// Add default schema fields
				this.schema.name = { type: 'Text' };
				this.schema.format = {
					type: 'Select',
					options: new openhmis.FieldFormatCollection()
				};
				this.schema.foreignKey = { type: 'BasicNumber' };
				this.schema.regExp = { type: 'Text' };
				this.schema.required = { type: 'Checkbox' };
                this.schema.attributeOrder = {type: 'BasicNumber'};
			},

			validate: function(attrs, options) {
				if (!attrs.name) {
					return { name: __("A name is required") }
				}
				return null;
			},

			toString: function() {
				return this.get('name');
			}
		});

        openhmis.InstanceAttributeTypeBase = openhmis.AttributeTypeBase.extend({
            initialize: function (attributes, options) {
                openhmis.AttributeTypeBase.prototype.initialize.call(this, attributes, options);

                this.schema.attributeOrder = {type: 'Hidden'};
            }
        });

        openhmis.AttributeBase = openhmis.GenericModel.extend({
            schema: {},

            attributeTypeClass: null,
            attributeTypeEditor: null,

            initialize: function(attributes, options) {
                openhmis.GenericModel.prototype.initialize.call(this, attributes, options);

                var temp = new this.attributeTypeClass();

                this.schema.attributeType = {
                    type: this.attributeTypeEditor,
                    title: temp.meta.name,
                    options: new openhmis.GenericCollection(null, {
                        model: this.attributeTypeClass,
                        url: temp.meta.restUrl
                    }),
                    objRef: true
                };
                this.schema.value = {
                    type: "Text"
                };
            },

            parse: function(resp) {
                if (resp.attributeType) {
                    resp.attributeType = new this.attributeTypeClass(resp.attributeType, { parse: true });
                }

                return resp;
            },

            toString: function() {
                return this.get('attributeType').name + ': ' + this.get('value');
            }
        });

		openhmis.CustomizableInstanceTypeBase = openhmis.GenericModel.extend({
            meta: {},
            schema: {},

            attributeTypeClass: null,

			initialize: function(attributes, options) {
                openhmis.GenericModel.prototype.initialize.call(this, attributes, options);

				this.schema.attributeTypes = {
					type: 'List',
					itemType: 'NestedModel',
					model: this.attributeTypeClass,
                    subResource: true
				};
			},

			parse: function(resp) {
				if (resp.attributeTypes) {
					var attributeTypes = resp.attributeTypes;
					resp.attributeTypes = [];

					for (var attrType in attributeTypes) {
						var type = new this.attributeTypeClass(attributeTypes[attrType], { parse: true });
						if (attributeTypes[attrType].order !== undefined) {
							resp.attributeTypes[attributeTypes[attrType].order] = type;
						} else {
							resp.attributeTypes.push(type);
						}
					}
				}
				return resp;
			}
		});

        openhmis.CustomizableBase = openhmis.GenericModel.extend({
            meta: {},
            schema: {},

            attributeClass: null,

            initialize: function(attributes, options) {
                openhmis.GenericModel.prototype.initialize.call(this, attributes, options);

                this.schema.attributes = {
                    type: 'List',
                    itemType: 'NestedModel',
                    model: this.attributeClass,
                    subResource: true
                }
            },

            parse: function(resp) {
                if (resp.attributes) {
                    var attributes = resp.attributes;
                    resp.attributes = [];

                    for (var attribute in attributes) {
                        var instance = new this.attributeClass(attributes[attribute], { parse: true });
                        if (attributes[attribute].order !== undefined) {
                            resp.attributes[attributes[attribute].order] = instance;
                        } else {
                            resp.attributes.push(instance);
                        }
                    }
                }

                return resp;
            }
        });
	}
);
<|endoftext|>


<commit_before>const NO_MORE_DOCS = -1;

export class Documents {
  constructor(scorers) {
    this.last_doc = null;
    this.scorers = scorers;
  }

  doSomething() {
    var scorer;
    for (scorer in this.scorers) {
      if (scorer.nextDoc() === NO_MORE_DOCS)
        this.last_doc = NO_MORE_DOCS;
        return;
      }
    }
  }

  toString() {
    return `Last doc: ${this.last_doc}`;
  }
}
<commit_msg>Make it more idiomatic.<commit_after>const NO_MORE_DOCS = -1;

export class Documents {
  constructor(scorers) {
    this.last_doc = null;
    this.scorers = scorers;
  }

  doSomething() {
    for (var scorer in this.scorers) {
      if (scorer.nextDoc() === NO_MORE_DOCS)
        this.last_doc = NO_MORE_DOCS;
        return;
      }
    }
  }

  toString() {
    return `Last doc: ${this.last_doc}`;
  }
}
<|endoftext|>


<commit_before>/*
 * @copyright 2009 - present by OpenGamma Inc
 * @license See distribution for license
 */
(function($, undefined) {
    var table_resizers = [], t;
    $(window).resize(function () {
        if (t) clearTimeout(t);
        t = setTimeout(function () {
            table_resizers.forEach(function (val) {val()});
        }, 300);
    });
    $.fn.awesometable = function(options) {
        if (!this.is('table')) throw new TypeError('$.awesometable: needs to be called on a table element');
        var self = this, cons = arguments.callee, $dup,
            get_scrollbar_width = function () {
            return 100 - $('
')
              .appendTo('body').append('
').find('div').css('height', '200px').width();
        };
        if (!self.parent().parent().hasClass('og-js-table')) { // initialize
            if (self.height() - self.find('thead').height() <= options.height) return;
            self.css('margin-top', '-1px'); // compensate for thead height being 1px
            self.wrap('
').parent()
                .css({height: options.height + 'px', overflow: 'auto'})
                .wrap('

');
            $dup = self.clone(), $dup.find('tbody').remove();
            self.parentsUntil('.js-awesometable').parent().prepend($dup);
            table_resizers.push(function () {cons.call(self, options)});
        }
        // resize the new header to mimic original
        (function () {
            var last, len = self.find('th').length, $dup = $('.js-awesometable > table th'),
                reset_css = {
                    'height': '0', 'line-height': '0', 'padding': '0', 'margin': '0',
                    'overflow': 'hidden', 'visibility': 'hidden'
                };
            self.find('th').each(function (index, elm) {
                index === len - 1 ? last = get_scrollbar_width() : last = 0;
                $($dup[index]).width($(elm).width() + last);
            });
            self.find('thead').css(reset_css).find('*').css(reset_css);
        }());
        // deal with and css before and after content
        (function () {
            if (table_resizers.length > 1) return;
            var $style = $('


<commit_before>/** @global {Jymfony.Component.DependencyInjection.ContainerBuilder} container */

const ChildDefinition = Jymfony.Component.DependencyInjection.ChildDefinition;
const Container = Jymfony.Component.DependencyInjection.Container;
const Reference = Jymfony.Component.DependencyInjection.Reference;

container.register(Jymfony.Component.HttpFoundation.Controller.ControllerResolverInterface, Jymfony.Component.HttpFoundation.Controller.ContainerControllerResolver)
    .addArgument(new Reference('service_container'))
    .addArgument(new Reference('logger', Container.IGNORE_ON_INVALID_REFERENCE))
;

container.register('argument_metadata_factory', Jymfony.Component.HttpServer.Controller.Metadata.ArgumentMetadataFactory);

container.register('argument_resolver', Jymfony.Component.HttpServer.Controller.ArgumentResolver)
    .addArgument(new Reference('argument_metadata_factory'))
    .addArgument([])
;

container.register('argument_resolver.request_attribute', Jymfony.Component.HttpServer.Controller.ArgumentResolvers.RequestAttributeValueResolver)
    .addTag('controller.argument_value_resolver', { priority: 100 })
;
container.register('argument_resolver.request', Jymfony.Component.HttpServer.Controller.ArgumentResolvers.RequestValueResolver)
    .addTag('controller.argument_value_resolver', { priority: 50 })
;
container.register('argument_resolver.session', Jymfony.Component.HttpServer.Controller.ArgumentResolvers.SessionValueResolver)
    .addTag('controller.argument_value_resolver', { priority: 50 })
;
container.register('argument_resolver.service', Jymfony.Component.HttpServer.Controller.ArgumentResolvers.ServiceValueResolver)
    .addArgument()
    .addTag('controller.argument_value_resolver', { priority: -50 })
;
container.register('argument_resolver.default', Jymfony.Component.HttpServer.Controller.ArgumentResolvers.DefaultValueResolver)
    .addTag('controller.argument_value_resolver', { priority: -100 })
;
container.register('argument_resolver.variadic', Jymfony.Component.HttpServer.Controller.ArgumentResolvers.VariadicValueResolver)
    .addTag('controller.argument_value_resolver', { priority: -150 })
;

container.register(Jymfony.Component.HttpServer.RequestHandler)
    .setAbstract(true)
    .addArgument(new Reference('event_dispatcher'))
    .addArgument(new Reference(Jymfony.Component.HttpFoundation.Controller.ControllerResolverInterface))
    .addArgument(new Reference('argument_resolver'))
    .addMethodCall('setLogger', [ new Reference('logger', Container.IGNORE_ON_INVALID_REFERENCE) ])
;

container.setDefinition(Jymfony.Component.HttpServer.HttpServer, new ChildDefinition(Jymfony.Component.HttpServer.RequestHandler))
    .setPublic(true)
;

container.register('kernel.exception_controller', Jymfony.Bundle.FrameworkBundle.Controller.ExceptionController)
    .setPublic(true)
    .addArgument('%kernel.debug%')
;

container.register(Jymfony.Component.HttpServer.EventListener.ExceptionListener)
    .addTag('kernel.event_subscriber')
    .addArgument('kernel.exception_controller:showAction')
    .addArgument(new Reference('logger', Container.IGNORE_ON_INVALID_REFERENCE))
    .addArgument('%kernel.debug%')
;

container.register(Jymfony.Component.HttpServer.EventListener.RouterListener)
    .addTag('kernel.event_subscriber')
    .addTag('jymfony.logger', { channel: 'request' })
    .addArgument(new Reference('router'))
    .addArgument(new Reference('logger', Container.IGNORE_ON_INVALID_REFERENCE))
    .addArgument('%kernel.project_dir%')
    .addArgument('%kernel.debug%')
;

container.register(Jymfony.Component.HttpServer.Command.HttpServerRunCommand)
    .addTag('console.command')
    .addArgument(new Reference(Jymfony.Component.HttpServer.HttpServer))
;

container.register(Jymfony.Component.HttpServer.EventListener.WebsocketListener)
    .addTag('kernel.event_subscriber')
;

container.setDefinition(Jymfony.Component.HttpServer.Serverless.AwsLambdaHandler, new ChildDefinition(Jymfony.Component.HttpServer.RequestHandler))
    .setPublic(true)
;
<commit_msg>[FrameworkBundle] fix request handlers service definitions<commit_after>/** @global {Jymfony.Component.DependencyInjection.ContainerBuilder} container */

const ChildDefinition = Jymfony.Component.DependencyInjection.ChildDefinition;
const Container = Jymfony.Component.DependencyInjection.Container;
const Reference = Jymfony.Component.DependencyInjection.Reference;

container.register(Jymfony.Component.HttpFoundation.Controller.ControllerResolverInterface, Jymfony.Component.HttpFoundation.Controller.ContainerControllerResolver)
    .addArgument(new Reference('service_container'))
    .addArgument(new Reference('logger', Container.IGNORE_ON_INVALID_REFERENCE))
;

container.register('argument_metadata_factory', Jymfony.Component.HttpServer.Controller.Metadata.ArgumentMetadataFactory);

container.register('argument_resolver', Jymfony.Component.HttpServer.Controller.ArgumentResolver)
    .addArgument(new Reference('argument_metadata_factory'))
    .addArgument([])
;

container.register('argument_resolver.request_attribute', Jymfony.Component.HttpServer.Controller.ArgumentResolvers.RequestAttributeValueResolver)
    .addTag('controller.argument_value_resolver', { priority: 100 })
;
container.register('argument_resolver.request', Jymfony.Component.HttpServer.Controller.ArgumentResolvers.RequestValueResolver)
    .addTag('controller.argument_value_resolver', { priority: 50 })
;
container.register('argument_resolver.session', Jymfony.Component.HttpServer.Controller.ArgumentResolvers.SessionValueResolver)
    .addTag('controller.argument_value_resolver', { priority: 50 })
;
container.register('argument_resolver.service', Jymfony.Component.HttpServer.Controller.ArgumentResolvers.ServiceValueResolver)
    .addArgument()
    .addTag('controller.argument_value_resolver', { priority: -50 })
;
container.register('argument_resolver.default', Jymfony.Component.HttpServer.Controller.ArgumentResolvers.DefaultValueResolver)
    .addTag('controller.argument_value_resolver', { priority: -100 })
;
container.register('argument_resolver.variadic', Jymfony.Component.HttpServer.Controller.ArgumentResolvers.VariadicValueResolver)
    .addTag('controller.argument_value_resolver', { priority: -150 })
;

container.register(Jymfony.Component.HttpServer.RequestHandler)
    .setAbstract(true)
    .addArgument(new Reference('event_dispatcher'))
    .addArgument(new Reference(Jymfony.Component.HttpFoundation.Controller.ControllerResolverInterface))
    .addArgument(new Reference('argument_resolver'))
    .addMethodCall('setLogger', [ new Reference('logger', Container.IGNORE_ON_INVALID_REFERENCE) ])
;

container.setDefinition(Jymfony.Component.HttpServer.HttpServer, new ChildDefinition(Jymfony.Component.HttpServer.RequestHandler))
    .setClass(Jymfony.Component.HttpServer.HttpServer)
    .setPublic(true)
;

container.register('kernel.exception_controller', Jymfony.Bundle.FrameworkBundle.Controller.ExceptionController)
    .setPublic(true)
    .addArgument('%kernel.debug%')
;

container.register(Jymfony.Component.HttpServer.EventListener.ExceptionListener)
    .addTag('kernel.event_subscriber')
    .addArgument('kernel.exception_controller:showAction')
    .addArgument(new Reference('logger', Container.IGNORE_ON_INVALID_REFERENCE))
    .addArgument('%kernel.debug%')
;

container.register(Jymfony.Component.HttpServer.EventListener.RouterListener)
    .addTag('kernel.event_subscriber')
    .addTag('jymfony.logger', { channel: 'request' })
    .addArgument(new Reference('router'))
    .addArgument(new Reference('logger', Container.IGNORE_ON_INVALID_REFERENCE))
    .addArgument('%kernel.project_dir%')
    .addArgument('%kernel.debug%')
;

container.register(Jymfony.Component.HttpServer.Command.HttpServerRunCommand)
    .addTag('console.command')
    .addArgument(new Reference(Jymfony.Component.HttpServer.HttpServer))
;

container.register(Jymfony.Component.HttpServer.EventListener.WebsocketListener)
    .addTag('kernel.event_subscriber')
;

container.setDefinition(Jymfony.Component.HttpServer.Serverless.AwsLambdaHandler, new ChildDefinition(Jymfony.Component.HttpServer.RequestHandler))
    .setClass(Jymfony.Component.HttpServer.Serverless.AwsLambdaHandler)
    .setPublic(true)
;
<|endoftext|>


<commit_before>import React, { PureComponent, PropTypes } from 'react';
import { findDOMNode } from 'react-dom';
import TransitionGroup from 'react-addons-transition-group';
import cn from 'classnames';

import isValidClick from '../utils/EventUtils/isValidClick';
import isValidFocusKeypress from '../utils/EventUtils/isValidFocusKeypress';
import calcPageOffset from '../utils/calcPageOffset';
import calculateHypotenuse from '../utils/NumberUtils/calculateHypotenuse';

import Ink from './Ink';

/**
 * The `InkContainer` is usesd for holding the list of inks that get created by touch,
 * click, or keyboard focus.
 *
 * If the container element has the `type="submit"` attribute, the ink will also be
 * triggered when the user presses enter anywhere in the form.
 */
export default class InkContainer extends PureComponent {
  static propTypes = {
    style: PropTypes.object,
    className: PropTypes.string,
    inkStyle: PropTypes.object,
    inkClassName: PropTypes.string,
    additionalTriggerKeys: PropTypes.arrayOf(PropTypes.number),
    waitForInkTransition: PropTypes.bool,
    disabledInteractions: PropTypes.arrayOf(PropTypes.oneOf(['keyboard', 'mouse', 'touch'])),
    transitionOverlap: PropTypes.number.isRequired,
    transitionEnterTimeout: PropTypes.number.isRequired,
    transitionLeaveTimeout: PropTypes.number.isRequired,
  };

  static defaultProps = {
    transitionOverlap: 150,
    transitionEnterTimeout: 450,
    transitionLeaveTimeout: 300,
  };

  constructor(props) {
    super(props);

    this.state = { inks: [] };
    this.createInk = this.createInk.bind(this);
    this._createInk = this._createInk.bind(this);
    this._removeInk = this._removeInk.bind(this);
    this._setContainers = this._setContainers.bind(this);
    this._maybeDelayClick = this._maybeDelayClick.bind(this);
    this._handleBlur = this._handleBlur.bind(this);
    this._handleKeyUp = this._handleKeyUp.bind(this);
    this._handleMouseDown = this._handleMouseDown.bind(this);
    this._handleMouseUp = this._handleMouseUp.bind(this);
    this._handleMouseLeave = this._handleMouseLeave.bind(this);
    this._handleTouchStart = this._handleTouchStart.bind(this);
    this._handleTouchMove = this._handleTouchMove.bind(this);
    this._handleTouchEnd = this._handleTouchEnd.bind(this);
    this._handleRemove = this._handleRemove.bind(this);
    this._handleSubmit = this._handleSubmit.bind(this);
  }

  componentWillReceiveProps(nextProps) {
    const { disabledInteractions: di } = this.props;
    const { disabledInteractions: ndi } = nextProps;
    if (di === ndi || !this._container) {
      return;
    }

    if (this._isListeneredDisabledDiff('keyboard', di, ndi)) {
      const fn = `${this._isListeneredDisabled('keyboard', ndi) ? 'remove' : 'add'}EventListener`;
      this._container[fn]('keyup', this._handleKeyUp);

      if (this._container.getAttribute('type') === 'submit') {
        window[fn]('submit', this._handleSubmit);
      }
    }

    if (this._isListeneredDisabledDiff('mouse', di, ndi)) {
      const fn = `${this._isListeneredDisabled('mouse', ndi) ? 'remove' : 'add'}EventListener`;
      this._container[fn]('mousedown', this._handleMouseDown);
      this._container[fn]('mouseup', this._handleMouseUp);
    }

    if (this._isListeneredDisabledDiff('touch', di, ndi)) {
      const fn = `${this._isListeneredDisabled('touch', ndi) ? 'remove' : 'add'}EventListener`;
      this._container[fn]('touchstart', this._handleTouchStart);
      this._container[fn]('touchend', this._handleTouchEnd);
    }
  }

  componentWillUnmount() {
    if (this._timeout) {
      clearTimeout(this._timeout);
    }

    if (this._container) {
      const { disabledInteractions } = this.props;
      if (!this._isListeneredDisabled('keyboard', disabledInteractions)) {
        this._container.addEventListener('keyup', this._handleKeyUp);

        if (this._container.getAttribute('type') === 'submit') {
          window.addEventListener('submit', this._handleSubmit);
        }
      }

      if (!this._isListeneredDisabled('mouse', disabledInteractions)) {
        this._container.addEventListener('mousedown', this._handleMouseDown);
        this._container.addEventListener('mouseup', this._handleMouseUp);
      }

      if (!this._isListeneredDisabled('touch', disabledInteractions)) {
        this._container.addEventListener('touchstart', this._handleTouchStart);
        this._container.addEventListener('touchend', this._handleTouchEnd);
      }
    }
  }

  /**
   * Creates an ink from pageX and pageY coordinates. These values should either come
   * from the `changedTouches` or just the base event (if clicked). These coordinates
   * are used to position the ink correctly in the container from touch/click point.
   * If either value is undefined, an ink will be created from the center of the
   * container.
   *
   * It will also automatically remove the ink.
   *
   * @param {number} pageX - The page x coordinate of the click or touch event.
   * @param {number} pageY - The page y coordinate of the click or touch event.
   */
  createInk(pageX, pageY) {
    this._createInk(pageX, pageY);
    this._removeTimeout = setTimeout(() => {
      this._removeTimeout = null;
      this._removeInk();
    }, this.props.transitionOverlap);
  }

  /**
   * Creates an ink from pageX and pageY coordinates. These values should either come
   * from the `changedTouches` or just the base event (if clicked). These coordinates
   * are used to position the ink correctly in the container from touch/click point.
   * If either value is undefined, an ink will be created from the center of the
   * container.
   *
   * @param {number} pageX - The page x coordinate of the click or touch event.
   * @param {number} pageY - The page y coordinate of the click or touch event.
   */
  _createInk(pageX, pageY) {
    const { offsetWidth, offsetHeight } = this._inkContainer;

    let x;
    let y;
    if (typeof pageX !== 'undefined' && typeof pageY !== 'undefined') {
      const pageOffset = calcPageOffset(this._inkContainer);

      x = pageX - pageOffset.left;
      y = pageY - pageOffset.top;
    } else {
      x = offsetWidth / 2;
      y = offsetHeight / 2;
    }

    const r = Math.max(
      calculateHypotenuse(x, y),
      calculateHypotenuse(offsetWidth - x, y),
      calculateHypotenuse(offsetWidth - x, offsetHeight - y),
      calculateHypotenuse(x, offsetHeight - y)
    );

    const ink = {
      left: x - r,
      top: y - r,
      size: r * 2,
      key: Date.now(),
    };

    const inks = this.state.inks.slice();
    inks.push(ink);
    this.setState({ inks });
  }

  /**
   * Removes an ink from the container.
   */
  _removeInk() {
    const inks = this.state.inks.slice();
    inks.pop();

    this.setState({ inks });
  }

  _setContainers(inkContainer) {
    if (inkContainer !== null) {
      this._inkContainer = findDOMNode(inkContainer);
      this._container = this._inkContainer.parentNode;

      if (this._container) {
        const { disabledInteractions } = this.props;
        if (!this._isListeneredDisabled('keyboard', disabledInteractions)) {
          this._container.addEventListener('keyup', this._handleKeyUp);

          if (this._container.getAttribute('type') === 'submit') {
            window.addEventListener('submit', this._handleSubmit);
          }
        }

        if (!this._isListeneredDisabled('mouse', disabledInteractions)) {
          this._container.addEventListener('mousedown', this._handleMouseDown);
          this._container.addEventListener('mouseup', this._handleMouseUp);
        }

        if (!this._isListeneredDisabled('touch', disabledInteractions)) {
          this._container.addEventListener('touchstart', this._handleTouchStart);
          this._container.addEventListener('touchend', this._handleTouchEnd);
        }
      }
    }
  }

  _isListeneredDisabledDiff(interaction, disabledInteractions, nextDisabledInteractions) {
    const i = disabledInteractions.indexOf(interaction);
    const ni = nextDisabledInteractions.indexOf(interaction);

    return (i < 0 && ni >= 0) || (i >= 0 && ni < 0);
  }

  _isListeneredDisabled(interaction, disabledInteractions) {
    return disabledInteractions && disabledInteractions.indexOf(interaction) !== -1;
  }

  _maybeDelayClick() {
    if (!this.props.waitForInkTransition) {
      return;
    }

    const captured = e => {
      e.stopPropagation();
      this._container.removeEventListener('click', captured, true);
    };

    // Prevent the next click event on the container only during the bubbling phase
    this._container.addEventListener('click', captured, true);
  }

  _handleRemove() {
    if (this.props.waitForInkTransition) {
      this._container.click();
    }
  }

  _handleBlur() {
    this._container.removeEventListener('blur', this._handleBlur);
    this._removeInk();
  }

  _handleKeyUp(e) {
    if (!isValidFocusKeypress(e, this.props.additionalTriggerKeys)) {
      return;
    }

    this._container.addEventListener('blur', this._handleBlur);
    this._createInk();
  }

  _handleMouseDown(e) {
    if (!isValidClick(e) || this._skipNextMouse) {
      this._skipNextMouse = false;
      return;
    }

    e.stopPropagation();
    this._mouseLeave = false;
    this._container.addEventListener('mouseleave', this._handleMouseLeave);
    this._createInk(e.pageX, e.pageY);
  }

  _handleMouseLeave() {
    this._container.removeEventListener('mouseleave', this._handleMouseLeave);
    this._mouseLeave = true;
    this._removeInk();
  }

  _handleMouseUp() {
    if (this._mouseLeave) {
      return;
    }

    this._maybeDelayClick();
    this._container.removeEventListener('mouseleave', this._handleMouseLeave);
    this._removeInk();
  }

  _handleTouchStart(e) {
    this._aborted = false;
    e.stopPropagation();
    window.addEventListener('touchmove', this._handleTouchMove);

    const { pageX, pageY } = e.changedTouches[0];
    this._createInk(pageX, pageY);
  }

  _handleTouchMove() {
    window.removeEventListener('touchmove', this._handleTouchMove);
    const lastInk = this.state.inks[this.state.inks.length - 1];
    if (!lastInk || Date.now() > (lastInk.key + 200)) {
      this._aborted = false;
      return;
    }

    const inks = this.state.inks.slice();
    const index = inks.length - 1;

    const abortedInk = Object.assign({}, lastInk, { aborted: true });
    inks.splice(index, 1, abortedInk);

    this._aborted = true;
    this.setState({ inks }, this._removeInk);
  }

  _handleTouchEnd() {
    this._skipNextMouse = true;

    if (this._aborted) {
      return;
    } else {
      window.removeEventListener('touchmove', this._handleTouchMove);
    }

    this._removeInk();
  }

  /**
   * If a form was submitted that contains the container of the ink and the current focus element
   * is not the container, trigger an ink effect.
   *
   * The current focus check is added so that two inks are not created.
   */
  _handleSubmit(e) {
    if (document.activeElement === this._container || !e.target.contains(this._container)) {
      return;
    }

    this._maybeDelayClick();
    this.createInk();
  }

  render() {
    const {
      style,
      className,
      inkStyle,
      inkClassName,
      transitionOverlap,
      transitionEnterTimeout,
      transitionLeaveTimeout,
    } = this.props;
    const inks = this.state.inks.map(props => (
      <Ink
        {...props}
        style={inkStyle}
        className={inkClassName}
        onRemove={this._handleRemove}
        transitionOverlap={transitionOverlap}
        transitionEnterTimeout={transitionEnterTimeout}
        transitionLeaveTimeout={transitionLeaveTimeout}
      />
    ));

    return (
      <TransitionGroup
        ref={this._setContainers}
        component="div"
        style={style}
        className={cn('md-ink-container', className)}
      >
        {inks}
      </TransitionGroup>
    );
  }
}
<commit_msg>Fixed bad copy/paste in event listeners for Inks<commit_after>import React, { PureComponent, PropTypes } from 'react';
import { findDOMNode } from 'react-dom';
import TransitionGroup from 'react-addons-transition-group';
import cn from 'classnames';

import isValidClick from '../utils/EventUtils/isValidClick';
import isValidFocusKeypress from '../utils/EventUtils/isValidFocusKeypress';
import calcPageOffset from '../utils/calcPageOffset';
import calculateHypotenuse from '../utils/NumberUtils/calculateHypotenuse';

import Ink from './Ink';

/**
 * The `InkContainer` is usesd for holding the list of inks that get created by touch,
 * click, or keyboard focus.
 *
 * If the container element has the `type="submit"` attribute, the ink will also be
 * triggered when the user presses enter anywhere in the form.
 */
export default class InkContainer extends PureComponent {
  static propTypes = {
    style: PropTypes.object,
    className: PropTypes.string,
    inkStyle: PropTypes.object,
    inkClassName: PropTypes.string,
    additionalTriggerKeys: PropTypes.arrayOf(PropTypes.number),
    waitForInkTransition: PropTypes.bool,
    disabledInteractions: PropTypes.arrayOf(PropTypes.oneOf(['keyboard', 'mouse', 'touch'])),
    transitionOverlap: PropTypes.number.isRequired,
    transitionEnterTimeout: PropTypes.number.isRequired,
    transitionLeaveTimeout: PropTypes.number.isRequired,
  };

  static defaultProps = {
    transitionOverlap: 150,
    transitionEnterTimeout: 450,
    transitionLeaveTimeout: 300,
  };

  constructor(props) {
    super(props);

    this.state = { inks: [] };
    this.createInk = this.createInk.bind(this);
    this._createInk = this._createInk.bind(this);
    this._removeInk = this._removeInk.bind(this);
    this._setContainers = this._setContainers.bind(this);
    this._maybeDelayClick = this._maybeDelayClick.bind(this);
    this._handleBlur = this._handleBlur.bind(this);
    this._handleKeyUp = this._handleKeyUp.bind(this);
    this._handleMouseDown = this._handleMouseDown.bind(this);
    this._handleMouseUp = this._handleMouseUp.bind(this);
    this._handleMouseLeave = this._handleMouseLeave.bind(this);
    this._handleTouchStart = this._handleTouchStart.bind(this);
    this._handleTouchMove = this._handleTouchMove.bind(this);
    this._handleTouchEnd = this._handleTouchEnd.bind(this);
    this._handleRemove = this._handleRemove.bind(this);
    this._handleSubmit = this._handleSubmit.bind(this);
  }

  componentWillReceiveProps(nextProps) {
    const { disabledInteractions: di } = this.props;
    const { disabledInteractions: ndi } = nextProps;
    if (di === ndi || !this._container) {
      return;
    }

    if (this._isListeneredDisabledDiff('keyboard', di, ndi)) {
      const fn = `${this._isListeneredDisabled('keyboard', ndi) ? 'remove' : 'add'}EventListener`;
      this._container[fn]('keyup', this._handleKeyUp);

      if (this._container.getAttribute('type') === 'submit') {
        window[fn]('submit', this._handleSubmit);
      }
    }

    if (this._isListeneredDisabledDiff('mouse', di, ndi)) {
      const fn = `${this._isListeneredDisabled('mouse', ndi) ? 'remove' : 'add'}EventListener`;
      this._container[fn]('mousedown', this._handleMouseDown);
      this._container[fn]('mouseup', this._handleMouseUp);
    }

    if (this._isListeneredDisabledDiff('touch', di, ndi)) {
      const fn = `${this._isListeneredDisabled('touch', ndi) ? 'remove' : 'add'}EventListener`;
      this._container[fn]('touchstart', this._handleTouchStart);
      this._container[fn]('touchend', this._handleTouchEnd);
    }
  }

  componentWillUnmount() {
    if (this._removeTimeout) {
      clearTimeout(this._removeTimeout);
    }

    if (this._container) {
      const { disabledInteractions } = this.props;
      if (!this._isListeneredDisabled('keyboard', disabledInteractions)) {
        this._container.removeEventListener('keyup', this._handleKeyUp);
        this._container.removeEventListener('blur', this._handleBlur);

        if (this._container.getAttribute('type') === 'submit') {
          window.removeEventListener('submit', this._handleSubmit);
        }
      }

      if (!this._isListeneredDisabled('mouse', disabledInteractions)) {
        this._container.removeEventListener('mousedown', this._handleMouseDown);
        this._container.removeEventListener('mouseup', this._handleMouseUp);
      }

      if (!this._isListeneredDisabled('touch', disabledInteractions)) {
        this._container.removeEventListener('touchstart', this._handleTouchStart);
        this._container.removeEventListener('touchend', this._handleTouchEnd);
      }
    }
  }

  /**
   * Creates an ink from pageX and pageY coordinates. These values should either come
   * from the `changedTouches` or just the base event (if clicked). These coordinates
   * are used to position the ink correctly in the container from touch/click point.
   * If either value is undefined, an ink will be created from the center of the
   * container.
   *
   * It will also automatically remove the ink.
   *
   * @param {number} pageX - The page x coordinate of the click or touch event.
   * @param {number} pageY - The page y coordinate of the click or touch event.
   */
  createInk(pageX, pageY) {
    this._createInk(pageX, pageY);
    this._removeTimeout = setTimeout(() => {
      this._removeTimeout = null;
      this._removeInk();
    }, this.props.transitionOverlap);
  }

  /**
   * Creates an ink from pageX and pageY coordinates. These values should either come
   * from the `changedTouches` or just the base event (if clicked). These coordinates
   * are used to position the ink correctly in the container from touch/click point.
   * If either value is undefined, an ink will be created from the center of the
   * container.
   *
   * @param {number} pageX - The page x coordinate of the click or touch event.
   * @param {number} pageY - The page y coordinate of the click or touch event.
   */
  _createInk(pageX, pageY) {
    const { offsetWidth, offsetHeight } = this._inkContainer;

    let x;
    let y;
    if (typeof pageX !== 'undefined' && typeof pageY !== 'undefined') {
      const pageOffset = calcPageOffset(this._inkContainer);

      x = pageX - pageOffset.left;
      y = pageY - pageOffset.top;
    } else {
      x = offsetWidth / 2;
      y = offsetHeight / 2;
    }

    const r = Math.max(
      calculateHypotenuse(x, y),
      calculateHypotenuse(offsetWidth - x, y),
      calculateHypotenuse(offsetWidth - x, offsetHeight - y),
      calculateHypotenuse(x, offsetHeight - y)
    );

    const ink = {
      left: x - r,
      top: y - r,
      size: r * 2,
      key: Date.now(),
    };

    const inks = this.state.inks.slice();
    inks.push(ink);
    this.setState({ inks });
  }

  /**
   * Removes an ink from the container.
   */
  _removeInk() {
    const inks = this.state.inks.slice();
    inks.pop();

    this.setState({ inks });
  }

  _setContainers(inkContainer) {
    if (inkContainer !== null) {
      this._inkContainer = findDOMNode(inkContainer);
      this._container = this._inkContainer.parentNode;

      if (this._container) {
        const { disabledInteractions } = this.props;
        if (!this._isListeneredDisabled('keyboard', disabledInteractions)) {
          this._container.addEventListener('keyup', this._handleKeyUp);

          if (this._container.getAttribute('type') === 'submit') {
            window.addEventListener('submit', this._handleSubmit);
          }
        }

        if (!this._isListeneredDisabled('mouse', disabledInteractions)) {
          this._container.addEventListener('mousedown', this._handleMouseDown);
          this._container.addEventListener('mouseup', this._handleMouseUp);
        }

        if (!this._isListeneredDisabled('touch', disabledInteractions)) {
          this._container.addEventListener('touchstart', this._handleTouchStart);
          this._container.addEventListener('touchend', this._handleTouchEnd);
        }
      }
    }
  }

  _isListeneredDisabledDiff(interaction, disabledInteractions, nextDisabledInteractions) {
    const i = disabledInteractions.indexOf(interaction);
    const ni = nextDisabledInteractions.indexOf(interaction);

    return (i < 0 && ni >= 0) || (i >= 0 && ni < 0);
  }

  _isListeneredDisabled(interaction, disabledInteractions) {
    return disabledInteractions && disabledInteractions.indexOf(interaction) !== -1;
  }

  _maybeDelayClick() {
    if (!this.props.waitForInkTransition) {
      return;
    }

    const captured = e => {
      e.stopPropagation();
      this._container.removeEventListener('click', captured, true);
    };

    // Prevent the next click event on the container only during the bubbling phase
    this._container.addEventListener('click', captured, true);
  }

  _handleRemove() {
    if (this.props.waitForInkTransition) {
      this._container.click();
    }
  }

  _handleBlur() {
    this._container.removeEventListener('blur', this._handleBlur);
    this._removeInk();
  }

  _handleKeyUp(e) {
    if (!isValidFocusKeypress(e, this.props.additionalTriggerKeys)) {
      return;
    }

    this._container.addEventListener('blur', this._handleBlur);
    this._createInk();
  }

  _handleMouseDown(e) {
    if (!isValidClick(e) || this._skipNextMouse) {
      this._skipNextMouse = false;
      return;
    }

    e.stopPropagation();
    this._mouseLeave = false;
    this._container.addEventListener('mouseleave', this._handleMouseLeave);
    this._createInk(e.pageX, e.pageY);
  }

  _handleMouseLeave() {
    this._container.removeEventListener('mouseleave', this._handleMouseLeave);
    this._mouseLeave = true;
    this._removeInk();
  }

  _handleMouseUp() {
    if (this._mouseLeave) {
      return;
    }

    this._maybeDelayClick();
    this._container.removeEventListener('mouseleave', this._handleMouseLeave);
    this._removeInk();
  }

  _handleTouchStart(e) {
    this._aborted = false;
    e.stopPropagation();
    window.addEventListener('touchmove', this._handleTouchMove);

    const { pageX, pageY } = e.changedTouches[0];
    this._createInk(pageX, pageY);
  }

  _handleTouchMove() {
    window.removeEventListener('touchmove', this._handleTouchMove);
    const lastInk = this.state.inks[this.state.inks.length - 1];
    if (!lastInk || Date.now() > (lastInk.key + 200)) {
      this._aborted = false;
      return;
    }

    const inks = this.state.inks.slice();
    const index = inks.length - 1;

    const abortedInk = Object.assign({}, lastInk, { aborted: true });
    inks.splice(index, 1, abortedInk);

    this._aborted = true;
    this.setState({ inks }, this._removeInk);
  }

  _handleTouchEnd() {
    this._skipNextMouse = true;

    if (this._aborted) {
      return;
    } else {
      window.removeEventListener('touchmove', this._handleTouchMove);
    }

    this._removeInk();
  }

  /**
   * If a form was submitted that contains the container of the ink and the current focus element
   * is not the container, trigger an ink effect.
   *
   * The current focus check is added so that two inks are not created.
   */
  _handleSubmit(e) {
    if (document.activeElement === this._container || !e.target.contains(this._container)) {
      return;
    }

    this._maybeDelayClick();
    this.createInk();
  }

  render() {
    const {
      style,
      className,
      inkStyle,
      inkClassName,
      transitionOverlap,
      transitionEnterTimeout,
      transitionLeaveTimeout,
    } = this.props;
    const inks = this.state.inks.map(props => (
      <Ink
        {...props}
        style={inkStyle}
        className={inkClassName}
        onRemove={this._handleRemove}
        transitionOverlap={transitionOverlap}
        transitionEnterTimeout={transitionEnterTimeout}
        transitionLeaveTimeout={transitionLeaveTimeout}
      />
    ));

    return (
      <TransitionGroup
        ref={this._setContainers}
        component="div"
        style={style}
        className={cn('md-ink-container', className)}
      >
        {inks}
      </TransitionGroup>
    );
  }
}
<|endoftext|>


<commit_before>export { ParamDescConfig, Base };

/**
 * Describe which parameter and how many combination for the parameter.
 *
 *
 * @member {ParamDesc.Base} paramDesc
 *   Which parameter to be used in the permutation.
 *
 * @member {number[]} valueOutMinMax
 *   An integer array restricts the generator range to [ valueOutMin, valueOutMax ]. Itself will be restricted to
 * [ paramDesc.valueDesc.range.min, paramDesc.valueDesc.range.max ] at most. When this.kinds is large, this parameter
 * could lower the kinds to reduce test cases quantity. If null or undefined, only one value (between
 * [ paramDesc.valueDesc.range.min, paramDesc.valueDesc.range.max ] randomly) will be generated. In fact, this is the
 * valueOutMinMax parameter of ValueRange.XXX.valueInputOutputGenerator().
 *
 */
class ParamDescConfig {
  constructor( paramDesc, valueOutMinMax ) {
    this.paramDesc = paramDesc;
    this.valueOutMinMax = valueOutMinMax;
  }
}

/**
 * @member {ParamDesc.Xxx} paramDesc    Which parameter is changed.
 * @member {number}  inValue_original    The parameter's original input value.
 * @member {integer} outValue_original  The parameter's original output value.
 * @member {number}  inValue_new         The parameter's new input value.
 * @member {integer} outValue_new       The parameter's new output value. This is adjusted value of outValue_specified.
 * @member {integer} outValue_specified The parameter's output value which is wanted.
 */
class ParamValueChangeRecord {
  constructor( paramDesc, inValue_original, outValue_original, inValue_new, outValue_new, outValue_specified ) {
    this.paramDesc = paramDesc;
    this.inValue_original = inValue_original;
    this.outValue_original = outValue_original;
    this.inValue_new = inValue_new;
    this.outValue_new = outValue_new;
    this.outValue_specified = outValue_specified;
  }
}

/**
 * This is an object { config, id, in, out } which has one number and two sub-objects.
 *
 * @member {object} config
 *   The configuration for generating parameters combination.
 *
 * @param {ParamDescConfig[]} config.paramDescConfigArray
 *   List all the parameters to be used in permutation combination.
 *
 * @member {number} id
 *   The numeric identifier of this testing parameter combination. No matter onYield_isLegal() is true or false, every combination
 * has its own id. The first id is 0 (not 1).
 *
 * @member {number} yieldCount
 *   How many legal (i.e. ( onYield_isLegal() == true ) ) TestParams are yielded.
 *
 * @member {object} in
 *   The "in" sub-object's data members represent every parameters of some (e.g. PointDepthPoint) Params's constructor. Besides,
 * it also has the following properties:
 *   - paramsNumberArrayObject: All (non-concatenated) parameters (include filters and biases) which will be packed into inputFloat32Array.
 *   - inputFloat32Array: A packed Float32Array from paramsNumberArrayObject with byteOffsetBegin.
 *   - byteOffsetBegin: The offset in inputFloat32Array to the first parameter.
 *
 * @member {object} out
 *   The "out" sub-object's data members represent the "should-be" result of some (e.g. PointDepthPoint) Params.extract().
 * That is, it has the data members of this.in except inputFloat32Array, byteOffsetBegin, weights.
 *
 * @member {ParamValueChangeRecord[]} modifyParamValueHistory
 *   A record will be pushed into this list when calling this.modifyParamValue(). When call this.restoreParamValues(),
 * these value will be restored and this list will be cleared to empty.
 *
 */
class Base {

  /**
   *
   */
  constructor( id = -1 ) {
    this.id = id;
    this.yieldCount = 0;
    this.in = { paramsNumberArrayObject: {} };
    this.out = {};
    this.modifyParamValueHistory = [];
  }

  /**
   * Called by permuteParamRecursively() before onYield_before() is called.
   *
   * The the following data should already be ready:
   *   - this.id
   *   - this.in.paramsNumberArrayObject: Every should-be-packed parameter.
   *   - this.in.Xxx: every non-packed parameter.
   *   - this.out.Xxx: every parameter.
   *
   * Sub-class should override this method.
   *
   * @return {boolean}
   *   If return true, the onYield_before() will be called. If return false, it mean this configuration is illegal so that there
   * is no yield will be done (i.e. onYield_before() and onYield_after() will not be called).
   */
  onYield_isLegal() {
    return true;
  }

  /**
   * Called by permuteParamRecursively() when a combination of parameters is complete and before this object to be yielded.
   *
   * The the following data should already be ready:
   *   - this.id
   *   - this.in.paramsNumberArrayObject: Every should-be-packed parameter.
   *   - this.in.Xxx: every non-packed parameter.
   *   - this.out.Xxx: every parameter.
   *
   * This method should fill the following data:
   *   - this.in.inputFloat32Array
   *   - this.in.byteOffsetBegin
   *
   * Sub-class should override this method.
   */
  onYield_before() {
  }

  /**
   * Called by permuteParamRecursively() when a combination of parameters is complete and after this object has been yielded.
   *
   * Usually, this method should clear some temperary data members.
   *
   * Sub-class should override this method.
   */
  onYield_after() {
  }

  /**
   * Modify specified parameter's value and record in this.modifyParamValueHistory so that they could be restore by restoreParamValues().
   *
   * @param {ParamDesc.Xxx} paramDesc
   *   The parameter to be doubled.
   *
   * @param {integer} outValue_specified
   *   The new value to be placed at the this.out[ paramDesc.paramName ].
   */
  modifyParamValue( paramDesc, outValue_specified ) {
    let paramName = paramDesc.paramName;

    let outValue_original = this.out[ paramName ];
    if ( outValue_original == undefined )
      return; // The parameter does not exist. No need to modify it.

    let valueDesc = paramDesc.valueDesc;
    let valueRange = valueDesc.range;

    let outValue_new = valueRange.adjust( outValue_specified ); // Confirm the new value is legal.

    this.out[ paramName ] = outValue_new;

    let inValue_original, inValue_new;

    let singleMinMax = [ outValue_new, outValue_new ]; // Only generate one new value.
    for ( let pair of valueRange.valueInputOutputGenerator( undefined, singleMinMax ) ) {

      inValue_new = pair.valueInput;

      if ( this.in[ paramName ] != undefined ) {
        inValue_original = this.in[ paramName ];
        this.in[ paramName ] = inValue_new;
      }

      if ( this.in.paramsNumberArrayObject[ paramName ] != undefined ) { // Note: If the element exists, it must be an array.
        inValue_original = this.in.paramsNumberArrayObject[ paramName ][ 0 ];
        this.in.paramsNumberArrayObject[ paramName ][ 0 ] = inValue_new; // The value is always at the element 0.
      }
    }

    let changeRecord = new ParamValueChangeRecord( paramDesc, inValue_original, outValue_original, inValue_new, outValue_new, outValue_specified );
    this.modifyParamValueHistory.push( changeRecord );
  }

  /**
   * Restore parameters' values according to this.modifyParamValueHistory. And empty this.modifyParamValueHistory.
   */
  restoreParamValues() {
    for ( let i = this.modifyParamValueHistory.length - 1; i >= 0; --i ) { // From the last to first.
      let changeRecord = this.modifyParamValueHistory[ i ];
      let paramName = changeRecord.paramDesc.paramName;

      if ( this.out[ paramName ] != undefined )
        this.out[ paramName ] = changeRecord.outValue_original;

      if ( this.in[ paramName ] != undefined ) {
        this.in[ paramName ] = changeRecord.inValue_original;
      }

      if ( this.in.paramsNumberArrayObject[ paramName ] != undefined ) { // Note: If the element exists, it must be an array.
        this.in.paramsNumberArrayObject[ paramName ][ 0 ] = changeRecord.inValue_original; // The value is always at the element 0.
      }
    }

    this.modifyParamValueHistory.length = 0; // Clear history.
  }

  /**
   * @param {object} io_object        The object to be checked and modified.
   * @param {string} propertyName     The property io_object[ propertyName ] will be ensured as a number array.
   * @param {number} elementCount     The property io_object[ propertyName ].length will be ensured as elementCount.
   * @param {number} randomOffsetMin  The random number offet lower bound.
   * @param {number} randomOffsetMax  The random number offet upperer bound.
   */
  static ensure_object_property_numberArray_length_filled(
    io_object, propertyName, length, randomOffsetMin, randomOffsetMax ) {

//!!! ...unfinished... (2022/05/21) RandTools.fill_numberArray()
// Perhaps, pool these numberArray. Re-use them if same ( elementCount, randomOffsetMin, randomOffsetMax ).

//!!! (2021/07/20 Temp Remarked) Fixed to non-random to simplify debug.
    return RandTools.generate_numberArray( elementCount, randomOffsetMin, randomOffsetMax );
//    return RandTools.generate_numberArray( elementCount, 0, 0 );
  }

  /**
   * Responsible for generating testing paramters combinations.
   *
   * @param {ParamDescConfig[]} paramDescConfigArray
   *   List all the parameters to be used in permutation combination.
   *
   * @yield {Base}
   *   Yield this object itself. The returned object (it is this object itself) should not be modified because it will be re-used.
   */
  static * ParamsGenerator( paramDescConfigArray ) {
    this.config = { paramDescConfigArray: paramDescConfigArray };

    this.in.paramsNumberArrayObject = {}; // All parameters which will be packed into weights array.
    yield *Base.permuteParamRecursively.call( this, 0 );
  }

  /**
   * This method will modify this.id and this.in.paramsNumberArrayObject. It also calls itself recursively to permute all parameters.
   *
   * @param {number} currentParamDescIndex
   *   The index into the this.paramDescArray[]. It represents the current parameter to be tried.
   *
   * @yield {Base}
   *   Every time one kind of parameters' combination is generated, the this.result will be yielded.
   */
  static * permuteParamRecursively( currentParamDescConfigIndex ) {

    if ( currentParamDescConfigIndex >= this.config.paramDescConfigArray.length ) {
      // All parameters are used to be composed as one kind of combination.

      ++this.id; // Every combination has unique id no matter whether is legal to be yielded.

      let bLegalToYield = this.onYield_isLegal();
      if ( bLegalToYield ) {

        ++this.yieldCount;  // Complete one kind of combination.

        this.onYield_before();
        yield this;
        this.onYield_after();
        this.restoreParamValues(); // Restore this object because onYield_before() may modify it.
      }

      return; // Stop this recusive. Back-track to another parameters combination.
    }

    let nextParamDescConfigIndex = currentParamDescConfigIndex + 1;

    let paramDescConfig = this.config.paramDescConfigArray[ currentParamDescConfigIndex ];
    let paramDesc = paramDescConfig.paramDesc;
    for ( let pair of paramDesc.valueDesc.range.valueInputOutputGenerator( undefined, paramDescConfig.valueOutMinMax ) ) {

      //!!! (2021/07/06 Temp Debug) Check the algorithm might be wrong.
      //if ( paramDesc.valueDesc.range.adjust( pair.valueInput ) != pair.valueOutput )
      //  debugger;

      this.out[ paramDesc.paramName ] = pair.valueOutput;

      // Randomly place the parameter directly or in weights array.

      //!!! (2021/07/19 Temp Used) For testing without randomly.
      //let dice = 0;
      let dice = Math.random();
      if ( dice < 0.5 ) {
        // Try parameter value assigned directly (i.e. by specifying).
        this.in[ paramDesc.paramName ] = pair.valueInput;
        yield *Base.permuteParamRecursively.call( this, nextParamDescConfigIndex );

      } else {
        // Try parameter value assigned from inputFloat32Array (i.e. by evolution).
        this.in[ paramDesc.paramName ] = null;
        this.in.paramsNumberArrayObject[ paramDesc.paramName ] = pair.valueInput; // (number or number array)
        yield *Base.permuteParamRecursively.call( this, nextParamDescConfigIndex );

        this.in.paramsNumberArrayObject[ paramDesc.paramName ] = undefined; // So that it could be re-tried as by-specifying when backtracking.
      }
    }
  }

}
<commit_msg>Update TestParams.js<commit_after>export { ParamDescConfig, Base };

/**
 * Describe which parameter and how many combination for the parameter.
 *
 *
 * @member {ParamDesc.Base} paramDesc
 *   Which parameter to be used in the permutation.
 *
 * @member {number[]} valueOutMinMax
 *   An integer array restricts the generator range to [ valueOutMin, valueOutMax ]. Itself will be restricted to
 * [ paramDesc.valueDesc.range.min, paramDesc.valueDesc.range.max ] at most. When this.kinds is large, this parameter
 * could lower the kinds to reduce test cases quantity. If null or undefined, only one value (between
 * [ paramDesc.valueDesc.range.min, paramDesc.valueDesc.range.max ] randomly) will be generated. In fact, this is the
 * valueOutMinMax parameter of ValueRange.XXX.valueInputOutputGenerator().
 *
 */
class ParamDescConfig {
  constructor( paramDesc, valueOutMinMax ) {
    this.paramDesc = paramDesc;
    this.valueOutMinMax = valueOutMinMax;
  }
}

/**
 * @member {ParamDesc.Xxx} paramDesc    Which parameter is changed.
 * @member {number}  inValue_original    The parameter's original input value.
 * @member {integer} outValue_original  The parameter's original output value.
 * @member {number}  inValue_new         The parameter's new input value.
 * @member {integer} outValue_new       The parameter's new output value. This is adjusted value of outValue_specified.
 * @member {integer} outValue_specified The parameter's output value which is wanted.
 */
class ParamValueChangeRecord {
  constructor( paramDesc, inValue_original, outValue_original, inValue_new, outValue_new, outValue_specified ) {
    this.paramDesc = paramDesc;
    this.inValue_original = inValue_original;
    this.outValue_original = outValue_original;
    this.inValue_new = inValue_new;
    this.outValue_new = outValue_new;
    this.outValue_specified = outValue_specified;
  }
}

/**
 * This is an object { config, id, in, out } which has one number and two sub-objects.
 *
 * @member {object} config
 *   The configuration for generating parameters combination.
 *
 * @param {ParamDescConfig[]} config.paramDescConfigArray
 *   List all the parameters to be used in permutation combination.
 *
 * @member {number} id
 *   The numeric identifier of this testing parameter combination. No matter onYield_isLegal() is true or false, every combination
 * has its own id. The first id is 0 (not 1).
 *
 * @member {number} yieldCount
 *   How many legal (i.e. ( onYield_isLegal() == true ) ) TestParams are yielded.
 *
 * @member {object} in
 *   The "in" sub-object's data members represent every parameters of some (e.g. PointDepthPoint) Params's constructor. Besides,
 * it also has the following properties:
 *   - paramsNumberArrayObject: All (non-concatenated) parameters (include filters and biases) which will be packed into inputFloat32Array.
 *   - inputFloat32Array: A packed Float32Array from paramsNumberArrayObject with byteOffsetBegin.
 *   - byteOffsetBegin: The offset in inputFloat32Array to the first parameter.
 *
 * @member {object} out
 *   The "out" sub-object's data members represent the "should-be" result of some (e.g. PointDepthPoint) Params.extract().
 * That is, it has the data members of this.in except inputFloat32Array, byteOffsetBegin, weights.
 *
 * @member {ParamValueChangeRecord[]} modifyParamValueHistory
 *   A record will be pushed into this list when calling this.modifyParamValue(). When call this.restoreParamValues(),
 * these value will be restored and this list will be cleared to empty.
 *
 */
class Base {

  /**
   *
   */
  constructor( id = -1 ) {
    this.id = id;
    this.yieldCount = 0;
    this.in = { paramsNumberArrayObject: {} };
    this.out = {};
    this.modifyParamValueHistory = [];
  }

  /**
   * Called by permuteParamRecursively() before onYield_before() is called.
   *
   * The the following data should already be ready:
   *   - this.id
   *   - this.in.paramsNumberArrayObject: Every should-be-packed parameter.
   *   - this.in.Xxx: every non-packed parameter.
   *   - this.out.Xxx: every parameter.
   *
   * Sub-class should override this method.
   *
   * @return {boolean}
   *   If return true, the onYield_before() will be called. If return false, it mean this configuration is illegal so that there
   * is no yield will be done (i.e. onYield_before() and onYield_after() will not be called).
   */
  onYield_isLegal() {
    return true;
  }

  /**
   * Called by permuteParamRecursively() when a combination of parameters is complete and before this object to be yielded.
   *
   * The the following data should already be ready:
   *   - this.id
   *   - this.in.paramsNumberArrayObject: Every should-be-packed parameter.
   *   - this.in.Xxx: every non-packed parameter.
   *   - this.out.Xxx: every parameter.
   *
   * This method should fill the following data:
   *   - this.in.inputFloat32Array
   *   - this.in.byteOffsetBegin
   *
   * Sub-class should override this method.
   */
  onYield_before() {
  }

  /**
   * Called by permuteParamRecursively() when a combination of parameters is complete and after this object has been yielded.
   *
   * Usually, this method should clear some temperary data members.
   *
   * Sub-class should override this method.
   */
  onYield_after() {
  }

  /**
   * Modify specified parameter's value and record in this.modifyParamValueHistory so that they could be restore by restoreParamValues().
   *
   * @param {ParamDesc.Xxx} paramDesc
   *   The parameter to be doubled.
   *
   * @param {integer} outValue_specified
   *   The new value to be placed at the this.out[ paramDesc.paramName ].
   */
  modifyParamValue( paramDesc, outValue_specified ) {
    let paramName = paramDesc.paramName;

    let outValue_original = this.out[ paramName ];
    if ( outValue_original == undefined )
      return; // The parameter does not exist. No need to modify it.

    let valueDesc = paramDesc.valueDesc;
    let valueRange = valueDesc.range;

    let outValue_new = valueRange.adjust( outValue_specified ); // Confirm the new value is legal.

    this.out[ paramName ] = outValue_new;

    let inValue_original, inValue_new;

    let singleMinMax = [ outValue_new, outValue_new ]; // Only generate one new value.
    for ( let pair of valueRange.valueInputOutputGenerator( undefined, singleMinMax ) ) {

      inValue_new = pair.valueInput;

      if ( this.in[ paramName ] != undefined ) {
        inValue_original = this.in[ paramName ];
        this.in[ paramName ] = inValue_new;
      }

      if ( this.in.paramsNumberArrayObject[ paramName ] != undefined ) { // Note: If the element exists, it must be an array.
        inValue_original = this.in.paramsNumberArrayObject[ paramName ][ 0 ];
        this.in.paramsNumberArrayObject[ paramName ][ 0 ] = inValue_new; // The value is always at the element 0.
      }
    }

    let changeRecord = new ParamValueChangeRecord( paramDesc, inValue_original, outValue_original, inValue_new, outValue_new, outValue_specified );
    this.modifyParamValueHistory.push( changeRecord );
  }

  /**
   * Restore parameters' values according to this.modifyParamValueHistory. And empty this.modifyParamValueHistory.
   */
  restoreParamValues() {
    for ( let i = this.modifyParamValueHistory.length - 1; i >= 0; --i ) { // From the last to first.
      let changeRecord = this.modifyParamValueHistory[ i ];
      let paramName = changeRecord.paramDesc.paramName;

      if ( this.out[ paramName ] != undefined )
        this.out[ paramName ] = changeRecord.outValue_original;

      if ( this.in[ paramName ] != undefined ) {
        this.in[ paramName ] = changeRecord.inValue_original;
      }

      if ( this.in.paramsNumberArrayObject[ paramName ] != undefined ) { // Note: If the element exists, it must be an array.
        this.in.paramsNumberArrayObject[ paramName ][ 0 ] = changeRecord.inValue_original; // The value is always at the element 0.
      }
    }

    this.modifyParamValueHistory.length = 0; // Clear history.
  }

  /**
   * Ensure io_object[ propertyName ] exists as a number array with specified length. It will be filled with random number
   * as ( sequence_nunmer + random_number_offset )
   *
   * @param {object} io_object        The object to be checked and modified.
   * @param {string} propertyName     The property io_object[ propertyName ] will be ensured as a number array.
   * @param {number} elementCount     The property io_object[ propertyName ].length will be ensured as elementCount.
   * @param {number} randomOffsetMin  The random number offet lower bound.
   * @param {number} randomOffsetMax  The random number offet upperer bound.
   */
  static ensure_object_property_numberArray_length_filled( io_object, propertyName, elementCount, randomOffsetMin, randomOffsetMax ) {

    if (   ( io_object[ propertyName ] == undefined )          // The property does not exist.
        || ( !( io_object[ propertyName ] instanceof Array ) ) // The property exists but is not an array.
       ) {
      io_object[ propertyName ] = new Array( elementCount );   // Ensure array with specified length.

    } else {                                                   // The property exists and is an array.
      io_object[ propertyName ].length = elementCount;         // Ensure it with specified length.
    }

    RandTools.fill_numberArray( io_object[ propertyName ], elementCount, randomOffsetMin, randomOffsetMax );
  }

  /**
   * Responsible for generating testing paramters combinations.
   *
   * @param {ParamDescConfig[]} paramDescConfigArray
   *   List all the parameters to be used in permutation combination.
   *
   * @yield {Base}
   *   Yield this object itself. The returned object (it is this object itself) should not be modified because it will be re-used.
   */
  static * ParamsGenerator( paramDescConfigArray ) {
    this.config = { paramDescConfigArray: paramDescConfigArray };

    this.in.paramsNumberArrayObject = {}; // All parameters which will be packed into weights array.
    yield *Base.permuteParamRecursively.call( this, 0 );
  }

  /**
   * This method will modify this.id and this.in.paramsNumberArrayObject. It also calls itself recursively to permute all parameters.
   *
   * @param {number} currentParamDescIndex
   *   The index into the this.paramDescArray[]. It represents the current parameter to be tried.
   *
   * @yield {Base}
   *   Every time one kind of parameters' combination is generated, the this.result will be yielded.
   */
  static * permuteParamRecursively( currentParamDescConfigIndex ) {

    if ( currentParamDescConfigIndex >= this.config.paramDescConfigArray.length ) {
      // All parameters are used to be composed as one kind of combination.

      ++this.id; // Every combination has unique id no matter whether is legal to be yielded.

      let bLegalToYield = this.onYield_isLegal();
      if ( bLegalToYield ) {

        ++this.yieldCount;  // Complete one kind of combination.

        this.onYield_before();
        yield this;
        this.onYield_after();
        this.restoreParamValues(); // Restore this object because onYield_before() may modify it.
      }

      return; // Stop this recusive. Back-track to another parameters combination.
    }

    let nextParamDescConfigIndex = currentParamDescConfigIndex + 1;

    let paramDescConfig = this.config.paramDescConfigArray[ currentParamDescConfigIndex ];
    let paramDesc = paramDescConfig.paramDesc;
    for ( let pair of paramDesc.valueDesc.range.valueInputOutputGenerator( undefined, paramDescConfig.valueOutMinMax ) ) {

      //!!! (2021/07/06 Temp Debug) Check the algorithm might be wrong.
      //if ( paramDesc.valueDesc.range.adjust( pair.valueInput ) != pair.valueOutput )
      //  debugger;

      this.out[ paramDesc.paramName ] = pair.valueOutput;

      // Randomly place the parameter directly or in weights array.

      //!!! (2021/07/19 Temp Used) For testing without randomly.
      //let dice = 0;
      let dice = Math.random();
      if ( dice < 0.5 ) {
        // Try parameter value assigned directly (i.e. by specifying).
        this.in[ paramDesc.paramName ] = pair.valueInput;
        yield *Base.permuteParamRecursively.call( this, nextParamDescConfigIndex );

      } else {
        // Try parameter value assigned from inputFloat32Array (i.e. by evolution).
        this.in[ paramDesc.paramName ] = null;
        this.in.paramsNumberArrayObject[ paramDesc.paramName ] = pair.valueInput; // (number or number array)
        yield *Base.permuteParamRecursively.call( this, nextParamDescConfigIndex );

        this.in.paramsNumberArrayObject[ paramDesc.paramName ] = undefined; // So that it could be re-tried as by-specifying when backtracking.
      }
    }
  }

}
<|endoftext|>


<commit_before>(function() {

	exports.getRandomID = function() {
		return String(Math.floor(Math.random() * 98765862));
	}

	exports.getSkinsDir = function() {
		Ti.Filesystem.getFile(Ti.Filesystem.getApplicationDataDirectory() + 'skins/').createDirectory();
		return Ti.Filesystem.getApplicationDataDirectory() + 'skins/';
	}

	exports.getBGImage = function() {
		if(exports.isiPad()) {
			return '/img/bg_ipad.png';
		} else {
			return '/img/bg.png';
		}
	}

	exports.getNavColor = function() {
		return '#6d482b';
	}

	exports.isiPhone = function() {
		return (Ti.Platform.getOsname() === 'iphone');
	}

	exports.isiPad = function() {
		return (Ti.Platform.getOsname() === 'ipad');
	}

	exports.createLoadingWindow = function() {
		var win = Ti.UI.createWindow({
			width: 320,
			height: Ti.UI.FILL,
			left: 0,
			top: 0
		}),

		view = Ti.UI.createView({
			height: 60,
			width: 60,
			borderRadius: 10,
			backgroundColor: 'black',
			opacity: 0.6
		}),

		spinWheel = Ti.UI.createActivityIndicator({
			style: Ti.UI.iPhone.ActivityIndicatorStyle.BIG
		});

		win.add(view);
		view.add(spinWheel);
		spinWheel.show();

		return win;
	}

	exports.getTextFieldRow = function(text, hint) {
		var row = Ti.UI.createTableViewRow({
			selectionStyle: Ti.UI.iPhone.TableViewCellSelectionStyle.NONE
		}),

		rowText = Ti.UI.createLabel({
			text: text,
			left: 10,
			width: 120,
			height: 20,
			font: {
				fontWeight: 'bold',
				fontSize: 17
			}
		}),

		textfield = Ti.UI.createTextField({
			hintText: hint,
			color: '#336699',
			height: 30,
			width: 160,
			right: 5,
			borderStyle: Ti.UI.INPUT_BORDERSTYLE_NONE,
			returnKeyType: Ti.UI.RETURNKEY_NEXT,
			clearButtonMode: Ti.UI.INPUT_BUTTONMODE_ONFOCUS
		});

		row.add(rowText);
		row.add(textfield);
		return row;
	}

	exports.getTextAreaRow = function(text) {
		var row = Ti.UI.createTableViewRow({
			selectionStyle: Ti.UI.iPhone.TableViewCellSelectionStyle.NONE,
			height: 100
		}),

		rowText = Ti.UI.createLabel({
			text: text,
			left: 10,
			width: 120,
			height: 20,
			font: {
				fontWeight: 'bold',
				fontSize: 17
			}
		}),

		textarea = Ti.UI.createTextArea({
			color: '#336699',
			height: 98,
			right: 10,
			width: 160,
			borderStyle: Ti.UI.INPUT_BORDERSTYLE_NONE,
			returnKeyType: Ti.UI.RETURNKEY_NEXT,
			clearButtonMode: Ti.UI.INPUT_BUTTONMODE_ONFOCUS,
			font: {
				fontSize: 15
			}
		});

		row.add(rowText);
		row.add(textarea);
		return row;
	}

	exports.closeiPadSkinDetails = function(ipad_win) {
		var detail = ipad_win.detailContent;

		ipad_win.detailWin.remove(detail);
		detail = null;

		ipad_win.detailWin.setRightNavButton(null, {animated: true});
		ipad_win.detailWin.setLeftNavButton(null, {animated: true});

		ipad_win.detailContent = ipad_win.initialInfoView;
		ipad_win.detailContent.setOpacity(0);

		ipad_win.detailWin.add(ipad_win.detailContent);
		ipad_win.detailContent.animate({
			opacity: 1,
			duration: 300,
			curve: Ti.UI.ANIMATION_CURVE_EASE_IN
		});
	}

})();
<commit_msg>Improve layout on other textfields<commit_after>(function() {

	exports.getRandomID = function() {
		return String(Math.floor(Math.random() * 98765862));
	}

	exports.getSkinsDir = function() {
		Ti.Filesystem.getFile(Ti.Filesystem.getApplicationDataDirectory() + 'skins/').createDirectory();
		return Ti.Filesystem.getApplicationDataDirectory() + 'skins/';
	}

	exports.getBGImage = function() {
		if(exports.isiPad()) {
			return '/img/bg_ipad.png';
		} else {
			return '/img/bg.png';
		}
	}

	exports.getNavColor = function() {
		return '#6d482b';
	}

	exports.isiPhone = function() {
		return (Ti.Platform.getOsname() === 'iphone');
	}

	exports.isiPad = function() {
		return (Ti.Platform.getOsname() === 'ipad');
	}

	exports.createLoadingWindow = function() {
		var win = Ti.UI.createWindow({
			width: 320,
			height: Ti.UI.FILL,
			left: 0,
			top: 0
		}),

		view = Ti.UI.createView({
			height: 60,
			width: 60,
			borderRadius: 10,
			backgroundColor: 'black',
			opacity: 0.6
		}),

		spinWheel = Ti.UI.createActivityIndicator({
			style: Ti.UI.iPhone.ActivityIndicatorStyle.BIG
		});

		win.add(view);
		view.add(spinWheel);
		spinWheel.show();

		return win;
	}

	exports.getTextFieldRow = function(text, hint) {
		var row = Ti.UI.createTableViewRow({
			selectionStyle: Ti.UI.iPhone.TableViewCellSelectionStyle.NONE,
			layout: 'horizontal'
		}),

		rowText = Ti.UI.createLabel({
			text: text,
			left: 10,
			width: Ti.UI.SIZE,
			top: 5,
			bottom: 5,
			height: 30,
			font: {
				fontWeight: 'bold',
				fontSize: 17
			}
		}),

		textfield = Ti.UI.createTextField({
			hintText: hint,
			color: '#336699',
			right: 10,
			left: 5,
			top: 5,
			bottom: 5,
			height: 30,
			width: Ti.UI.FILL,
			textAlign: Ti.UI.TEXT_ALIGNMENT_RIGHT,
			borderStyle: Ti.UI.INPUT_BORDERSTYLE_NONE,
			returnKeyType: Ti.UI.RETURNKEY_NEXT,
			clearButtonMode: Ti.UI.INPUT_BUTTONMODE_ONFOCUS
		});

		row.add(rowText);

		rowText.addEventListener('postlayout', function() {
			if(rowText.rect.width >= 140) {
				rowText.width = 140;
			}
		});

		row.add(textfield);
		return row;
	}

	exports.getTextAreaRow = function(text) {
		var row = Ti.UI.createTableViewRow({
			selectionStyle: Ti.UI.iPhone.TableViewCellSelectionStyle.NONE,
			height: 100
		}),

		rowText = Ti.UI.createLabel({
			text: text,
			left: 10,
			width: 120,
			height: 20,
			font: {
				fontWeight: 'bold',
				fontSize: 17
			}
		}),

		textarea = Ti.UI.createTextArea({
			color: '#336699',
			height: 98,
			right: 10,
			width: 160,
			borderStyle: Ti.UI.INPUT_BORDERSTYLE_NONE,
			returnKeyType: Ti.UI.RETURNKEY_NEXT,
			clearButtonMode: Ti.UI.INPUT_BUTTONMODE_ONFOCUS,
			font: {
				fontSize: 15
			}
		});

		row.add(rowText);
		row.add(textarea);
		return row;
	}

	exports.closeiPadSkinDetails = function(ipad_win) {
		var detail = ipad_win.detailContent;

		ipad_win.detailWin.remove(detail);
		detail = null;

		ipad_win.detailWin.setRightNavButton(null, {animated: true});
		ipad_win.detailWin.setLeftNavButton(null, {animated: true});

		ipad_win.detailContent = ipad_win.initialInfoView;
		ipad_win.detailContent.setOpacity(0);

		ipad_win.detailWin.add(ipad_win.detailContent);
		ipad_win.detailContent.animate({
			opacity: 1,
			duration: 300,
			curve: Ti.UI.ANIMATION_CURVE_EASE_IN
		});
	}

})();
<|endoftext|>


<commit_before>// Karma configuration
// Generated on Sat Sep 21 2013 17:47:53 GMT-0400 (Eastern Daylight Time)

module.exports = function(config) {
  config.set({

    // base path, that will be used to resolve files and exclude
    basePath: '',

    // frameworks to use
    frameworks: ['jasmine'],

    // list of files / patterns to load in the browser
    files: [
      'source/vendor/underscore/underscore.js',
      'source/vendor/jquery/jquery.js',
      'source/vendor/jasmine-jquery/lib/jasmine-jquery.js',
      'source/js/**/*.js',
      'test/helpers/**/*.js',
      'test/**/*Spec.js'
    ],

    // list of files to exclude
    exclude: [
      '**/*.swp'
    ],

    // test results reporter to use
    // possible values: 'dots', 'progress', 'junit', 'growl', 'coverage'
    reporters: ['progress'],

    // web server port
    port: 9876,

    // enable / disable colors in the output (reporters and logs)
    colors: true,

    // level of logging
    // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
    logLevel: config.LOG_INFO,

    // enable / disable watching file and executing tests whenever any file changes
    autoWatch: true,

    // Start these browsers, currently available:
    // - Chrome
    // - ChromeCanary
    // - Firefox
    // - Opera
    // - Safari (only Mac)
    // - PhantomJS
    // - IE (only Windows)
    browsers: ['Chrome'],

    // If browser does not capture in given timeout [ms], kill it
    captureTimeout: 60000,

    // Continuous Integration mode
    // if true, it capture browsers, run tests and exit
    singleRun: false
  });
};
<commit_msg>added some dependencies in the karma config<commit_after>// Karma configuration
// Generated on Sat Sep 21 2013 17:47:53 GMT-0400 (Eastern Daylight Time)

module.exports = function(config) {
  config.set({

    // base path, that will be used to resolve files and exclude
    basePath: '',

    // frameworks to use
    frameworks: ['jasmine'],

    // list of files / patterns to load in the browser
    files: [
      'source/vendor/underscore/underscore.js',
      'source/vendor/jquery/jquery.js',
      'source/vendor/jasmine-jquery/lib/jasmine-jquery.js',
      'source/js/**/*.js',
      {
        pattern: 'source/css/**/*.css',
        watched: true,
        served: true,
        included: false
      },
      {
        pattern: 'test/fixtures/**/*.html',
        watched: true,
        served: true,
        included: false
      },
      'test/helpers/**/*.js',
      'test/**/*Spec.js'
    ],

    // list of files to exclude
    exclude: [
      '**/*.swp'
    ],

    // test results reporter to use
    // possible values: 'dots', 'progress', 'junit', 'growl', 'coverage'
    reporters: ['progress'],

    // web server port
    port: 9876,

    // enable / disable colors in the output (reporters and logs)
    colors: true,

    // level of logging
    // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
    logLevel: config.LOG_INFO,

    // enable / disable watching file and executing tests whenever any file changes
    autoWatch: true,

    // Start these browsers, currently available:
    // - Chrome
    // - ChromeCanary
    // - Firefox
    // - Opera
    // - Safari (only Mac)
    // - PhantomJS
    // - IE (only Windows)
    browsers: ['Chrome'],

    // If browser does not capture in given timeout [ms], kill it
    captureTimeout: 60000,

    // Continuous Integration mode
    // if true, it capture browsers, run tests and exit
    singleRun: false
  });
};
<|endoftext|>