<commit_before>define(['render', 'jquery', 'ajax', 'common'], function (render, $, ajax, common) {

    function loadingError(error) {
        ajax.elementErrorMessageFn($('#project-validation-stamp-mgt-error'))(error.responseText)
    }

    function loadValidationStamps(config, branch) {
        return $.get('ui/manage/project/{0}/branch/{1}/validation_stamp'.format(config.project, branch))
    }

    function displayBranches(config, stamps1, stamps2, target) {
        var project = config.project;
        var branch1 = config.branch1;
        var branch2 = config.branch2;
        // Indexation of validation stamps by names
        var stampNameFn = function (stamp) {
            return stamp.name;
        }
        var indexedStamps1 = common.uniqueIndex(stamps1, stampNameFn);
        var indexedStamps2 = common.uniqueIndex(stamps2, stampNameFn);
        // Gets all names in a sorted list
        var names = [];
        for (var name in indexedStamps1) {
            if (names.indexOf(name) < 0) {
                names.push(name);
            }
        }
        for (var name in indexedStamps2) {
            if (names.indexOf(name) < 0) {
                names.push(name);
            }
        }
        names.sort();
    }

    function loadBranches(config, target) {
        var branch1 = config.branch1;
        var branch2 = config.branch2;
        if (branch1 != '' && branch2 != '' && branch1 != branch2) {
            // Two parallel AJAX calls
            var ajax1 = loadValidationStamps(config, branch1);
            var ajax2 = loadValidationStamps(config, branch2);
            // Loading...
            ajax.showLoading({
                mode: 'container',
                el: $('#project-validation-stamp-mgt-loading')
            }, true);
            // Completion
            $.when(ajax1, ajax2).then(
                function (result1, result2) {
                    displayBranches(config, result1[0], result2[0], target);
                },
                loadingError
            ).done(
                function () {
                    ajax.showLoading({
                        mode: 'container',
                        el: $('#project-validation-stamp-mgt-loading')
                    }, false);
                }
            )
        }
    }

    return {
        url: function (config) {
            return 'ui/manage/project/{0}/branch'.format(config.project)
        },
        render: render.asSimpleTemplate(
            'project-validation-stamp-mgt',
            render.sameDataFn,
            function (config, branches, target) {
                config.branch1 = '';
                config.branch2 = '';
                // On selection of a branch
                target.find('select.project-validation-stamp-mgt-branch').change(function (e) {
                    var branchTarget = $(this).attr('data-target');
                    var branch = $(this).val();
                    if (branchTarget == '1') {
                        config.branch1 = branch;
                    } else {
                        config.branch2 = branch;
                    }
                    loadBranches(config, target);
                })
            }
        )
    }

});<commit_msg>#220 Getting the model for the grid<commit_after>define(['render', 'jquery', 'ajax', 'common'], function (render, $, ajax, common) {

    function loadingError(error) {
        ajax.elementErrorMessageFn($('#project-validation-stamp-mgt-error'))(error.responseText)
    }

    function loadValidationStamps(config, branch) {
        return $.get('ui/manage/project/{0}/branch/{1}/validation_stamp'.format(config.project, branch))
    }

    function displayBranches(config, stamps1, stamps2, target) {
        var project = config.project;
        var branch1 = config.branch1;
        var branch2 = config.branch2;

        // Indexation of validation stamps by names
        var stampNameFn = function (stamp) {
            return stamp.name;
        }
        var indexedStamps1 = common.uniqueIndex(stamps1, stampNameFn);
        var indexedStamps2 = common.uniqueIndex(stamps2, stampNameFn);

        // Gets all names in a sorted list
        var names = [];
        for (var name in indexedStamps1) {
            if (names.indexOf(name) < 0) {
                names.push(name);
            }
        }
        for (var name in indexedStamps2) {
            if (names.indexOf(name) < 0) {
                names.push(name);
            }
        }
        names.sort();

        // Creating the model
        var model = {
            project: project,
            branch1: branch1,
            branch2: branch2,
            stamps: []
        };
        $.each(names, function (index, name) {
            var line = {
                name: name
            };
            var stamp1 = indexedStamps1[name];
            if (stamp1) {
                line.stamp1 = stamp1;
            }
            var stamp2 = indexedStamps2[name];
            if (stamp2) {
                line.stamp2 = stamp2;
            }
            model.stamps.push(line);
        });
        console.log(model);
    }

    function loadBranches(config, target) {
        var branch1 = config.branch1;
        var branch2 = config.branch2;
        if (branch1 != '' && branch2 != '' && branch1 != branch2) {
            // Two parallel AJAX calls
            var ajax1 = loadValidationStamps(config, branch1);
            var ajax2 = loadValidationStamps(config, branch2);
            // Loading...
            ajax.showLoading({
                mode: 'container',
                el: $('#project-validation-stamp-mgt-loading')
            }, true);
            // Completion
            $.when(ajax1, ajax2).then(
                function (result1, result2) {
                    displayBranches(config, result1[0], result2[0], target);
                },
                loadingError
            ).done(
                function () {
                    ajax.showLoading({
                        mode: 'container',
                        el: $('#project-validation-stamp-mgt-loading')
                    }, false);
                }
            )
        }
    }

    return {
        url: function (config) {
            return 'ui/manage/project/{0}/branch'.format(config.project)
        },
        render: render.asSimpleTemplate(
            'project-validation-stamp-mgt',
            render.sameDataFn,
            function (config, branches, target) {
                config.branch1 = '';
                config.branch2 = '';
                // On selection of a branch
                target.find('select.project-validation-stamp-mgt-branch').change(function (e) {
                    var branchTarget = $(this).attr('data-target');
                    var branch = $(this).val();
                    if (branchTarget == '1') {
                        config.branch1 = branch;
                    } else {
                        config.branch2 = branch;
                    }
                    loadBranches(config, target);
                })
            }
        )
    }

});<|endoftext|>


<commit_before>import React, {PureComponent as Component} from 'react'
import PropTypes from 'prop-types'
import { default as Collapsible, propTypes as collapsibleTypes } from '../Collapsible'
import Flexy from '../Flexy'
import Heading from '../Heading'
import SortableDragHandle from '../Sortable/DragHandle'
import Icon from '../Icon'
import { createUniqueIDFactory } from '../../utilities/id'
import classNames from '../../utilities/classNames'

export const propTypes = Object.assign({}, collapsibleTypes, {
  header: PropTypes.element,
  title: PropTypes.string,
  isOpen: PropTypes.bool,
  sortable: PropTypes.bool
})

export const defaultProps = {
  duration: 200,
  isOpen: false,
  sortable: false
}

const uniqueID = createUniqueIDFactory('SidebarCollapsibleCard')

class SidebarCollapsibleCard extends Component {
  constructor (props) {
    super()
    this.state = {
      id: props.id || uniqueID(),
      isOpen: props.isOpen
    }
    this.handleToggleOpen = this.handleToggleOpen.bind(this)
  }

  componentWillUpdate (nextProps, nextState) {
    if (this.props.isOpen !== nextProps.isOpen) {
      this.handleToggleOpen()
    }
  }

  handleToggleOpen () {
    this.setState({ isOpen: !this.state.isOpen })
  }

  render () {
    const {
      children,
      className,
      duration,
      header,
      onClose,
      onOpen,
      isOpen,
      sortable,
      title,
      ...rest
    } = this.props
    const {
      isOpen: open,
      id: cardId
    } = this.state

    const componentClassName = classNames(
      'c-SidebarCollapsibleCard',
      open && 'is-open',
      className
    )

    const handleToggleOpen = this.handleToggleOpen

    const displayHeader = () => {
      if (header) return header
      if (title) {
        return (
          <Heading className='c-SidebarCollapsibleCard__title' size='h4' lineHeightReset>
            {title}
          </Heading>
        )
      }
      return null
    }

    const iconName = open ? 'caret-up' : 'caret-down'
    const regionId = `${cardId}-region`
    const headerMarkup = displayHeader()
    const dragHandleMarkup = sortable ? (
      <Flexy.Item>
        <SortableDragHandle className='c-SidebarCollapsibleCard__drag-handle' />
      </Flexy.Item>
    ) : null

    return (

          <Flexy gap='sm'>
            <Flexy.Block>
              {headerMarkup}
            </Flexy.Block>
            {dragHandleMarkup}
            <Flexy.Item>
              <Icon name={iconName} size='14' muted />
            </Flexy.Item>
          </Flexy>

          <Collapsible
            duration={duration}
            onOpen={onOpen}
            onClose={onClose}
            isOpen={open}
          >

              {children}

          </Collapsible>

    )
  }
}

SidebarCollapsibleCard.propTypes = propTypes
SidebarCollapsibleCard.defaultProps = defaultProps

export default SidebarCollapsibleCard
<commit_msg>Prevent default behavior on SidebarCollapsibleCard click<commit_after>import React, {PureComponent as Component} from 'react'
import PropTypes from 'prop-types'
import { default as Collapsible, propTypes as collapsibleTypes } from '../Collapsible'
import Flexy from '../Flexy'
import Heading from '../Heading'
import SortableDragHandle from '../Sortable/DragHandle'
import Icon from '../Icon'
import { createUniqueIDFactory } from '../../utilities/id'
import classNames from '../../utilities/classNames'

export const propTypes = Object.assign({}, collapsibleTypes, {
  header: PropTypes.element,
  title: PropTypes.string,
  isOpen: PropTypes.bool,
  sortable: PropTypes.bool
})

export const defaultProps = {
  duration: 200,
  isOpen: false,
  sortable: false
}

const uniqueID = createUniqueIDFactory('SidebarCollapsibleCard')

class SidebarCollapsibleCard extends Component {
  constructor (props) {
    super()
    this.state = {
      id: props.id || uniqueID(),
      isOpen: props.isOpen
    }
    this.handleToggleOpen = this.handleToggleOpen.bind(this)
  }

  componentWillUpdate (nextProps, nextState) {
    if (this.props.isOpen !== nextProps.isOpen) {
      this.handleToggleOpen()
    }
  }

  handleToggleOpen (e) {
    e.preventDefault()
    this.setState({ isOpen: !this.state.isOpen })
  }

  render () {
    const {
      children,
      className,
      duration,
      header,
      onClose,
      onOpen,
      isOpen,
      sortable,
      title,
      ...rest
    } = this.props
    const {
      isOpen: open,
      id: cardId
    } = this.state

    const componentClassName = classNames(
      'c-SidebarCollapsibleCard',
      open && 'is-open',
      className
    )

    const handleToggleOpen = this.handleToggleOpen

    const displayHeader = () => {
      if (header) return header
      if (title) {
        return (
          <Heading className='c-SidebarCollapsibleCard__title' size='h4' lineHeightReset>
            {title}
          </Heading>
        )
      }
      return null
    }

    const iconName = open ? 'caret-up' : 'caret-down'
    const regionId = `${cardId}-region`
    const headerMarkup = displayHeader()
    const dragHandleMarkup = sortable ? (
      <Flexy.Item>
        <SortableDragHandle className='c-SidebarCollapsibleCard__drag-handle' />
      </Flexy.Item>
    ) : null

    return (

          <Flexy gap='sm'>
            <Flexy.Block>
              {headerMarkup}
            </Flexy.Block>
            {dragHandleMarkup}
            <Flexy.Item>
              <Icon name={iconName} size='14' muted />
            </Flexy.Item>
          </Flexy>

          <Collapsible
            duration={duration}
            onOpen={onOpen}
            onClose={onClose}
            isOpen={open}
          >

              {children}

          </Collapsible>

    )
  }
}

SidebarCollapsibleCard.propTypes = propTypes
SidebarCollapsibleCard.defaultProps = defaultProps

export default SidebarCollapsibleCard
<|endoftext|>


<commit_before>// db.states.ensureIndex( { "url": 1 }, { unique: true , dropDups: true} )
// db.entity_url.ensureIndex( { "url": 1 }, { unique: true , dropDups: true} )
// db.entity_url_not_downloaded.ensureIndex( { "url": 1 }, { unique: true , dropDups: true} )
// db.cities.ensureIndex( { "url": 1 }, { unique: true , dropDups: true} )
// db.entities.ensureIndex( { "url": 1 }, { unique: true , dropDups: true} )
var mongoose = require('mongoose'),
    Q = require('q'),
    colors = require('colors');

mongoose.connect('mongodb://localhost/cnes2015');

var models = {
    City: mongoose.model('City', {
        'Estado': String,
        'NomeEstado': String,
        'cidade_IBGE': String,
        'cidade_cadastrados': String,
        'cidade_nome': String,
        'done': String,
        'url': String
    }),

    Entity: mongoose.model('Entity', {
        'Nome': String,
        'CNES': String,
        'CNPJ': String,
        'Nome Empresarial': String,
        'CPF': String,
        'Personalidade': String,
        'Logradouro': String,
        'N\xFAmero': String,
        'Telefone': String,
        'Complemento': String,
        'Bairro': String,
        'CEP': String,
        'Munic\xEDpio': String,
        'UF': String,
        'Tipo Estabelecimento': String,
        'Sub Tipo Estabelecimento': String,
        'Esfera Administrativa': String,
        'Gest\xE3o': String,
        'Natureza da Organiza\xE7\xE3o': String,
        'Depend\xEAncia': String,
        'N\xFAmero Alvar\xE1': String,
        '\xD3rg\xE3o Expedidor': String,
        'Data Expedi\xE7\xE3o': String,
        'url': String,
        'VCo_Unidade': String,
        'VEstado': String,
        'VCodMunicipio': String
    }),

    EntityUrl: mongoose.model('EntityUrl', {
        'url': String,
        'VCo_Unidade': String,
        'VEstado': String,
        'VCodMunicipio': String
    }),

    EntityToDownload: mongoose.model('EntityToDownload', {
        'url': String,
        'VCo_Unidade': String,
        'VEstado': String,
        'VCodMunicipio': String
    }),

    State: mongoose.model('State', {
        'estado_nome': String,
        'estado_total': String,
        'estado_%': String,
        'url': String
    })
}

module.exports = {
    models: models,

    save: function(entities, ModelObject) {
        var deferred = Q.defer();
        var isSaved = false;

        if (Object.prototype.toString.call(entities) === '[object Array]') {
            for (var i = entities.length - 1; i >= 0; i--) {
                var ent = JSON.flatten(entities[i]);
                var modelObj = new ModelObject(ent);
                modelObj.save(function(error, result) {
                    if (error) {
                        console.log(error);
                    }
                    deferred.resolve(true);
                });
            }
        } else {
            var modelObj = new ModelObject(JSON.flatten(entities));
            modelObj.save(function(error, result) {
                if (error) {
                    deferred.reject(error);
                }
                deferred.resolve(result);
            });
        }
        return deferred.promise;
    },

    delete: function(json, ModelObject) {
        var deferred = Q.defer();
        ModelObject.remove(json, function(error) {
            if (error) {
                deferred.reject(error);
            }
            deferred.resolve(true);
        });
        return deferred.promise;
    },

    findOne: function(json, ModelObject) {
        var deferred = Q.defer();
        var inputJson = json || {};

        ModelObject.findOne(inputJson, function(error, result) {
            if (error) {
                deferred.reject(error);
            }
            deferred.resolve(result);
        });
        return deferred.promise;
    },

    find: function(ModelObject) {
        var stream = ModelObject.find({}).stream();
        return stream;
    },

    count: function(ModelObject, callback) {
        ModelObject.count({}, function(err, count) {
            callback(count);
        });
    }
};

JSON.flatten = function(data) {
    var result = {};

    function recurse(cur, prop) {
        if (Object(cur) !== cur) {
            result[prop] = cur;
        } else if (Array.isArray(cur)) {
            for (var i = 0, l = cur.length; i < l; i++)
                recurse(cur[i], prop + '[' + i + ']');
            if (l == 0)
                result[prop] = [];
        } else {
            var isEmpty = true;
            for (var p in cur) {
                isEmpty = false;
                recurse(cur[p], prop ? prop + '.' + p : p);
            }
            if (isEmpty && prop) {
                var splitProp = prop.split('.').pop();
                //result[split_prop] = {};
                result[prop] = {};
            }
        }
    }
    recurse(data, '');
    return result;
};<commit_msg>removed unused table<commit_after>// db.states.ensureIndex( { "url": 1 }, { unique: true , dropDups: true} )
// db.entity_url.ensureIndex( { "url": 1 }, { unique: true , dropDups: true} )
// db.entity_url_not_downloaded.ensureIndex( { "url": 1 }, { unique: true , dropDups: true} )
// db.cities.ensureIndex( { "url": 1 }, { unique: true , dropDups: true} )
// db.entities.ensureIndex( { "url": 1 }, { unique: true , dropDups: true} )
var mongoose = require('mongoose'),
    Q = require('q'),
    colors = require('colors');

mongoose.connect('mongodb://localhost/cnes2015');

var models = {
    City: mongoose.model('City', {
        'Estado': String,
        'NomeEstado': String,
        'cidade_IBGE': String,
        'cidade_cadastrados': String,
        'cidade_nome': String,
        'done': String,
        'url': String
    }),

    Entity: mongoose.model('Entity', {
        'Nome': String,
        'CNES': String,
        'CNPJ': String,
        'Nome Empresarial': String,
        'CPF': String,
        'Personalidade': String,
        'Logradouro': String,
        'N\xFAmero': String,
        'Telefone': String,
        'Complemento': String,
        'Bairro': String,
        'CEP': String,
        'Munic\xEDpio': String,
        'UF': String,
        'Tipo Estabelecimento': String,
        'Sub Tipo Estabelecimento': String,
        'Esfera Administrativa': String,
        'Gest\xE3o': String,
        'Natureza da Organiza\xE7\xE3o': String,
        'Depend\xEAncia': String,
        'N\xFAmero Alvar\xE1': String,
        '\xD3rg\xE3o Expedidor': String,
        'Data Expedi\xE7\xE3o': String,
        'url': String,
        'VCo_Unidade': String,
        'VEstado': String,
        'VCodMunicipio': String
    }),

    EntityUrl: mongoose.model('EntityUrl', {
        'url': String,
        'VCo_Unidade': String,
        'VEstado': String,
        'VCodMunicipio': String
    }),

    State: mongoose.model('State', {
        'estado_nome': String,
        'estado_total': String,
        'estado_%': String,
        'url': String
    })
}

module.exports = {
    models: models,

    save: function(entities, ModelObject) {
        var deferred = Q.defer();
        var isSaved = false;

        if (Object.prototype.toString.call(entities) === '[object Array]') {
            for (var i = entities.length - 1; i >= 0; i--) {
                var ent = JSON.flatten(entities[i]);
                var modelObj = new ModelObject(ent);
                modelObj.save(function(error, result) {
                    if (error) {
                        console.log(error);
                    }
                    deferred.resolve(true);
                });
            }
        } else {
            var modelObj = new ModelObject(JSON.flatten(entities));
            modelObj.save(function(error, result) {
                if (error) {
                    deferred.reject(error);
                }
                deferred.resolve(result);
            });
        }
        return deferred.promise;
    },

    delete: function(json, ModelObject) {
        var deferred = Q.defer();
        ModelObject.remove(json, function(error) {
            if (error) {
                deferred.reject(error);
            }
            deferred.resolve(true);
        });
        return deferred.promise;
    },

    findOne: function(json, ModelObject) {
        var deferred = Q.defer();
        var inputJson = json || {};

        ModelObject.findOne(inputJson, function(error, result) {
            if (error) {
                deferred.reject(error);
            }
            deferred.resolve(result);
        });
        return deferred.promise;
    },

    find: function(ModelObject) {
        var stream = ModelObject.find({}).stream();
        return stream;
    },

    count: function(ModelObject, callback) {
        ModelObject.count({}, function(err, count) {
            callback(count);
        });
    }
};

JSON.flatten = function(data) {
    var result = {};

    function recurse(cur, prop) {
        if (Object(cur) !== cur) {
            result[prop] = cur;
        } else if (Array.isArray(cur)) {
            for (var i = 0, l = cur.length; i < l; i++)
                recurse(cur[i], prop + '[' + i + ']');
            if (l == 0)
                result[prop] = [];
        } else {
            var isEmpty = true;
            for (var p in cur) {
                isEmpty = false;
                recurse(cur[p], prop ? prop + '.' + p : p);
            }
            if (isEmpty && prop) {
                var splitProp = prop.split('.').pop();
                //result[split_prop] = {};
                result[prop] = {};
            }
        }
    }
    recurse(data, '');
    return result;
};
<|endoftext|>


<commit_before>/*!
 * palapala.js v2.0.2
 * https://github.com/splead/palapala.js
 * http://www.palapala.jp/
 *
 * Copyright (c) 2012, Kei Osumi
 * http://www.splead.co.jp/
 *
 * Released under the MIT license.
 * https://github.com/splead/palapala.js/blob/master/license.txt
 *
 */

function palapala ( actions, options ) {

	var timer_msec = 50;
	var time_line  = {};
	var play_list  = [];

	// set action onto time line
	actions = actions || {};
	time_line = setTimeline( actions );

	// set options
	options = options || {};

	if ( options.fps ) {
		timer_msec = 1000 / options.fps
	}

	if ( options.play !== 'undefined' ) {
		var play = options.play;
		if ( play instanceof Array ) {
			play = play.join( ',' );
		}
		play = ',' + play + ','
		for ( var id in time_line ) {
			if ( play.indexOf( ',' + id + ',' ) == -1 ) {
				// stop action
				time_line[ id ].step = -1;
			} else {
				// set action start point
				time_line[ id ].step = 0;
			}
		}
	}

	// start animation
	animation();

	function animation () {

		for ( var id in time_line ) {

			// set play
			for ( var i=0; i<play_list.length; i++ ) {
				var pid = play_list.pop();
				if (time_line[ pid ] ) {
					time_line[ pid ].step = 0;
				} else {
					alert( "action '" + pid + "' is not defined" );
					throw "action '" + pid + "' is not defined";
				}
			}

			// get each action
			var action = time_line[ id ];

			// current step of action
			var step = action.step;

			// do action if step > -1
			if ( step > -1 ) {

				// action match to step
				if ( action[ step ] ) {

					// show
					if ( typeof action[ step ].show !== 'undefined' ) {

						for ( var id in action[ step ][ 'show' ] ) {

							var target = action[ step ][ 'show' ][ id ];
							if ( target instanceof Array ) {
								target = target.join( ',' );
							}
							target = ',' + target + ','
							var node = document.getElementById( id );
							for ( var i=0; i<node.childNodes.length; i++ ) {
								if ( node.childNodes[ i ].style ) {
									if ( target.indexOf( ',' + node.childNodes[ i ].id + ',' ) == -1 ) {
										node.childNodes[ i ].style.display = "none";
									} else {
										node.childNodes[ i ].style.display = "block";
									}
								}
							}
						}
					}

					// style
					if ( typeof action[ step ].style !== 'undefined' ) {
						for ( var id in action[ step ][ 'style' ] ) {
							if ( action[ step ][ 'style' ][ id ] == "" ) {
								className = document.getElementById( id ).className;
								document.getElementById( id ).className = className.split( '  ' )[0];
							} else {
								className = document.getElementById( id ).className;
								document.getElementById( id ).className = className + '  ' + action[ step ][ 'style' ][ id ];
							}
						}
					}

					// action
					if ( typeof action[ step ].action !== 'undefined' ) {
						if ( action[ step ].action instanceof Array ) {
							play_list = play_list.concat( action[ step ].action );
						} else {
							play_list.push( action[ step ].action );
						}
					}

					// repeat
					if ( typeof action[ step ].repeat !== 'undefined' ) {
						if ( action[ step ].repeat != 0 ) {
							// set action start point
							action.step = -1;
							action[ step ].repeat = action[ step ].repeat - 1;
						} else {
							// stop action
							action.step = -2;
						}
					}
				}

				// count up the step of action
				action.step = action.step + 1;
			}
		}

		// go to next step
		setTimeout( animation, timer_msec );
	}

	function setTimeline( actions ) {

		var time_line = {};

		for ( var id in actions ) {

			// set action as serial format
			if ( actions[ id ] instanceof Array ) {

				var action = {};
				var step = 0;

				for ( var i in actions[ id ] ) {

					if ( actions[ id ][ i ].interval ) {
						step = step + actions[ id ][ i ].interval;
					} else {
						action[ step ] = actions[ id ][ i ];
						step = step + 1;
					}
				}
				time_line[ id ] = action;
			} else {
				time_line[ id ] = actions[ id ];
			}

			// check and add repeat
			var last = 0;
			for ( var no in time_line[ id ] ) {
				if ( last < parseInt( no ) ) {
					last = parseInt( no );
				}
			}
			if( time_line[ id ][ last ] ){
				if ( typeof time_line[ id ][ last ][ 'repeat' ] == 'undefined' ) {
					time_line[ id ][ last + 1 ] = { repeat: 0 };
					time_line[ id ][ 'repeat' ] = 0;
				} else {
					time_line[ id ][ 'repeat' ] = time_line[ id ][ last ][ 'repeat' ];
				}
			} else {
				time_line[ id ][ 0 ] = { repeat: 0 };
				time_line[ id ][ 'repeat' ] = 0;
			}

			// add step counter and repeat counter
			time_line[ id ][ 'step' ] = 0;
		}

		return time_line;
	}

	return {
		play: function( ids ) {
			if ( ids instanceof Array ) {
				play_list = play_list.concat( ids );
			} else {
				play_list.push( ids );
			}
		}
	}
};
<commit_msg>bug fix<commit_after>/*!
 * palapala.js v2.0.3
 * https://github.com/splead/palapala.js
 * http://www.palapala.jp/
 *
 * Copyright (c) 2012, Kei Osumi
 * http://www.splead.co.jp/
 *
 * Released under the MIT license.
 * https://github.com/splead/palapala.js/blob/master/license.txt
 *
 */

function palapala ( actions, options ) {

	var timer_msec = 50;
	var time_line  = {};
	var play_list  = [];

	// set action onto time line
	actions = actions || {};
	time_line = setTimeline( actions );

	// set options
	options = options || {};

	if ( options.fps ) {
		timer_msec = 1000 / options.fps
	}

	if ( options.play !== 'undefined' ) {
		var play = options.play;
		if ( play instanceof Array ) {
			play = play.join( ',' );
		}
		play = ',' + play + ','
		for ( var id in time_line ) {
			if ( play.indexOf( ',' + id + ',' ) == -1 ) {
				// stop action
				time_line[ id ].step = -1;
			} else {
				// set action start point
				time_line[ id ].step = 0;
			}
		}
	}

	// start animation
	animation();

	function animation () {

		for ( var id in time_line ) {

			// set play
			for ( var i=0; i<play_list.length; i++ ) {
				var pid = play_list.pop();
				if (time_line[ pid ] ) {
					time_line[ pid ].step = 0;
				} else {
					alert( "action '" + pid + "' is not defined" );
					throw "action '" + pid + "' is not defined";
				}
			}

			// get each action
			var action = time_line[ id ];

			// current step of action
			var step = action.step;

			// do action if step > -1
			if ( step > -1 ) {

				// action match to step
				if ( action[ step ] ) {

					// show
					if ( typeof action[ step ].show !== 'undefined' ) {

						for ( var id in action[ step ][ 'show' ] ) {

							var target = action[ step ][ 'show' ][ id ];
							if ( target instanceof Array ) {
								target = target.join( ',' );
							}
							target = ',' + target + ','
							var node = document.getElementById( id );
							for ( var i=0; i<node.childNodes.length; i++ ) {
								if ( node.childNodes[ i ].style ) {
									if ( target.indexOf( ',' + node.childNodes[ i ].id + ',' ) == -1 ) {
										node.childNodes[ i ].style.display = "none";
									} else {
										node.childNodes[ i ].style.display = "block";
									}
								}
							}
						}
					}

					// style
					if ( typeof action[ step ].style !== 'undefined' ) {
						for ( var id in action[ step ][ 'style' ] ) {
							if ( action[ step ][ 'style' ][ id ] == "" ) {
								className = document.getElementById( id ).className;
								document.getElementById( id ).className = className.split( '  ' )[0];
							} else {
								className = document.getElementById( id ).className;
								document.getElementById( id ).className = className + '  ' + action[ step ][ 'style' ][ id ];
							}
						}
					}

					// action
					if ( typeof action[ step ].action !== 'undefined' ) {
						if ( action[ step ].action instanceof Array ) {
							play_list = play_list.concat( action[ step ].action );
						} else {
							play_list.push( action[ step ].action );
						}
					}

					// repeat
					if ( typeof action[ step ].repeat !== 'undefined' ) {
						if ( action[ step ].repeat != 0 ) {
							// set action start point
							action.step = -1;
							action[ step ].repeat = action[ step ].repeat - 1;
						} else {
							// stop action
							action.step = -2;
						}
					}
				}

				// count up the step of action
				action.step = action.step + 1;
			}
		}

		// go to next step
		setTimeout( animation, timer_msec );
	}

	function setTimeline( actions ) {

		var time_line = {};

		for ( var id in actions ) {

			// set action as serial format
			if ( actions[ id ] instanceof Array ) {

				var action = {};
				var step = 0;

				for ( var i in actions[ id ] ) {

					if ( actions[ id ][ i ].interval ) {
						step = step + actions[ id ][ i ].interval;
					} else {
						action[ step ] = actions[ id ][ i ];
						step = step + 1;
					}
				}
				time_line[ id ] = action;
			} else {
				time_line[ id ] = actions[ id ];
			}

			// check and add repeat
			var last = 0;
			for ( var no in time_line[ id ] ) {
				if ( last < parseInt( no ) ) {
					last = parseInt( no );
				}
			}
			if( time_line[ id ][ last ] ){
				if ( typeof time_line[ id ][ last ][ 'repeat' ] == 'undefined' ) {
					time_line[ id ][ last + 1 ] = { repeat: 0 };
					time_line[ id ][ 'repeat' ] = 0;
				} else {
					time_line[ id ][ 'repeat' ] = time_line[ id ][ last ][ 'repeat' ];
				}
			} else {
				time_line[ id ][ 0 ] = { repeat: 0 };
				time_line[ id ][ 'repeat' ] = 0;
			}

			// add step counter and repeat counter
			time_line[ id ][ 'step' ] = 0;
		}

		return time_line;
	}

	return {
		play: function( ids ) {
			if ( ids instanceof Array ) {
				play_list = play_list.concat( ids );
			} else {
				play_list.push( ids );
			}
		}
	}
};
<|endoftext|>


<commit_before>import { Color, pt, Rectangle } from "lively.graphics";
import { arr, promise } from "lively.lang";
import { connect, disconnect } from "lively.bindings";
import { Window, morph, show } from "../index.js";
import { GridLayout } from "../layout.js";
import CodeEditor from "./code-editor.js";

// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
// commands
// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

function commandsForBrowser(browser) {
  var pList = browser.get("packageList"),
      mList = browser.get("moduleList"),
      editor = browser.get("sourceEditor"),
      world = browser.world();

  return [
    {name: "focus list with selection", exec: () => focusList(mList.selection ? mList : pList)},
    {name: "focus package list", exec: () => focusList(pList)},
    {name: "focus module list", exec: () => focusList(mList)},
    {name: "focus source editor", exec: () => { editor.focus(); editor.show(); return true; }},

    {name: "reload module", exec: async () => {
      var m = browser.selectedModule;
      if (!m) return browser.world().inform("No module selected", {requester: browser});
      try {
        await (await browser.systemInterface()).interactivelyReloadModule(null, m.name);
      } catch(err) {
        browser.world().inform(`Error while reloading ${m.name}:\n${err.stack || err}`, {requester: browser});
        return true;
      }
      show(`Reloaded ${m.name}`);
      browser.selectModuleNamed(m.nameInPackage);
      return true;
    }},

    {name: "load or add module", exec: async (browser) => {
      var p = browser.selectedPackage;
      try {
        var mods = await (await browser.systemInterface()).interactivelyAddModule(null, p ? p.address : null, browser.world());
      } catch(e) {
        e === "Canceled" ?
          show(e) :
          browser.world().inform(`Error while trying to load modules:\n${e.stack || e}`, {requester: browser});
        return;
      }

      mods.forEach(({name, error}) =>
        error ? show(`Error while loading module ${name}: ${error.stack || error}`) :
                show(`Module ${name} loaded`))
      await browser.updateModuleList(p);
      mods.length && browser.selectModuleNamed(mods[0].name);
      return true;
    }},

    {name: "run all tests in module",
     exec: (browser) => {
       var m = browser.selectedModule;
        if (!m) return browser.world().inform("No module selected", {requester: browser});
       return runTestsInModule(browser, m.name, null);
     }},

    {name: "run tests at point",
     exec: async (browser) => {
       var m = browser.selectedModule;
        if (!m) return browser.world().inform("No module selected", {requester: browser});

        var {parse, query: {nodesAt}} = await System.import("lively.ast");
        var ed = browser.get("sourceEditor").text;
        var source = ed.textString;
        var parsed = parse(source);
        var nodes = nodesAt(ed.document.positionToIndex(ed.cursorPosition), parsed)
          .filter(n => n.type === "CallExpression" && n.callee.name && n.callee.name.match(/describe|it/) && n.arguments[0].type === "Literal")
            .map(n => ({
              type: n.callee.name.match(/describe/) ? "suite" : "test",
              title: n.arguments[0].value,
          }))

        if (!nodes.length)
          return browser.world().inform("No test at " + JSON.stringify(ed.cursorPosition), {requester: browser});

       var spec = {fullTitle: arr.pluck(nodes, "title").join(" "), type: arr.last(nodes).type, file: m.name}
       return runTestsInModule(browser, m.name, spec);
     }}
  ]

  function focusList(list) {
    list.scrollSelectionIntoView();
    list.update();
    list.show();
    list.focus();
    return list
  }

  function runTestsInModule(browser, moduleName, spec) {
    var runner = browser.get("test runner window");
    if (!runner)
      runner = world.execCommand("open test runner");
    if (runner.minimized)
      runner.toggleMinimize();
    return spec ?
      runner.targetMorph[spec.type === "suite" ? "runSuite" : "runTest"](spec.fullTitle):
      runner.targetMorph.runTestFile(moduleName);
  }

}

// -=-=-=-=-=-
// Browser UI
// -=-=-=-=-=-

export class Browser extends Window {

  static async browse(packageName, moduleName, textPosition = {row: 0, column: 0}, browserOrProps = {}) {
    var browser = browserOrProps instanceof Browser ? browserOrProps : new this(browserOrProps);
    if (!browser.world())
      browser.openInWorldNearHand();
    await browser.whenRendered();
    if (packageName) await browser.selectPackageNamed(packageName);
    if (packageName && moduleName) await browser.selectModuleNamed(moduleName);
    if (textPosition) {
      var text = browser.get("sourceEditor").text;
      text.cursorPosition = textPosition;
      text.centerRow(textPosition.row);
    }
    return browser;
  }

  constructor(props = {}) {
    super({
      name: "browser",
      extent: pt(700,600),
      ...props,
      targetMorph: this.build()
    });
    this.state = {packageUpdateInProgress: null, moduleUpdateInProgress: null};
    this.onLoad();
  }

  get isBrowser() { return true; }

  focus() {
    this.get("sourceEditor").focus();
  }

  whenPackageUpdated() { return this.state.packageUpdateInProgress || Promise.resolve(); }
  whenModuleUpdated() { return this.state.moduleUpdateInProgress || Promise.resolve(); }

  build() {
    var style = {borderWidth: 1, borderColor: Color.gray, fontSize: 14, fontFamily: "Helvetica Neue, Arial, sans-serif"},
        textStyle = {borderWidth: 1, borderColor: Color.gray, fontSize: 12, type: CodeEditor, mode: "javascript"},
        container = morph({
          ...style,
          layout: new GridLayout({
            grid: [["packageList", "moduleList"],
                   ["sourceEditor", "sourceEditor"]]}),
          submorphs: [
            {name: "packageList", type: "list", ...style},
            {name: "moduleList", type: "list", ...style},
            {name: "sourceEditor", ...textStyle, doSave() { this.owner.owner/*FIXME*/.save(); }}
          ]
        });
    // FIXME? how to specify that directly??
    container.layout.grid.row(0).adjustProportion(-1/5);
    container.get("sourceEditor").text.__defineGetter__("evalEnvironment", function () {
      var browser = this.getWindow();
      if (!browser.selectedModule) throw new Error("Browser has no module selected");
      return {
        targetModule: browser.selectedModule.name,
        context: this.doitContext || this.owner.doitContext || this
      }
    });
    return container;
  }

  get keybindings() {
    return [
      {keys: "Alt-Up", command: "focus list with selection"},
      {keys: "F1", command: "focus package list"},
      {keys: "F2", command: "focus module list"},
      {keys: "F3|Alt-Down", command: "focus source editor"},
      {keys: "Alt-R", command: "reload module"},
      {keys: "Alt-L", command: "load or add module"},
      {keys: "Ctrl-C Ctrl-T", command: "run all tests in module"},
      {keys: "Ctrl-C T", command: "run tests at point"},
    ].concat(super.keybindings);
  }

  get commands() { return commandsForBrowser(this); }

  reset() {
    connect(this.get("packageList"), "selection", this, "onPackageSelected");
    connect(this.get("moduleList"), 'selection', this, 'onModuleSelected');
    this.get("packageList").items = [];
    this.get("moduleList").items = [];
    this.get("sourceEditor").textString = ""
  }

  async systemInterface() {
    return (await System.import("lively-system-interface")).localInterface;
  }

  get selectedModule() {
    return this.get("moduleList").selection;
  }

  get selectedPackage() {
    return this.get("packageList").selection;
  }

  async packageResources(p) {
    // await this.packageResources(this.selectedPackage)
    return (await (await this.systemInterface()).resourcesOfPackage(p.address))
      .filter(({name}) => name.endsWith(".js") || name.endsWith(".json"));
  }

  async onLoad() {
    this.reset();
    this.get("packageList").items = (await (await this.systemInterface()).getPackages()).map(p => ({isListItem: true, string: p.name, value: p}));
  }

  async selectPackageNamed(pName) {
    var p = this.get("packageList").selection = this.get("packageList").values.find(({address, name}) => address === pName || name === pName);
    await this.whenPackageUpdated();
    return p;
  }

  async selectModuleNamed(mName) {
    var m = this.get("moduleList").selection = this.get("moduleList").values.find(({nameInPackage, name}) => mName === name || mName === nameInPackage);
    await this.whenModuleUpdated();
    return m;
  }

  async searchForModuleAndSelect(moduleURI) {
    // moduleURI = System.decanonicalize("lively.vm")
    // var x= await (that.getWindow().searchForModuleAndSelect(System.decanonicalize("lively.vm")));

    var {selectedModule, selectedPackage} = this;
    if (selectedModule && selectedModule.name === moduleURI)
      return selectedModule;

    var system = await this.systemInterface(),
        mods = await system.getModules(),
        m = mods.find(({name}) => name === moduleURI),
        p = m && await system.getPackageForModule(m.name);

    if (!p) return null;
    await this.selectPackageNamed(p.address);
    await this.selectModuleNamed(m.name);
    return this.selectedModule;
  }

  async onPackageSelected(p) {
    if (!this.state.packageUpdateInProgress) {
      var deferred = promise.deferred();
      this.state.packageUpdateInProgress = deferred.promise;
    }

    try {
      if (!p) {
        this.get("moduleList").items = [];
        this.get("sourceEditor").textString = "";
        this.title = "browser";
        return;
      }

      this.title = "browser – " + p.name;

      this.get("packageList").scrollSelectionIntoView();
      this.get("moduleList").selection = null;

      await this.updateModuleList(p);
    } finally {
      this.state.packageUpdateInProgress = null;
      deferred && deferred.resolve(p);
    }
  }

  async onModuleSelected(m) {

    var pack = this.get("packageList").selection;

    if (!m) {
      this.get("sourceEditor").textString = "";
      this.title = "browser – " + pack && pack.name || "";
      return;
    }

    if (!this.state.moduleUpdateInProgress) {
      var deferred = promise.deferred()
      this.state.moduleUpdateInProgress = deferred.promise;
    }

    try {
      var system = await this.systemInterface();

      if (!m.isLoaded && m.name.endsWith("js")) {
        var err;
        try {
          await System.import(m.name);
        } catch(e) { err = e; }

        if (err) this.world().logError(err);

        var p = await system.getPackage(pack.address),
            isLoadedNow = p.modules.map(ea => ea.name).includes(m.name);

        if (isLoadedNow) {
          Object.assign(pack, p);
          m.isLoaded = true;
          // await this.selectPackageNamed(pack.address);
          await this.updateModuleList();
          this.state.moduleUpdateInProgress = null;
          await this.selectModuleNamed(m.name);
          m = this.selectedModule;
          if (deferred)
            this.state.moduleUpdateInProgress = deferred.promise;
          return;
        }
      }

      this.get("moduleList").scrollSelectionIntoView();
      this.title = "browser – " + pack.name + "/" + m.nameInPackage;
      var source = await system.moduleRead(m.name);
      this.get("sourceEditor").textString = source;
      this.get("sourceEditor").text.cursorPosition = {row: 0, column: 0}
    } finally {
      this.state.moduleUpdateInProgress = null;
      deferred && deferred.resolve(m);
    }
  }

  async updateModuleList(p = this.selectedPackage) {
    if (!p) return;
    var mods = await this.packageResources(p);

    this.get("moduleList").items = mods
      .sort((a, b) => {
        if (a.isLoaded && !b.isLoaded) return -1;
        if (!a.isLoaded && b.isLoaded) return 1;
        if (a.nameInPackage.toLowerCase() < b.nameInPackage.toLowerCase()) return -1;
        if (a.nameInPackage.toLowerCase() == b.nameInPackage.toLowerCase()) return 0;
        return 1
      })
      .map(m => ({string: m.nameInPackage + (m.isLoaded ? "" : " [not loaded]"), value: m, isListItem: true}));

    await this.get("moduleList").whenRendered();
  }

  async save() {
    var module = this.get("moduleList").selection;
    if (!module) return show("Cannot save, no module selected");

    var content = this.get("sourceEditor").textString,
        system = await this.systemInterface();

    try {
      if (module.isLoaded) { // is loaded in runtime
        await system.interactivelyChangeModule(
          this, module.name, content,
          {targetModule: module.name, doEval: true});
      } else await system.moduleWrite(module.name, content);
    } catch(err) { return this.world().logError(err); }

    this.world().setStatusMessage("saved " + module.nameInPackage, Color.green);
  }

}<commit_msg>browser: fix update on save<commit_after>import { Color, pt, Rectangle } from "lively.graphics";
import { arr, promise } from "lively.lang";
import { connect, disconnect } from "lively.bindings";
import { Window, morph, show } from "../index.js";
import { GridLayout } from "../layout.js";
import CodeEditor from "./code-editor.js";

// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
// commands
// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

function commandsForBrowser(browser) {
  var pList = browser.get("packageList"),
      mList = browser.get("moduleList"),
      editor = browser.get("sourceEditor"),
      world = browser.world();

  return [
    {name: "focus list with selection", exec: () => focusList(mList.selection ? mList : pList)},
    {name: "focus package list", exec: () => focusList(pList)},
    {name: "focus module list", exec: () => focusList(mList)},
    {name: "focus source editor", exec: () => { editor.focus(); editor.show(); return true; }},

    {name: "reload module", exec: async () => {
      var m = browser.selectedModule;
      if (!m) return browser.world().inform("No module selected", {requester: browser});
      try {
        await (await browser.systemInterface()).interactivelyReloadModule(null, m.name);
      } catch(err) {
        browser.world().inform(`Error while reloading ${m.name}:\n${err.stack || err}`, {requester: browser});
        return true;
      }
      show(`Reloaded ${m.name}`);
      browser.selectModuleNamed(m.nameInPackage);
      return true;
    }},

    {name: "load or add module", exec: async (browser) => {
      var p = browser.selectedPackage;
      try {
        var mods = await (await browser.systemInterface()).interactivelyAddModule(null, p ? p.address : null, browser.world());
      } catch(e) {
        e === "Canceled" ?
          show(e) :
          browser.world().inform(`Error while trying to load modules:\n${e.stack || e}`, {requester: browser});
        return;
      }

      mods.forEach(({name, error}) =>
        error ? show(`Error while loading module ${name}: ${error.stack || error}`) :
                show(`Module ${name} loaded`))
      await browser.updateModuleList(p);
      mods.length && browser.selectModuleNamed(mods[0].name);
      return true;
    }},

    {name: "run all tests in module",
     exec: (browser) => {
       var m = browser.selectedModule;
        if (!m) return browser.world().inform("No module selected", {requester: browser});
       return runTestsInModule(browser, m.name, null);
     }},

    {name: "run tests at point",
     exec: async (browser) => {
       var m = browser.selectedModule;
        if (!m) return browser.world().inform("No module selected", {requester: browser});

        var {parse, query: {nodesAt}} = await System.import("lively.ast");
        var ed = browser.get("sourceEditor").text;
        var source = ed.textString;
        var parsed = parse(source);
        var nodes = nodesAt(ed.document.positionToIndex(ed.cursorPosition), parsed)
          .filter(n => n.type === "CallExpression" && n.callee.name && n.callee.name.match(/describe|it/) && n.arguments[0].type === "Literal")
            .map(n => ({
              type: n.callee.name.match(/describe/) ? "suite" : "test",
              title: n.arguments[0].value,
          }))

        if (!nodes.length)
          return browser.world().inform("No test at " + JSON.stringify(ed.cursorPosition), {requester: browser});

       var spec = {fullTitle: arr.pluck(nodes, "title").join(" "), type: arr.last(nodes).type, file: m.name}
       return runTestsInModule(browser, m.name, spec);
     }}
  ]

  function focusList(list) {
    list.scrollSelectionIntoView();
    list.update();
    list.show();
    list.focus();
    return list
  }

  function runTestsInModule(browser, moduleName, spec) {
    var runner = browser.get("test runner window");
    if (!runner)
      runner = world.execCommand("open test runner");
    if (runner.minimized)
      runner.toggleMinimize();
    return spec ?
      runner.targetMorph[spec.type === "suite" ? "runSuite" : "runTest"](spec.fullTitle):
      runner.targetMorph.runTestFile(moduleName);
  }

}

// -=-=-=-=-=-
// Browser UI
// -=-=-=-=-=-

export class Browser extends Window {

  static async browse(packageName, moduleName, textPosition = {row: 0, column: 0}, browserOrProps = {}) {
    var browser = browserOrProps instanceof Browser ? browserOrProps : new this(browserOrProps);
    if (!browser.world())
      browser.openInWorldNearHand();
    await browser.whenRendered();
    if (packageName) await browser.selectPackageNamed(packageName);
    if (packageName && moduleName) await browser.selectModuleNamed(moduleName);
    if (textPosition) {
      var text = browser.get("sourceEditor").text;
      text.cursorPosition = textPosition;
      text.centerRow(textPosition.row);
    }
    return browser;
  }

  constructor(props = {}) {
    super({
      name: "browser",
      extent: pt(700,600),
      ...props,
      targetMorph: this.build()
    });
    this.state = {packageUpdateInProgress: null, moduleUpdateInProgress: null};
    this.onLoad();
  }

  get isBrowser() { return true; }

  focus() {
    this.get("sourceEditor").focus();
  }

  whenPackageUpdated() { return this.state.packageUpdateInProgress || Promise.resolve(); }
  whenModuleUpdated() { return this.state.moduleUpdateInProgress || Promise.resolve(); }

  build() {
    var style = {borderWidth: 1, borderColor: Color.gray, fontSize: 14, fontFamily: "Helvetica Neue, Arial, sans-serif"},
        textStyle = {borderWidth: 1, borderColor: Color.gray, fontSize: 12, type: CodeEditor, mode: "javascript"},
        container = morph({
          ...style,
          layout: new GridLayout({
            grid: [["packageList", "moduleList"],
                   ["sourceEditor", "sourceEditor"]]}),
          submorphs: [
            {name: "packageList", type: "list", ...style},
            {name: "moduleList", type: "list", ...style},
            {name: "sourceEditor", ...textStyle, doSave() { this.owner.owner/*FIXME*/.save(); }}
          ]
        });
    // FIXME? how to specify that directly??
    container.layout.grid.row(0).adjustProportion(-1/5);
    container.get("sourceEditor").text.__defineGetter__("evalEnvironment", function () {
      var browser = this.getWindow();
      if (!browser.selectedModule) throw new Error("Browser has no module selected");
      return {
        targetModule: browser.selectedModule.name,
        context: this.doitContext || this.owner.doitContext || this
      }
    });
    return container;
  }

  get keybindings() {
    return [
      {keys: "Alt-Up", command: "focus list with selection"},
      {keys: "F1", command: "focus package list"},
      {keys: "F2", command: "focus module list"},
      {keys: "F3|Alt-Down", command: "focus source editor"},
      {keys: "Alt-R", command: "reload module"},
      {keys: "Alt-L", command: "load or add module"},
      {keys: "Ctrl-C Ctrl-T", command: "run all tests in module"},
      {keys: "Ctrl-C T", command: "run tests at point"},
    ].concat(super.keybindings);
  }

  get commands() { return commandsForBrowser(this); }

  reset() {
    connect(this.get("packageList"), "selection", this, "onPackageSelected");
    connect(this.get("moduleList"), 'selection', this, 'onModuleSelected');
    this.get("packageList").items = [];
    this.get("moduleList").items = [];
    this.get("sourceEditor").textString = ""
  }

  async systemInterface() {
    return (await System.import("lively-system-interface")).localInterface;
  }

  get selectedModule() {
    return this.get("moduleList").selection;
  }

  get selectedPackage() {
    return this.get("packageList").selection;
  }

  async packageResources(p) {
    // await this.packageResources(this.selectedPackage)
    return (await (await this.systemInterface()).resourcesOfPackage(p.address))
      .filter(({name}) => name.endsWith(".js") || name.endsWith(".json"));
  }

  async onLoad() {
    this.reset();
    this.get("packageList").items = (await (await this.systemInterface()).getPackages()).map(p => ({isListItem: true, string: p.name, value: p}));
  }

  async selectPackageNamed(pName) {
    var p = this.get("packageList").selection = this.get("packageList").values.find(({address, name}) => address === pName || name === pName);
    await this.whenPackageUpdated();
    return p;
  }

  async selectModuleNamed(mName) {
    var m = this.get("moduleList").selection = this.get("moduleList").values.find(({nameInPackage, name}) => mName === name || mName === nameInPackage);
    await this.whenModuleUpdated();
    return m;
  }

  async searchForModuleAndSelect(moduleURI) {
    // moduleURI = System.decanonicalize("lively.vm")
    // var x= await (that.getWindow().searchForModuleAndSelect(System.decanonicalize("lively.vm")));

    var {selectedModule, selectedPackage} = this;
    if (selectedModule && selectedModule.name === moduleURI)
      return selectedModule;

    var system = await this.systemInterface(),
        mods = await system.getModules(),
        m = mods.find(({name}) => name === moduleURI),
        p = m && await system.getPackageForModule(m.name);

    if (!p) return null;
    await this.selectPackageNamed(p.address);
    await this.selectModuleNamed(m.name);
    return this.selectedModule;
  }

  async onPackageSelected(p) {
    if (!this.state.packageUpdateInProgress) {
      var deferred = promise.deferred();
      this.state.packageUpdateInProgress = deferred.promise;
    }

    try {
      if (!p) {
        this.get("moduleList").items = [];
        this.get("sourceEditor").textString = "";
        this.title = "browser";
        return;
      }

      this.title = "browser – " + p.name;

      this.get("packageList").scrollSelectionIntoView();
      this.get("moduleList").selection = null;

      await this.updateModuleList(p);
    } finally {
      this.state.packageUpdateInProgress = null;
      deferred && deferred.resolve(p);
    }
  }

  async onModuleSelected(m) {

    var pack = this.get("packageList").selection;

    if (!m) {
      this.get("sourceEditor").textString = "";
      this.title = "browser – " + pack && pack.name || "";
      return;
    }

    if (!this.state.moduleUpdateInProgress) {
      var deferred = promise.deferred()
      this.state.moduleUpdateInProgress = deferred.promise;
    }

    try {
      var system = await this.systemInterface();

      if (!m.isLoaded && m.name.endsWith("js")) {
        var err;
        try {
          await System.import(m.name);
        } catch(e) { err = e; }

        if (err) this.world().logError(err);

        var p = await system.getPackage(pack.address),
            isLoadedNow = p.modules.map(ea => ea.name).includes(m.name);

        if (isLoadedNow) {
          Object.assign(pack, p);
          m.isLoaded = true;
          // await this.selectPackageNamed(pack.address);
          await this.updateModuleList();
          this.state.moduleUpdateInProgress = null;
          await this.selectModuleNamed(m.name);
          m = this.selectedModule;
          if (deferred)
            this.state.moduleUpdateInProgress = deferred.promise;
          return;
        }
      }

      this.get("moduleList").scrollSelectionIntoView();
      this.title = "browser – " + pack.name + "/" + m.nameInPackage;
      var source = await system.moduleRead(m.name);
      this.get("sourceEditor").textString = source;
      this.get("sourceEditor").text.cursorPosition = {row: 0, column: 0}
    } finally {
      this.state.moduleUpdateInProgress = null;
      deferred && deferred.resolve(m);
    }
  }

  async updateModuleList(p = this.selectedPackage) {
    if (!p) return;
    var mods = await this.packageResources(p);

    this.get("moduleList").items = mods
      .sort((a, b) => {
        if (a.isLoaded && !b.isLoaded) return -1;
        if (!a.isLoaded && b.isLoaded) return 1;
        if (a.nameInPackage.toLowerCase() < b.nameInPackage.toLowerCase()) return -1;
        if (a.nameInPackage.toLowerCase() == b.nameInPackage.toLowerCase()) return 0;
        return 1
      })
      .map(m => ({string: m.nameInPackage + (m.isLoaded ? "" : " [not loaded]"), value: m, isListItem: true}));

    await this.get("moduleList").whenRendered();
  }

  async save() {
    var module = this.get("moduleList").selection;
    if (!module) return show("Cannot save, no module selected");

    var content = this.get("sourceEditor").textString,
        system = await this.systemInterface();

    try {
      if (module.isLoaded) { // is loaded in runtime
        await system.interactivelyChangeModule(
          null, module.name, content,
          {targetModule: module.name, doEval: true});
      } else await system.moduleWrite(module.name, content);
    } catch(err) { return this.world().logError(err); }

    this.world().setStatusMessage("saved " + module.nameInPackage, Color.green);
  }

}<|endoftext|>


<commit_before>/**
骨骼model的类
@module
**/
define([
    'Backbone.Relational', 'relationalScope',
    'modelUtil', 'model.keyframe', 'collection.keyframe', 'collection.Bone'
], function(
    Backbone, relationalScope,
    util
){
    var BoneModel;

    /**
    @class BoneModel
    @extends Backbone.RelationalModel
    **/
    BoneModel = Backbone.RelationalModel.extend({
        /**
        Start: backbone内置属性/方法
        **/
        defaults: {
            // 骨骼的名字
            name: 'unknown',
            // 纹理图的url
            texture: 'img/defaultTexture.gif',
            // 纹理图相对于骨骼容器的位置
            textureX: 0,
            textureY: 0,
            // 纹理图的宽高
            textureWidth: 'auto',
            textureHeight: 'auto'
        },
        relations: [{
            // 有多个关键帧，组成一个关键帧集合
            type: 'HasMany',
            key: 'keyframes',
            relatedModel: 'KeyframeModel',
            collectionType: 'KeyframeCollection',
            reverseRelation: {
                // 一个关键帧集合对应一个骨骼
                key: 'bone'
            }
        }, {
            // 有多个子骨骼
            type: 'HasMany',
            key: 'children',
            relatedModel: 'BoneModel',
            collectionType: 'BoneCollection'
        }],
        initialize: function(){
            var id;

            id = util.createId();
            console.debug('Create a bone model with id %s', id);
            this.set('id', id);
        },
        fetch: function(){},
        save: function(){},
        /**
        End: backbone内置属性/方法
        **/

        /**
        判断是否含有子骨骼，或是否含有某个指定的子骨骼
        @method hasChild
        @param {String} [id] 子骨骼id
        @return {Boolean}
        @example
            bodyBoneModel.hasChild() 是否有子骨骼
            bodyBoneModel.hasChild(headBoneModel.get('id')) 是否有某个子骨骼
        **/
        hasChild: function(id){
            var childBoneColl;

            if( (childBoneColl = this.get('children')).length ){
                if(id) return !!childBoneColl.get(id);
                else return true;
            }
            else{
                return false;
            }
        }
    });

    relationalScope.BoneModel = BoneModel;

    return BoneModel;
});
<commit_msg>Bone model support 'toJSON()' with two options: specifying time; whether mixin keyframe data into bone data<commit_after>/**
骨骼model的类
@module
**/
define([
    'underscore', 'Backbone.Relational', 'relationalScope',
    'modelUtil', 'model.keyframe', 'collection.keyframe', 'collection.Bone'
], function(
    _, Backbone, relationalScope,
    util
){
    var findWhere = _.findWhere,
        extend = _.extend,
        BoneModel;

    /**
    @class BoneModel
    @extends Backbone.RelationalModel
    **/
    BoneModel = Backbone.RelationalModel.extend({
        /**
        Start: backbone内置属性/方法
        **/
        defaults: {
            // 骨骼的名字
            name: 'unknown',
            // 纹理图的url
            texture: 'img/defaultTexture.gif',
            // 纹理图相对于骨骼容器的位置
            textureX: 0,
            textureY: 0,
            // 纹理图的宽高
            textureWidth: 'auto',
            textureHeight: 'auto'
        },
        relations: [{
            // 有多个关键帧，组成一个关键帧集合
            type: 'HasMany',
            key: 'keyframes',
            relatedModel: 'KeyframeModel',
            collectionType: 'KeyframeCollection',
            reverseRelation: {
                // 一个关键帧集合对应一个骨骼
                key: 'bone'
            }
        }, {
            // 有多个子骨骼
            type: 'HasMany',
            key: 'children',
            relatedModel: 'BoneModel',
            collectionType: 'BoneCollection'
        }],
        initialize: function(){
            var id;

            id = util.createId();
            console.debug('Create a bone model with id %s', id);
            this.set('id', id);
        },
        /**
        @param {Object} [options]
            @param {Number} [options.time] 只获取指定时间点的数据
            @param {Boolean} [options.mixin=true] 是否将关键帧的数据混入到骨骼数据中。只有当设置了 `options.time` 时才有效
        **/
        toJSON: function(options){
            var keyframeData,
                json;

            options = options || {};

            json = this.constructor.__super__.toJSON.call(this, options);
            if('time' in options){
                keyframeData = findWhere(json.keyframes, {time: options.time});
                if(keyframeData){
                    delete json.keyframes;
                    delete keyframeData.id;
                    delete keyframeData.bone;
                    extend(json, keyframeData);
                }
                else{
                    // TODO: 支持获取关键帧范围内某个时间点的数据，即指定的时间点不一定是关键帧所在的时间点
                    throw new Error('No keyframe at specified time');
                }
            }

            return json;
        },
        fetch: function(){},
        save: function(){},
        /**
        End: backbone内置属性/方法
        **/

        /**
        判断是否含有子骨骼，或是否含有某个指定的子骨骼
        @method hasChild
        @param {String} [id] 子骨骼id
        @return {Boolean}
        @example
            bodyBoneModel.hasChild() 是否有子骨骼
            bodyBoneModel.hasChild(headBoneModel.get('id')) 是否有某个子骨骼
        **/
        hasChild: function(id){
            var childBoneColl;

            if( (childBoneColl = this.get('children')).length ){
                if(id) return !!childBoneColl.get(id);
                else return true;
            }
            else{
                return false;
            }
        }
    });

    relationalScope.BoneModel = BoneModel;

    return BoneModel;
});
<|endoftext|>


<commit_before>const { graphql: { types } } = require('koapi')
const models = require('../../../../models')
const { Post } = require('../types')

const SearchType = new types.Enum({
  name: 'SearchType',
  values: {
    POST: { value: models.Post }
  }
})
const Searchable = new types.Union({
  name: 'Searchable',
  types: [ Post ],
  resolveType: model => {
    if (model instanceof models.Post) {
      return Post
    }
  }
})

module.exports = {
  type: types.connection.define(Searchable),
  args: types.connection.args({
    type: types.nonNull(SearchType)()
  }),
  resolve: types.connection.resolve(async (root, {first, after, type}, ctx) => {
    const result = await type.forge().fetchPage({ limit: first, offset: after })
    return {
      totalCount: result.pagination.rowCount,
      edges: result.models.map((node, index) => ({node, cursor: after + index})),
      pageInfo: {
        startCursor: after,
        endCursor: after + first,
        hasNextPage: after < result.pagination.rowCount - first
      }
    }
  })
}
<commit_msg>improve<commit_after>const { graphql: { types } } = require('koapi')
const models = require('../../../../models')
const { Post } = require('../types')

const SearchType = new types.Enum({
  name: 'SearchType',
  values: {
    POST: {
      value: ({first, after}) => models.Post.forge().fetchPage({limit: first, offset: after})
    }
  }
})

const SearchableItem = new types.Union({
  name: 'SearchableItem',
  types: [ Post ],
  resolveType: model => {
    if (model instanceof models.Post) {
      return Post
    }
  }
})

module.exports = {
  type: types.connection.define(SearchableItem),
  args: types.connection.args({
    type: types.nonNull(SearchType)()
  }),
  resolve: types.connection.resolve(async (root, {type, first, after}, ctx) => {
    const result = await type({first, after})
    return {
      totalCount: result.pagination.rowCount,
      edges: result.models.map((node, index) => ({node, cursor: after + index})),
      pageInfo: {
        startCursor: after,
        endCursor: after + first,
        hasNextPage: after < result.pagination.rowCount - first
      }
    }
  })
}
<|endoftext|>


<commit_before>const menuItems = Object.freeze({
  'primary receptions': 'Первичные приёмы',
  'laboratory': 'Лабораторные',
  'paraclinical': 'Параклинические',
  'consultation': 'Консультации',
  'diaries': 'Дневники',
  'vc': 'Врачебная комиссия',
  'operation': 'Операции',
  'bl': 'Больничные листы',
  'physiotherapy': 'Физиотерапия',
  'pharmacotherapy': 'Фармакотерапия',
  't, ad, p sheet': 't, ad, p – листы',
  'epicrisis': 'Эпикризы',
  'extracts': 'Выписки',
  'all': 'Показать всё',
});

export default {
  data() {
    return {
      menuItems,
      menuNeedPlus: {
        'primary receptions': true,
        laboratory: true,
        paraclinical: true,
        consultation: true,
        diaries: true,
        vc: true,
        operation: true,
        bl: true,
        physiotherapy: true,
        pharmacotherapy: true,
        't, ad, p sheet': true,
        epicrisis: true,
        extracts: true,
      },
      plusDirectionsMode: {
        laboratory: true,
        paraclinical: true,
        consultation: true,
      },
      allowedOnlyOneEntry: {
        'primary receptions': true,
      }
    }
  }
}
<commit_msg>To allowedOnlyOneEntry: extracts<commit_after>const menuItems = Object.freeze({
  'primary receptions': 'Первичные приёмы',
  'laboratory': 'Лабораторные',
  'paraclinical': 'Параклинические',
  'consultation': 'Консультации',
  'diaries': 'Дневники',
  'vc': 'Врачебная комиссия',
  'operation': 'Операции',
  'bl': 'Больничные листы',
  'physiotherapy': 'Физиотерапия',
  'pharmacotherapy': 'Фармакотерапия',
  't, ad, p sheet': 't, ad, p – листы',
  'epicrisis': 'Эпикризы',
  'extracts': 'Выписки',
  'all': 'Показать всё',
});

export default {
  data() {
    return {
      menuItems,
      menuNeedPlus: {
        'primary receptions': true,
        laboratory: true,
        paraclinical: true,
        consultation: true,
        diaries: true,
        vc: true,
        operation: true,
        bl: true,
        physiotherapy: true,
        pharmacotherapy: true,
        't, ad, p sheet': true,
        epicrisis: true,
        extracts: true,
      },
      plusDirectionsMode: {
        laboratory: true,
        paraclinical: true,
        consultation: true,
      },
      allowedOnlyOneEntry: {
        'primary receptions': true,
        extracts: true,
      }
    }
  }
}
<|endoftext|>


<commit_before>var AST = {}

AST.InstrumentDefinition = function(time, number, unit_generators) {
    this.time = time;
    this.number = number;
    this.unit_generators = unit_generators;
};

AST.Oscillator = function(amplitude, frequency, output, stored_function, initial_value) {
    this.amplitude = amplitude;
    this.frequency = frequency;
    this.output = output;
    this.stored_function = stored_function;
    this.initial_value = initial_value;
};

AST.Output = function(input, output) {
    this.input = input;
    this.output = output;
};

AST.GeneratedFunction = function(time, subroutine_number, function_number, points) {
    this.time = time;
    this.subroutine_number = subroutine_number;
    this.function_number = function_number;
    this.points = points;
};

AST.Note = function(time, instrument_number, duration, params) {
    this.time = time;
    this.instrument_number = instrument_number;
    this.duration = duration;
    this.params = params;

    this.add_to_score = function(score) {
        score.notes.push(new Model.Note(time, duration));
    }
};

AST.Terminator = function(time) {
    this.time = time;

    this.add_to_score = function(score) {
        score.duration = this.time;
    }
};

AST.Score = function(data_statements) {
    this.data_statements = data_statements;

    this.to_score = function() {
        var score = new Model.Score();
        data_statements.forEach(function(statement) {
            if(statement.add_to_score) { statement.add_to_score(score) };
        });
        return score;
    };
};

var Model = {};
Model.Note = function(time, duration) {
    this.start = time;
    this.end = this.start + duration;
};

Model.Score = function() {
    this.notes = [];

    this.play = function(context) {
        var buffer = context.createBuffer(1, this.duration * context.sampleRate, context.sampleRate);
        var data = buffer.getChannelData(0);

        this.notes.forEach(function(note) {
            var start = note.start * context.sampleRate;
            var end = note.end * context.sampleRate;

            for (var i = start; i < end; i++) {
                data[i] = Math.random() * 2 - 1;
            }
        });

        var source = context.createBufferSource();
        source.buffer = buffer;
        source.connect(context.destination);
        source.start();
    };
};

var score_source = document.getElementById('score').value
var grammar = document.getElementById('grammar').value

var parser = PEG.buildParser(grammar);
var ast = parser.parse(score_source);
console.log(ast);

var score = ast.to_score();
console.log(score);

var context = new AudioContext();
score.play(context);
<commit_msg>move play method on to prototype<commit_after>var AST = {}

AST.InstrumentDefinition = function(time, number, unit_generators) {
    this.time = time;
    this.number = number;
    this.unit_generators = unit_generators;
};

AST.Oscillator = function(amplitude, frequency, output, stored_function, initial_value) {
    this.amplitude = amplitude;
    this.frequency = frequency;
    this.output = output;
    this.stored_function = stored_function;
    this.initial_value = initial_value;
};

AST.Output = function(input, output) {
    this.input = input;
    this.output = output;
};

AST.GeneratedFunction = function(time, subroutine_number, function_number, points) {
    this.time = time;
    this.subroutine_number = subroutine_number;
    this.function_number = function_number;
    this.points = points;
};

AST.Note = function(time, instrument_number, duration, params) {
    this.time = time;
    this.instrument_number = instrument_number;
    this.duration = duration;
    this.params = params;

    this.add_to_score = function(score) {
        score.notes.push(new Model.Note(time, duration));
    }
};

AST.Terminator = function(time) {
    this.time = time;

    this.add_to_score = function(score) {
        score.duration = this.time;
    }
};

AST.Score = function(data_statements) {
    this.data_statements = data_statements;

    this.to_score = function() {
        var score = new Model.Score();
        data_statements.forEach(function(statement) {
            if(statement.add_to_score) { statement.add_to_score(score) };
        });
        return score;
    };
};

var Model = {};
Model.Note = function(time, duration) {
    this.start = time;
    this.end = this.start + duration;
};

Model.Score = function() {
    this.notes = [];
};

Model.Score.prototype.play = function(context) {
    var buffer = context.createBuffer(1, this.duration * context.sampleRate, context.sampleRate);
    var data = buffer.getChannelData(0);

    this.notes.forEach(function(note) {
        var start = note.start * context.sampleRate;
        var end = note.end * context.sampleRate;

        for (var i = start; i < end; i++) {
            data[i] = Math.random() * 2 - 1;
        }
    });

    var source = context.createBufferSource();
    source.buffer = buffer;
    source.connect(context.destination);
    source.start();
};

var score_source = document.getElementById('score').value
var grammar = document.getElementById('grammar').value

var parser = PEG.buildParser(grammar);
var ast = parser.parse(score_source);
console.log(ast);

var score = ast.to_score();
console.log(score);

var context = new AudioContext();
score.play(context);
<|endoftext|>