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

CLASS({
  package: 'foam.build',
  name: 'BuildApp',

  imports: [
    'log',
    'error'
  ],
  requires: [
    'foam.dao.NodeFileDAO as FileDAO',
    'foam.dao.File',
    'foam.core.dao.OrDAO',
    'node.dao.ModelFileDAO',
    'foam.build.WebApplication'
  ],
  properties: [
    {
      name: 'appDefinition'
    },
    {
      name: 'controller',
      help: 'Name of the main controller/model to create',
    },
    {
      model_: 'StringArrayProperty',
      name: 'coreFiles',
      adapt: function(_, s) { if ( typeof s === 'string' ) return s.split(','); return s; }
    },
    {
      name: 'defaultView',
      help: "Default view of the controller to use.  If not set, the controller will be used as view (if it is one), or DetailView will be used"
    },
    {
      name: 'targetPath',
      help: "Directory to write output files to.  Will be created if it doesn't exist.",
      required: true
    },
    {
      model_: 'BooleanProperty',
      name: 'precompileTemplates',
      help: 'True to precompile templates of models loaded from the ModelDAO.',
      defaultValue: false
    },
    {
      model_: 'BooleanProperty',
      name: 'includeFoamCSS',
      defaultValue: false
    },
    {
      model_: 'StringProperty',
      name: 'icon'
    },
    {
      model_: 'StringProperty',
      name: 'version'
    },
    {
      model_: 'StringArrayProperty',
      name: 'resources'
    },
    {
      model_: 'BooleanProperty',
      name: 'appcacheManifest',
      defaultValue: false
    },
    {
      model_: 'StringArrayProperty',
      name: 'extraFiles',
      help: 'Extra files to both load during the build process, and include in the built image.',
      adapt: function(_, s) { if ( typeof s === 'string' ) return s.split(','); return s; }
    },
    {
      model_: 'StringArrayProperty',
      name: 'extraModels',
      help: 'Extra models to include in the image regardless of if they were arequired or not.',
      adapt: function(_, s) { if ( typeof s === 'string' ) return s.split(','); return s; },
      factory: function() { return ['foam.ui.FoamTagView']; }
    },
    {
      model_: 'StringArrayProperty',
      name: 'blacklistModels',
      help: 'Models to unconditionally exclude from the image, even if they are listed as required.',
      adapt: function(_, s) { if ( typeof s === 'string' ) return s.split(','); return s; }
    },
    {
      model_: 'BooleanProperty',
      name: 'outputManifest',
      defaultValue: false,
      help: 'Set to true to write out a MANIFEST file listing all included models.'
    },
    {
      name: 'htmlFileName',
      help: 'Name of the main html file to produce.',
      defaultValue: 'main.html'
    },
    {
      model_: 'StringArrayProperty',
      name: 'htmlHeaders'
    },
    {
      name: 'formatter',
      factory: function() {
        return {
          __proto__: JSONUtil.compact,
          keys_: {},
          keyify: JSONUtil.prettyModel.keyify,
          outputObject_: function(out, obj, opt_defaultModel) {
            var first = true;

            out('{');
            if ( obj.model_.id !== opt_defaultModel ) {
              this.outputModel_(out, obj);
              first = false;
            }

            if ( Template.isInstance(obj) ) var isTemplate = true;

            for ( var key in obj.model_.properties_ ) {
              var prop = obj.model_.properties_[key];

              if ( ! this.p(prop) && ( ! isTemplate || prop.name !== 'code' ) ) continue;

              if ( prop.name === 'documentation' ) continue;

              if ( prop.name in obj.instance_ ) {
                var val = obj[prop.name];
                if ( Array.isArray(val) && ! val.length ) continue;
                if ( ! first ) out(',');
                out(this.keyify(prop.name), ': ');

                if ( prop.name === 'methods' ) {
                  out('{');
                  var ff = true;
                  for ( var i = 0 ; i < val.length ; i++ ) {
                    if ( ! ff ) out(',');

                    out(this.keyify(val[i].name), ': ');
                    out(val[i].code);
                    ff = false;
                  }
                  out('}');
                } else {
                  this.output(out, val);
                }
                first = false;
              }
            }

            out('}');
          }
        };
      }
    },
    {
      name: 'path',
      factory: function() { return require('path'); }
    },
    {
      name: 'fileDAO',
      factory: function() { return this.FileDAO.create(); }
    },
    {
      model_: 'StringArrayProperty',
      name: 'extraClassPaths',
      help: 'List of extra .js hierarchies to load models from.  Paths will be checked in the order given, finally falling back to the main FOAM js/ hierarchy.',
      adapt: function(_, s) { if ( typeof s === 'string' ) return s.split(','); return s; }
    },
    {
      model_: 'StringProperty',
      name: 'delegate'
    }
  ],
  methods: {
    execute: function() {
      for ( var i = 0; i < this.extraClassPaths.length ; i++ ) {
        this.X.ModelDAO = this.OrDAO.create({
          delegate: this.ModelFileDAO.create({
            classpath: this.extraClassPaths[i]
          }),
          primary: this.X.ModelDAO
        });
      }

      if ( this.appDefinition ) {
        this.X.ModelDAO.find(this.appDefinition, {
          put: function(d) {
            this.copyFrom(d);
            this.execute_();
          }.bind(this),
          error: function() {
            console.log("App definition failed");
            this.execute_();
          }.bind(this)
        });
      } else {
        this.execute_();
      }
    },
    execute_: function() {
      if ( this.delegate ) {
        arequire(this.delegate)(function(delegate) { delegate.buildApp(); });
      } else {
        this.buildApp();
      }
    },
    buildApp: function() {
      if ( ! this.targetPath ) {
        this.error("targetPath is required");
        process.exit(1);
      }
      if ( ! this.controller ) {
        this.error("controller is required");
        process.exit(1);
      }

      for ( var i = 0 ; i < this.extraFiles.length ; i++ ) {
        require(FOAM_BOOT_DIR + this.path.sep + this.extraFiles[i] + '.js');
      }

      var view = this.defaultView ? arequire(this.defaultView) : anop;

      var seq = [view];
      for ( var i = 0; i < this.extraModels.length ; i++ ) {
        seq.push(arequire(this.extraModels[i]));
      }

      aseq(
        aseq.apply(null, seq),
        arequire(this.controller))(this.buildModel.bind(this));
    },
    buildCoreJS_: function(ret) {
      var i = 0;
      var self = this;
      var corejs = '';
      var file;
      if ( this.coreFiles.length ) var myfiles = this.coreFiles;
      else myfiles = files;
      myfiles = myfiles.concat(this.extraFiles);
      awhile(
        function() { return i < myfiles.length; },
        aif(
          function() {
            file = myfiles[i++];
            if ( Array.isArray(file) ) {
              if ( file[1] == IN_NODEJS )
                return false;
              file = file[0];
            }
            return true;
          },
          aseq(
            function(ret) {
              var path = FOAM_BOOT_DIR + this.path.sep + file + '.js';
              this.fileDAO.find(path, {
                put: ret,
                error: function() {
                  self.error.apply(["Error reading file: ", path].concat(arguments));
                }
              });
            }.bind(this),
            function(ret, file) {
              corejs += '\n';
              corejs += file.contents;
              ret();
            })))(function() { ret(corejs); });
    },
    buildAppJS_: function(ret) {
      var models = {};
      var visited = {};
      var error = this.error;
      var self = this;

      function add(require) {
        if ( visited[require] ) return;
        visited[require] = true;

        var model = X.lookup(require);
        if ( ! model ) {
          error("Could not load model: ", require);
        }
        if ( model.package &&
             self.blacklistModels.indexOf(model.id) == -1 ) {
          models[model.id] = model;
        }

        model.getAllRequires().forEach(add);
      };
      add(this.controller);
      if ( this.defaultView ) add(this.defaultView);

      for ( var i = 0; i < this.extraModels.length ; i++ ) {
        add(this.extraModels[i]);
      }

      var contents = '';

      var ids = Object.keys(models);
      if ( this.outputManifest ) {
        this.fileDAO.put(this.File.create({
          path: this.targetPath + this.path.sep + 'MANIFEST',
          contents: ids.join('\n')
        }));
      }

      for ( var i = 0; i < ids.length; i++ ) {
        var model = models[ids[i]];
        if ( this.precompileTemplates ) {
          for ( var j = 0 ; j < model.templates.length ; j++ ) {
            var t = model.templates[j];
            // It's safe to remove leading and trailing whitespace from CSS.
            if ( t.name === 'CSS' ) t.template = t.template.split('\n').map(function(s) { return s.trim(); }).join('\n');
            t.code = TemplateUtil.compile(t);
            t.clearProperty('template');
          }
        }
        contents += 'CLASS(';
        var formatter = this.precompileTemplates ? this.formatter : JSONUtil.compact;
        contents += formatter.where(NOT_TRANSIENT).stringifyObject(models[ids[i]], 'Model');
        contents += ')\n';
      }

      ret(contents);
    },
    buildModel: function(model) {
      if ( ! model ) {
        this.error('Could not find model: ', this.controller);
      }
      this.log('Building   ', model.id);
      this.log('Target is: ', this.targetPath);
      this.log(this.precompileTemplates ? '' : 'NOT ', 'pre-compiling templates.');

      var self = this;
      aseq(
        function(ret) {
          var file = this.File.create({
            path: this.targetPath + this.path.sep + this.htmlFileName,
            contents: this.HTML()
          });

          console.log('Writing: ', file.path);
          this.fileDAO.put(file, {
            put: ret,
            error: function() {
              self.error('ERROR writing file: ', file.path);
              process.exit(1);
            }
          });
        }.bind(this),
        aif(this.appcacheManifest,
            function(ret) {
              var file = this.File.create({
                path: this.targetPath + this.path.sep + "app.manifest",
                contents: this.MANIFEST()
              });
              console.log('Writing: ', file.path);
              this.fileDAO.put(file, {
                put: ret,
                error: function() {
                  this.error("ERROR writing file: ", file.path);
                  process.exit(1);
                }
              });
            }.bind(this)),
        apar(
          function(ret) { this.buildCoreJS_(ret); }.bind(this),
          function(ret) { this.buildAppJS_(ret); }.bind(this)),
        function(ret, corejs, appjs) {
          var file = this.File.create({
            path: this.targetPath + this.path.sep + 'foam.js',
            contents: corejs + appjs
          });
          console.log('Writing: ', file.path);
          this.fileDAO.put(file, {
            put: ret,
            error: function() {
              self.error('ERROR writing file: ', file.path);
              process.exit(1);
            }
          });
        }.bind(this)
      )(
        function(){
          process.exit(0);
        });
    }
  },
  templates: [
    function HTML() {/*<html<% if ( this.appcacheManifest ) { %> manifest="app.manifest"<% } %>><meta charset="utf-8"><%= this.htmlHeaders.join('') %><% if ( this.includeFoamCSS ) { %><link rel="stylesheet" type="text/css" href="foam.css"/><% } %><% if ( this.icon ) { %><link rel="icon" sizes="128x128" href="<%= this.icon %>"/><% } %><foam model="<%= this.controller %>"<% if ( this.defaultView ) { %> view="<%= this.defaultView %>"<% } %>></foam>*/},
    function MANIFEST() {/*CACHE MANIFEST
# version <%= this.version %>
<% if ( this.appDefinition ) { %># hash: <%= this.appDefinition.hashCode() %><% } %>

CACHE:
foam.js
<%= this.htmlFileName %>
<% if ( this.includeFoamCSS ) { %>foam.css<% } %>
<% for ( var i = 0 ; i < this.resources.length ; i++ ) { %><%= this.resources[i] %>
<% } %>

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

CLASS({
  package: 'foam.build',
  name: 'BuildApp',

  imports: [
    'log',
    'error'
  ],
  requires: [
    'foam.dao.NodeFileDAO as FileDAO',
    'foam.dao.File',
    'foam.core.dao.OrDAO',
    'node.dao.ModelFileDAO',
    'foam.build.WebApplication'
  ],
  properties: [
    {
      name: 'appDefinition'
    },
    {
      name: 'controller',
      help: 'Name of the main controller/model to create',
    },
    {
      model_: 'StringArrayProperty',
      name: 'coreFiles',
      adapt: function(_, s) { if ( typeof s === 'string' ) return s.split(','); return s; }
    },
    {
      name: 'defaultView',
      help: "Default view of the controller to use.  If not set, the controller will be used as view (if it is one), or DetailView will be used"
    },
    {
      name: 'targetPath',
      help: "Directory to write output files to.  Will be created if it doesn't exist.",
      required: true
    },
    {
      model_: 'BooleanProperty',
      name: 'precompileTemplates',
      help: 'True to precompile templates of models loaded from the ModelDAO.',
      defaultValue: false
    },
    {
      model_: 'BooleanProperty',
      name: 'includeFoamCSS',
      defaultValue: false
    },
    {
      model_: 'StringProperty',
      name: 'icon'
    },
    {
      model_: 'StringProperty',
      name: 'version'
    },
    {
      model_: 'StringArrayProperty',
      name: 'resources'
    },
    {
      model_: 'BooleanProperty',
      name: 'appcacheManifest',
      defaultValue: false
    },
    {
      model_: 'StringArrayProperty',
      name: 'extraFiles',
      help: 'Extra files to both load during the build process, and include in the built image.',
      adapt: function(_, s) { if ( typeof s === 'string' ) return s.split(','); return s; }
    },
    {
      model_: 'StringArrayProperty',
      name: 'extraModels',
      help: 'Extra models to include in the image regardless of if they were arequired or not.',
      adapt: function(_, s) { if ( typeof s === 'string' ) return s.split(','); return s; },
      factory: function() { return ['foam.ui.FoamTagView']; }
    },
    {
      model_: 'StringArrayProperty',
      name: 'blacklistModels',
      help: 'Models to unconditionally exclude from the image, even if they are listed as required.',
      adapt: function(_, s) { if ( typeof s === 'string' ) return s.split(','); return s; }
    },
    {
      model_: 'BooleanProperty',
      name: 'outputManifest',
      defaultValue: false,
      help: 'Set to true to write out a MANIFEST file listing all included models.'
    },
    {
      name: 'htmlFileName',
      help: 'Name of the main html file to produce.',
      defaultValue: 'main.html'
    },
    {
      model_: 'StringArrayProperty',
      name: 'htmlHeaders'
    },
    {
      name: 'formatter',
      factory: function() {
        return {
          __proto__: JSONUtil.compact,
          keys_: {},
          keyify: JSONUtil.prettyModel.keyify,
          outputObject_: function(out, obj, opt_defaultModel) {
            var first = true;

            out('{');
            if ( obj.model_.id !== opt_defaultModel ) {
              this.outputModel_(out, obj);
              first = false;
            }

            if ( Template.isInstance(obj) ) var isTemplate = true;

            for ( var key in obj.model_.properties_ ) {
              var prop = obj.model_.properties_[key];

              if ( ! this.p(prop) && ( ! isTemplate || prop.name !== 'code' ) ) continue;

              if ( prop.name === 'documentation' ) continue;

              if ( prop.name in obj.instance_ ) {
                var val = obj[prop.name];
                if ( Array.isArray(val) && ! val.length ) continue;
                if ( ! first ) out(',');
                out(this.keyify(prop.name), ': ');

                if ( prop.name === 'methods' ) {
                  out('{');
                  var ff = true;
                  for ( var i = 0 ; i < val.length ; i++ ) {
                    if ( ! ff ) out(',');

                    out(this.keyify(val[i].name), ': ');
                    out(val[i].code);
                    ff = false;
                  }
                  out('}');
                } else {
                  this.output(out, val);
                }
                first = false;
              }
            }

            out('}');
          }
        };
      }
    },
    {
      name: 'path',
      factory: function() { return require('path'); }
    },
    {
      name: 'fileDAO',
      factory: function() { return this.FileDAO.create(); }
    },
    {
      model_: 'StringArrayProperty',
      name: 'extraClassPaths',
      help: 'List of extra .js hierarchies to load models from.  Paths will be checked in the order given, finally falling back to the main FOAM js/ hierarchy.',
      adapt: function(_, s) { if ( typeof s === 'string' ) return s.split(','); return s; }
    },
    {
      model_: 'StringProperty',
      name: 'delegate'
    }
  ],
  methods: {
    execute: function() {
      for ( var i = 0; i < this.extraClassPaths.length ; i++ ) {
        this.X.ModelDAO = this.OrDAO.create({
          delegate: this.ModelFileDAO.create({
            classpath: this.extraClassPaths[i]
          }),
          primary: this.X.ModelDAO
        });
      }

      if ( this.appDefinition ) {
        this.X.ModelDAO.find(this.appDefinition, {
          put: function(d) {
            this.copyFrom(d);
            this.execute_();
          }.bind(this),
          error: function() {
            console.log("App definition failed");
            this.execute_();
          }.bind(this)
        });
      } else {
        this.execute_();
      }
    },
    execute_: function() {
      if ( this.delegate ) {
        arequire(this.delegate)(function(DelegateModel) {
          DelegateModel.create({ builder: this }).buildApp();
        });
      } else {
        this.buildApp();
      }
    },
    buildApp: function() {
      if ( ! this.targetPath ) {
        this.error("targetPath is required");
        process.exit(1);
      }
      if ( ! this.controller ) {
        this.error("controller is required");
        process.exit(1);
      }

      for ( var i = 0 ; i < this.extraFiles.length ; i++ ) {
        require(FOAM_BOOT_DIR + this.path.sep + this.extraFiles[i] + '.js');
      }

      var view = this.defaultView ? arequire(this.defaultView) : anop;

      var seq = [view];
      for ( var i = 0; i < this.extraModels.length ; i++ ) {
        seq.push(arequire(this.extraModels[i]));
      }

      aseq(
        aseq.apply(null, seq),
        arequire(this.controller))(this.buildModel.bind(this));
    },
    buildCoreJS_: function(ret) {
      var i = 0;
      var self = this;
      var corejs = '';
      var file;
      if ( this.coreFiles.length ) var myfiles = this.coreFiles;
      else myfiles = files;
      myfiles = myfiles.concat(this.extraFiles);
      awhile(
        function() { return i < myfiles.length; },
        aif(
          function() {
            file = myfiles[i++];
            if ( Array.isArray(file) ) {
              if ( file[1] == IN_NODEJS )
                return false;
              file = file[0];
            }
            return true;
          },
          aseq(
            function(ret) {
              var path = FOAM_BOOT_DIR + this.path.sep + file + '.js';
              this.fileDAO.find(path, {
                put: ret,
                error: function() {
                  self.error.apply(["Error reading file: ", path].concat(arguments));
                }
              });
            }.bind(this),
            function(ret, file) {
              corejs += '\n';
              corejs += file.contents;
              ret();
            })))(function() { ret(corejs); });
    },
    buildAppJS_: function(ret) {
      var models = {};
      var visited = {};
      var error = this.error;
      var self = this;

      function add(require) {
        if ( visited[require] ) return;
        visited[require] = true;

        var model = X.lookup(require);
        if ( ! model ) {
          error("Could not load model: ", require);
        }
        if ( model.package &&
             self.blacklistModels.indexOf(model.id) == -1 ) {
          models[model.id] = model;
        }

        model.getAllRequires().forEach(add);
      };
      add(this.controller);
      if ( this.defaultView ) add(this.defaultView);

      for ( var i = 0; i < this.extraModels.length ; i++ ) {
        add(this.extraModels[i]);
      }

      var contents = '';

      var ids = Object.keys(models);
      if ( this.outputManifest ) {
        this.fileDAO.put(this.File.create({
          path: this.targetPath + this.path.sep + 'MANIFEST',
          contents: ids.join('\n')
        }));
      }

      for ( var i = 0; i < ids.length; i++ ) {
        var model = models[ids[i]];
        if ( this.precompileTemplates ) {
          for ( var j = 0 ; j < model.templates.length ; j++ ) {
            var t = model.templates[j];
            // It's safe to remove leading and trailing whitespace from CSS.
            if ( t.name === 'CSS' ) t.template = t.template.split('\n').map(function(s) { return s.trim(); }).join('\n');
            t.code = TemplateUtil.compile(t);
            t.clearProperty('template');
          }
        }
        contents += 'CLASS(';
        var formatter = this.precompileTemplates ? this.formatter : JSONUtil.compact;
        contents += formatter.where(NOT_TRANSIENT).stringifyObject(models[ids[i]], 'Model');
        contents += ')\n';
      }

      ret(contents);
    },
    buildModel: function(model) {
      if ( ! model ) {
        this.error('Could not find model: ', this.controller);
      }
      this.log('Building   ', model.id);
      this.log('Target is: ', this.targetPath);
      this.log(this.precompileTemplates ? '' : 'NOT ', 'pre-compiling templates.');

      var self = this;
      aseq(
        function(ret) {
          var file = this.File.create({
            path: this.targetPath + this.path.sep + this.htmlFileName,
            contents: this.HTML()
          });

          console.log('Writing: ', file.path);
          this.fileDAO.put(file, {
            put: ret,
            error: function() {
              self.error('ERROR writing file: ', file.path);
              process.exit(1);
            }
          });
        }.bind(this),
        aif(this.appcacheManifest,
            function(ret) {
              var file = this.File.create({
                path: this.targetPath + this.path.sep + "app.manifest",
                contents: this.MANIFEST()
              });
              console.log('Writing: ', file.path);
              this.fileDAO.put(file, {
                put: ret,
                error: function() {
                  this.error("ERROR writing file: ", file.path);
                  process.exit(1);
                }
              });
            }.bind(this)),
        apar(
          function(ret) { this.buildCoreJS_(ret); }.bind(this),
          function(ret) { this.buildAppJS_(ret); }.bind(this)),
        function(ret, corejs, appjs) {
          var file = this.File.create({
            path: this.targetPath + this.path.sep + 'foam.js',
            contents: corejs + appjs
          });
          console.log('Writing: ', file.path);
          this.fileDAO.put(file, {
            put: ret,
            error: function() {
              self.error('ERROR writing file: ', file.path);
              process.exit(1);
            }
          });
        }.bind(this)
      )(
        function(){
          process.exit(0);
        });
    }
  },
  templates: [
    function HTML() {/*<html<% if ( this.appcacheManifest ) { %> manifest="app.manifest"<% } %>><meta charset="utf-8"><%= this.htmlHeaders.join('') %><% if ( this.includeFoamCSS ) { %><link rel="stylesheet" type="text/css" href="foam.css"/><% } %><% if ( this.icon ) { %><link rel="icon" sizes="128x128" href="<%= this.icon %>"/><% } %><foam model="<%= this.controller %>"<% if ( this.defaultView ) { %> view="<%= this.defaultView %>"<% } %>></foam>*/},
    function MANIFEST() {/*CACHE MANIFEST
# version <%= this.version %>
<% if ( this.appDefinition ) { %># hash: <%= this.appDefinition.hashCode() %><% } %>

CACHE:
foam.js
<%= this.htmlFileName %>
<% if ( this.includeFoamCSS ) { %>foam.css<% } %>
<% for ( var i = 0 ; i < this.resources.length ; i++ ) { %><%= this.resources[i] %>
<% } %>

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


<commit_before>'use strict';

import $ from 'jquery';
import { GetYoDigits } from './foundation.util.core';
import { Plugin } from './foundation.plugin';
import { SmoothScroll } from './foundation.smoothScroll';

/**
 * Magellan module.
 * @module foundation.magellan
 * @requires foundation.smoothScroll
 */

class Magellan extends Plugin {
  /**
   * Creates a new instance of Magellan.
   * @class
   * @name Magellan
   * @fires Magellan#init
   * @param {Object} element - jQuery object to add the trigger to.
   * @param {Object} options - Overrides to the default plugin settings.
   */
  _setup(element, options) {
    this.$element = element;
    this.options  = $.extend({}, Magellan.defaults, this.$element.data(), options);
    this.className = 'Magellan'; // ie9 back compat

    this._init();
    this.calcPoints();
  }

  /**
   * Initializes the Magellan plugin and calls functions to get equalizer functioning on load.
   * @private
   */
  _init() {
    var id = this.$element[0].id || GetYoDigits(6, 'magellan');
    var _this = this;
    this.$targets = $('[data-magellan-target]');
    this.$links = this.$element.find('a');
    this.$element.attr({
      'data-resize': id,
      'data-scroll': id,
      'id': id
    });
    this.$active = $();
    this.scrollPos = parseInt(window.pageYOffset, 10);

    this._events();
  }

  /**
   * Calculates an array of pixel values that are the demarcation lines between locations on the page.
   * Can be invoked if new elements are added or the size of a location changes.
   * @function
   */
  calcPoints() {
    var _this = this,
        body = document.body,
        html = document.documentElement;

    this.points = [];
    this.winHeight = Math.round(Math.max(window.innerHeight, html.clientHeight));
    this.docHeight = Math.round(Math.max(body.scrollHeight, body.offsetHeight, html.clientHeight, html.scrollHeight, html.offsetHeight));

    this.$targets.each(function(){
      var $tar = $(this),
          pt = Math.round($tar.offset().top - _this.options.threshold);
      $tar.targetPoint = pt;
      _this.points.push(pt);
    });
  }

  /**
   * Initializes events for Magellan.
   * @private
   */
  _events() {
    var _this = this,
        $body = $('html, body'),
        opts = {
          duration: _this.options.animationDuration,
          easing:   _this.options.animationEasing
        };
    $(window).one('load', function(){
      if(_this.options.deepLinking){
        if(location.hash){
          _this.scrollToLoc(location.hash);
        }
      }
      _this.calcPoints();
      _this._updateActive();
    });

    this.$element.on({
      'resizeme.zf.trigger': this.reflow.bind(this),
      'scrollme.zf.trigger': this._updateActive.bind(this)
    }).on('click.zf.magellan', 'a[href^="#"]', function(e) {
        e.preventDefault();
        var arrival   = this.getAttribute('href');
        _this.scrollToLoc(arrival);
      });

    this._deepLinkScroll = function(e) {
      if(_this.options.deepLinking) {
        _this.scrollToLoc(window.location.hash);
      }
    };

    $(window).on('popstate', this._deepLinkScroll);
  }

  /**
   * Function to scroll to a given location on the page.
   * @param {String} loc - a properly formatted jQuery id selector. Example: '#foo'
   * @function
   */
  scrollToLoc(loc) {
    this._inTransition = true;
    var _this = this;

    var options = {
      animationEasing: this.options.animationEasing,
      animationDuration: this.options.animationDuration,
      threshold: this.options.threshold,
      offset: this.options.offset
    };

    SmoothScroll.scrollToLoc(loc, options, function() {
      _this._inTransition = false;
      _this._updateActive();
    })
  }

  /**
   * Calls necessary functions to update Magellan upon DOM change
   * @function
   */
  reflow() {
    this.calcPoints();
    this._updateActive();
  }

  /**
   * Updates the visibility of an active location link, and updates the url hash for the page, if deepLinking enabled.
   * @private
   * @function
   * @fires Magellan#update
   */
  _updateActive(/*evt, elem, scrollPos*/) {
    if(this._inTransition) {return;}
    var winPos = /*scrollPos ||*/ parseInt(window.pageYOffset, 10),
        curIdx;

    if(winPos + this.winHeight === this.docHeight){ curIdx = this.points.length - 1; }
    else if(winPos < this.points[0]){ curIdx = undefined; }
    else{
      var isDown = this.scrollPos < winPos,
          _this = this,
          curVisible = this.points.filter(function(p, i){
            return isDown ? p - _this.options.offset <= winPos : p - _this.options.offset - _this.options.threshold <= winPos;
          });
      curIdx = curVisible.length ? curVisible.length - 1 : 0;
    }

    this.$active.removeClass(this.options.activeClass);
    if(curIdx !== undefined){
      this.$active = this.$links.filter('[href="#' + this.$targets.eq(curIdx).data('magellan-target') + '"]').addClass(this.options.activeClass);
    }else{
      this.$active = $();
    }

    if(this.options.deepLinking){
      var hash = "";
      if(curIdx !== undefined){
        hash = this.$active[0].getAttribute('href');
      }
      if(hash !== window.location.hash) {
        if(window.history.pushState){
          var url = curIdx !== undefined ? hash : window.location.pathname;
          if(this.options.updateHistory){
            window.history.pushState({}, '', url);
          }else{
            window.history.replaceState({}, '', url);
          }
        }else{
          window.location.hash = hash;
        }
      }
    }

    this.scrollPos = winPos;
    /**
     * Fires when magellan is finished updating to the new active element.
     * @event Magellan#update
     */
    this.$element.trigger('update.zf.magellan', [this.$active]);
  }

  /**
   * Destroys an instance of Magellan and resets the url of the window.
   * @function
   */
  _destroy() {
    this.$element.off('.zf.trigger .zf.magellan')
        .find(`.${this.options.activeClass}`).removeClass(this.options.activeClass);

    if(this.options.deepLinking){
      var hash = this.$active[0].getAttribute('href');
      window.location.hash.replace(hash, '');
    }
    $(window).off('popstate', this._deepLinkScroll);
  }
}

/**
 * Default settings for plugin
 */
Magellan.defaults = {
  /**
   * Amount of time, in ms, the animated scrolling should take between locations.
   * @option
   * @type {number}
   * @default 500
   */
  animationDuration: 500,
  /**
   * Animation style to use when scrolling between locations. Can be `'swing'` or `'linear'`.
   * @option
   * @type {string}
   * @default 'linear'
   * @see {@link https://api.jquery.com/animate|Jquery animate}
   */
  animationEasing: 'linear',
  /**
   * Number of pixels to use as a marker for location changes.
   * @option
   * @type {number}
   * @default 50
   */
  threshold: 50,
  /**
   * Class applied to the active locations link on the magellan container.
   * @option
   * @type {string}
   * @default 'is-active'
   */
  activeClass: 'is-active',
  /**
   * Allows the script to manipulate the url of the current page, and if supported, alter the history.
   * @option
   * @type {boolean}
   * @default false
   */
  deepLinking: false,
  /**
   * Update the browser history with the active link, if deep linking is enabled.
   * @option
   * @type {boolean}
   * @default false
   */
  updateHistory: false,
  /**
   * Number of pixels to offset the scroll of the page on item click if using a sticky nav bar.
   * @option
   * @type {number}
   * @default 0
   */
  offset: 0
}

export {Magellan};
<commit_msg>fix: prevent to loose query params when reseting hash in magellan<commit_after>'use strict';

import $ from 'jquery';
import { GetYoDigits } from './foundation.util.core';
import { Plugin } from './foundation.plugin';
import { SmoothScroll } from './foundation.smoothScroll';

/**
 * Magellan module.
 * @module foundation.magellan
 * @requires foundation.smoothScroll
 */

class Magellan extends Plugin {
  /**
   * Creates a new instance of Magellan.
   * @class
   * @name Magellan
   * @fires Magellan#init
   * @param {Object} element - jQuery object to add the trigger to.
   * @param {Object} options - Overrides to the default plugin settings.
   */
  _setup(element, options) {
    this.$element = element;
    this.options  = $.extend({}, Magellan.defaults, this.$element.data(), options);
    this.className = 'Magellan'; // ie9 back compat

    this._init();
    this.calcPoints();
  }

  /**
   * Initializes the Magellan plugin and calls functions to get equalizer functioning on load.
   * @private
   */
  _init() {
    var id = this.$element[0].id || GetYoDigits(6, 'magellan');
    var _this = this;
    this.$targets = $('[data-magellan-target]');
    this.$links = this.$element.find('a');
    this.$element.attr({
      'data-resize': id,
      'data-scroll': id,
      'id': id
    });
    this.$active = $();
    this.scrollPos = parseInt(window.pageYOffset, 10);

    this._events();
  }

  /**
   * Calculates an array of pixel values that are the demarcation lines between locations on the page.
   * Can be invoked if new elements are added or the size of a location changes.
   * @function
   */
  calcPoints() {
    var _this = this,
        body = document.body,
        html = document.documentElement;

    this.points = [];
    this.winHeight = Math.round(Math.max(window.innerHeight, html.clientHeight));
    this.docHeight = Math.round(Math.max(body.scrollHeight, body.offsetHeight, html.clientHeight, html.scrollHeight, html.offsetHeight));

    this.$targets.each(function(){
      var $tar = $(this),
          pt = Math.round($tar.offset().top - _this.options.threshold);
      $tar.targetPoint = pt;
      _this.points.push(pt);
    });
  }

  /**
   * Initializes events for Magellan.
   * @private
   */
  _events() {
    var _this = this,
        $body = $('html, body'),
        opts = {
          duration: _this.options.animationDuration,
          easing:   _this.options.animationEasing
        };
    $(window).one('load', function(){
      if(_this.options.deepLinking){
        if(location.hash){
          _this.scrollToLoc(location.hash);
        }
      }
      _this.calcPoints();
      _this._updateActive();
    });

    this.$element.on({
      'resizeme.zf.trigger': this.reflow.bind(this),
      'scrollme.zf.trigger': this._updateActive.bind(this)
    }).on('click.zf.magellan', 'a[href^="#"]', function(e) {
        e.preventDefault();
        var arrival   = this.getAttribute('href');
        _this.scrollToLoc(arrival);
      });

    this._deepLinkScroll = function(e) {
      if(_this.options.deepLinking) {
        _this.scrollToLoc(window.location.hash);
      }
    };

    $(window).on('popstate', this._deepLinkScroll);
  }

  /**
   * Function to scroll to a given location on the page.
   * @param {String} loc - a properly formatted jQuery id selector. Example: '#foo'
   * @function
   */
  scrollToLoc(loc) {
    this._inTransition = true;
    var _this = this;

    var options = {
      animationEasing: this.options.animationEasing,
      animationDuration: this.options.animationDuration,
      threshold: this.options.threshold,
      offset: this.options.offset
    };

    SmoothScroll.scrollToLoc(loc, options, function() {
      _this._inTransition = false;
      _this._updateActive();
    })
  }

  /**
   * Calls necessary functions to update Magellan upon DOM change
   * @function
   */
  reflow() {
    this.calcPoints();
    this._updateActive();
  }

  /**
   * Updates the visibility of an active location link, and updates the url hash for the page, if deepLinking enabled.
   * @private
   * @function
   * @fires Magellan#update
   */
  _updateActive(/*evt, elem, scrollPos*/) {
    if(this._inTransition) {return;}
    var winPos = /*scrollPos ||*/ parseInt(window.pageYOffset, 10),
        curIdx;

    if(winPos + this.winHeight === this.docHeight){ curIdx = this.points.length - 1; }
    else if(winPos < this.points[0]){ curIdx = undefined; }
    else{
      var isDown = this.scrollPos < winPos,
          _this = this,
          curVisible = this.points.filter(function(p, i){
            return isDown ? p - _this.options.offset <= winPos : p - _this.options.offset - _this.options.threshold <= winPos;
          });
      curIdx = curVisible.length ? curVisible.length - 1 : 0;
    }

    this.$active.removeClass(this.options.activeClass);
    if(curIdx !== undefined){
      this.$active = this.$links.filter('[href="#' + this.$targets.eq(curIdx).data('magellan-target') + '"]').addClass(this.options.activeClass);
    }else{
      this.$active = $();
    }

    if(this.options.deepLinking){
      var hash = "";
      if(curIdx !== undefined){
        hash = this.$active[0].getAttribute('href');
      }
      if(hash !== window.location.hash) {
        if(window.history.pushState){
          // If there is no active idx, move to the same url without hash
          // https://stackoverflow.com/a/5298684/4317384
          var url = curIdx !== undefined ? hash : window.location.pathname + window.location.search;

          if(this.options.updateHistory){
            window.history.pushState({}, '', url);
          }else{
            window.history.replaceState({}, '', url);
          }
        }else{
          window.location.hash = hash;
        }
      }
    }

    this.scrollPos = winPos;
    /**
     * Fires when magellan is finished updating to the new active element.
     * @event Magellan#update
     */
    this.$element.trigger('update.zf.magellan', [this.$active]);
  }

  /**
   * Destroys an instance of Magellan and resets the url of the window.
   * @function
   */
  _destroy() {
    this.$element.off('.zf.trigger .zf.magellan')
        .find(`.${this.options.activeClass}`).removeClass(this.options.activeClass);

    if(this.options.deepLinking){
      var hash = this.$active[0].getAttribute('href');
      window.location.hash.replace(hash, '');
    }
    $(window).off('popstate', this._deepLinkScroll);
  }
}

/**
 * Default settings for plugin
 */
Magellan.defaults = {
  /**
   * Amount of time, in ms, the animated scrolling should take between locations.
   * @option
   * @type {number}
   * @default 500
   */
  animationDuration: 500,
  /**
   * Animation style to use when scrolling between locations. Can be `'swing'` or `'linear'`.
   * @option
   * @type {string}
   * @default 'linear'
   * @see {@link https://api.jquery.com/animate|Jquery animate}
   */
  animationEasing: 'linear',
  /**
   * Number of pixels to use as a marker for location changes.
   * @option
   * @type {number}
   * @default 50
   */
  threshold: 50,
  /**
   * Class applied to the active locations link on the magellan container.
   * @option
   * @type {string}
   * @default 'is-active'
   */
  activeClass: 'is-active',
  /**
   * Allows the script to manipulate the url of the current page, and if supported, alter the history.
   * @option
   * @type {boolean}
   * @default false
   */
  deepLinking: false,
  /**
   * Update the browser history with the active link, if deep linking is enabled.
   * @option
   * @type {boolean}
   * @default false
   */
  updateHistory: false,
  /**
   * Number of pixels to offset the scroll of the page on item click if using a sticky nav bar.
   * @option
   * @type {number}
   * @default 0
   */
  offset: 0
}

export {Magellan};
<|endoftext|>


<commit_before>// NOTE: to run > babel-node examples/example_publications.js
// need .env file at root
require('dotenv').config();
const widgetsUrl = process.env.WIDGETS_URL
console.log("WIDGETS_URL="+widgetsUrl)

import * as data from './per0482202_test.json'
import { WidgetsParser } from '../src/widgets_parser'

let widgetsParser = new WidgetsParser()

let prof = widgetsParser.parseProfessionalActivities(data)
let details = {...prof }
console.log(details)
<commit_msg>FDP-3842: update 'example' print-out of 'activities' to include professional-activities<commit_after>// NOTE: to run > babel-node examples/example_publications.js
// need .env file at root
require('dotenv').config();
const widgetsUrl = process.env.WIDGETS_URL
console.log("WIDGETS_URL="+widgetsUrl)

import * as data from './per0482202_test.json'
import { WidgetsParser } from '../src/widgets_parser'

let widgetsParser = new WidgetsParser()

let prof = widgetsParser.parseProfessionalActivities(data)
let teaching = widgetsParser.parseTeachingActivities(data)
let details = {...prof, ...teaching }
console.log(details)
<|endoftext|>


<commit_before>(function($){
"use strict";
/**
 * jqGrid Russian Translation v1.0 02.07.2009 (based on translation by Alexey Kanaev v1.1 21.01.2009, http://softcore.com.ru)
 * Sergey Dyagovchenko
 * http://d.sumy.ua
 * Dual licensed under the MIT and GPL licenses:
 * http://www.opensource.org/licenses/mit-license.php
 * http://www.gnu.org/licenses/gpl.html
**/
$.jgrid = $.jgrid || {};
$.extend(true,$.jgrid,{
	defaults : {
		recordtext: "Просмотр {0} - {1} из {2}",
		emptyrecords: "Нет записей для просмотра",
		loadtext: "Загрузка...",
		pgtext : "Стр. {0} из {1}",
		pgfirst : "First Page",
		pglast : "Last Page",
		pgnext : "Next Page",
		pgprev : "Previous Page",
		pgrecs : "Records per Page",
		showhide: "Toggle Expand Collapse Grid"
	},
	search : {
		caption: "Поиск...",
		Find: "Найти",
		Reset: "Сброс",
		odata: [{ oper:'eq', text:"равно"},{ oper:'ne', text:"не равно"},{ oper:'lt', text:"меньше"},{ oper:'le', text:"меньше или равно"},{ oper:'gt', text:"больше"},{ oper:'ge', text:"больше или равно"},{ oper:'bw', text:"начинается с"},{ oper:'bn', text:"не начинается с"},{ oper:'in', text:"находится в"},{ oper:'ni', text:"не находится в"},{ oper:'ew', text:"заканчивается на"},{ oper:'en', text:"не заканчивается на"},{ oper:'cn', text:"содержит"},{ oper:'nc', text:"не содержит"},{ oper:'nu', text:"равно NULL"},{ oper:'nn', text:"не равно NULL"}],
		groupOps: [	{ op: "AND", text: "все" }, { op: "OR", text: "любой" }],
		operandTitle : "Click to select search operation.",
		resetTitle : "Reset Search Value"
	},
	edit : {
		addCaption: "Добавить запись",
		editCaption: "Редактировать запись",
		bSubmit: "Сохранить",
		bCancel: "Отмена",
		bClose: "Закрыть",
		saveData: "Данные были измененны! Сохранить изменения?",
		bYes : "Да",
		bNo : "Нет",
		bExit : "Отмена",
		msg: {
			required:"Поле является обязательным",
			number:"Пожалуйста, введите правильное число",
			minValue:"значение должно быть больше либо равно",
			maxValue:"значение должно быть меньше либо равно",
			email: "некорректное значение e-mail",
			integer: "Пожалуйста, введите целое число",
			date: "Пожалуйста, введите правильную дату",
			url: "неверная ссылка. Необходимо ввести префикс ('http://' или 'https://')",
			nodefined : " не определено!",
			novalue : " возвращаемое значение обязательно!",
			customarray : "Пользовательская функция должна возвращать массив!",
			customfcheck : "Пользовательская функция должна присутствовать в случаи пользовательской проверки!"
		}
	},
	view : {
		caption: "Просмотр записи",
		bClose: "Закрыть"
	},
	del : {
		caption: "Удалить",
		msg: "Удалить выбранную запись(и)?",
		bSubmit: "Удалить",
		bCancel: "Отмена"
	},
	nav : {
		edittext: " ",
		edittitle: "Редактировать выбранную запись",
		addtext:" ",
		addtitle: "Добавить новую запись",
		deltext: " ",
		deltitle: "Удалить выбранную запись",
		searchtext: " ",
		searchtitle: "Найти записи",
		refreshtext: "",
		refreshtitle: "Обновить таблицу",
		alertcap: "Внимание",
		alerttext: "Пожалуйста, выберите запись",
		viewtext: "",
		viewtitle: "Просмотреть выбранную запись"
	},
	col : {
		caption: "Показать/скрыть столбцы",
		bSubmit: "Сохранить",
		bCancel: "Отмена"
	},
	errors : {
		errcap : "Ошибка",
		nourl : "URL не установлен",
		norecords: "Нет записей для обработки",
		model : "Число полей не соответствует числу столбцов таблицы!"
	},
	formatter : {
		integer : {thousandsSeparator: " ", defaultValue: '0'},
		number : {decimalSeparator:",", thousandsSeparator: " ", decimalPlaces: 2, defaultValue: '0,00'},
		currency : {decimalSeparator:",", thousandsSeparator: " ", decimalPlaces: 2, prefix: "", suffix:"", defaultValue: '0,00'},
		date : {
			dayNames:   [
				"Вс", "Пн", "Вт", "Ср", "Чт", "Пт", "Сб",
				"Воскресение", "Понедельник", "Вторник", "Среда", "Четверг", "Пятница", "Суббота"
			],
			monthNames: [
				"Янв", "Фев", "Мар", "Апр", "Май", "Июн", "Июл", "Авг", "Сен", "Окт", "Ноя", "Дек",
				"Январь", "Февраль", "Март", "Апрель", "Май", "Июнь", "Июль", "Август", "Сентябрь", "Октябрь", "Ноябрь", "Декабрь"
			],
			AmPm : ["am","pm","AM","PM"],
			S: function (j) {return j < 11 || j > 13 ? ['st', 'nd', 'rd', 'th'][Math.min((j - 1) % 10, 3)] : 'th';},
			srcformat: 'Y-m-d',
			newformat: 'd.m.Y',
			masks : {
				ShortDate: "n.j.Y",
				LongDate: "l, F d, Y",
				FullDateTime: "l, F d, Y G:i:s",
				MonthDay: "F d",
				ShortTime: "G:i",
				LongTime: "G:i:s",
				YearMonth: "F, Y"
			}
		}
	}
});
}(jQuery));
<commit_msg>Fix translation to Russian<commit_after>(function($){
"use strict";
/**
 * jqGrid Russian Translation v1.0 02.07.2009 based on translation by Alexey Kanaev, v1.1 21.01.2009 (http://softcore.com.ru) and 07.01.2015 (http://smartcore.ru)
 * Sergey Dyagovchenko
 * http://d.sumy.ua
 * Dual licensed under the MIT and GPL licenses:
 * http://www.opensource.org/licenses/mit-license.php
 * http://www.gnu.org/licenses/gpl.html
**/
$.jgrid = $.jgrid || {};
$.extend(true,$.jgrid,{
	defaults : {
		recordtext: "Просмотр {0} - {1} из {2}",
		emptyrecords: "Нет записей для просмотра",
		loadtext: "Загрузка...",
		pgtext : "Стр. {0} из {1}",
		pgfirst : "Первая стр.",
		pglast : "Последняя стр.",
		pgnext : "След. стр.",
		pgprev : "Пред. стр.",
		pgrecs : "Записей на стр.",
		showhide: "Показать/скрыть таблицу"
	},
	search : {
		caption: "Поиск...",
		Find: "Найти",
		Reset: "Сброс",
		odata: [{ oper:'eq', text:"равно"},{ oper:'ne', text:"не равно"},{ oper:'lt', text:"меньше"},{ oper:'le', text:"меньше или равно"},{ oper:'gt', text:"больше"},{ oper:'ge', text:"больше или равно"},{ oper:'bw', text:"начинается с"},{ oper:'bn', text:"не начинается с"},{ oper:'in', text:"находится в"},{ oper:'ni', text:"не находится в"},{ oper:'ew', text:"заканчивается на"},{ oper:'en', text:"не заканчивается на"},{ oper:'cn', text:"содержит"},{ oper:'nc', text:"не содержит"},{ oper:'nu', text:"равно NULL"},{ oper:'nn', text:"не равно NULL"}],
		groupOps: [	{ op: "AND", text: "все" }, { op: "OR", text: "любой" }],
		operandTitle : "Выбрать операцию поиска",
		resetTitle : "Сбросить"
	},
	edit : {
		addCaption: "Добавить запись",
		editCaption: "Редактировать запись",
		bSubmit: "Сохранить",
		bCancel: "Отмена",
		bClose: "Закрыть",
		saveData: "Данные были измененны! Сохранить изменения?",
		bYes : "Да",
		bNo : "Нет",
		bExit : "Отмена",
		msg: {
			required:"Поле является обязательным",
			number:"Пожалуйста, введите правильное число",
			minValue:"значение должно быть больше либо равно",
			maxValue:"значение должно быть меньше либо равно",
			email: "некорректное значение e-mail",
			integer: "Пожалуйста, введите целое число",
			date: "Пожалуйста, введите правильную дату",
			url: "неверная ссылка. Необходимо ввести префикс ('http://' или 'https://')",
			nodefined : " не определено!",
			novalue : " возвращаемое значение обязательно!",
			customarray : "Пользовательская функция должна возвращать массив!",
			customfcheck : "Пользовательская функция должна присутствовать в случаи пользовательской проверки!"
		}
	},
	view : {
		caption: "Просмотр записи",
		bClose: "Закрыть"
	},
	del : {
		caption: "Удалить",
		msg: "Удалить выбранную запись(и)?",
		bSubmit: "Удалить",
		bCancel: "Отмена"
	},
	nav : {
		edittext: " ",
		edittitle: "Редактировать выбранную запись",
		addtext:" ",
		addtitle: "Добавить новую запись",
		deltext: " ",
		deltitle: "Удалить выбранную запись",
		searchtext: " ",
		searchtitle: "Найти записи",
		refreshtext: "",
		refreshtitle: "Обновить таблицу",
		alertcap: "Внимание",
		alerttext: "Пожалуйста, выберите запись",
		viewtext: "",
		viewtitle: "Просмотреть выбранную запись"
	},
	col : {
		caption: "Показать/скрыть столбцы",
		bSubmit: "Сохранить",
		bCancel: "Отмена"
	},
	errors : {
		errcap : "Ошибка",
		nourl : "URL не установлен",
		norecords: "Нет записей для обработки",
		model : "Число полей не соответствует числу столбцов таблицы!"
	},
	formatter : {
		integer : {thousandsSeparator: " ", defaultValue: '0'},
		number : {decimalSeparator:",", thousandsSeparator: " ", decimalPlaces: 2, defaultValue: '0,00'},
		currency : {decimalSeparator:",", thousandsSeparator: " ", decimalPlaces: 2, prefix: "", suffix:"", defaultValue: '0,00'},
		date : {
			dayNames:   [
				"Вс", "Пн", "Вт", "Ср", "Чт", "Пт", "Сб",
				"Воскресение", "Понедельник", "Вторник", "Среда", "Четверг", "Пятница", "Суббота"
			],
			monthNames: [
				"Янв", "Фев", "Мар", "Апр", "Май", "Июн", "Июл", "Авг", "Сен", "Окт", "Ноя", "Дек",
				"Январь", "Февраль", "Март", "Апрель", "Май", "Июнь", "Июль", "Август", "Сентябрь", "Октябрь", "Ноябрь", "Декабрь"
			],
			AmPm : ["am","pm","AM","PM"],
			S: function (j) {return j < 11 || j > 13 ? ['st', 'nd', 'rd', 'th'][Math.min((j - 1) % 10, 3)] : 'th';},
			srcformat: 'Y-m-d',
			newformat: 'd.m.Y',
			masks : {
				ShortDate: "n.j.Y",
				LongDate: "l, F d, Y",
				FullDateTime: "l, F d, Y G:i:s",
				MonthDay: "F d",
				ShortTime: "G:i",
				LongTime: "G:i:s",
				YearMonth: "F, Y"
			}
		}
	}
});
}(jQuery));
<|endoftext|>


<commit_before>// Copyright 2002-2012, University of Colorado

/**
 * A layer state is used to construct layer information (and later, layers), and is a state machine
 * that layer strategies from each node modify. Iterating through all of the nodes in a depth-first
 * manner will modify the LayerBuilder so that layer information can be retrieved.
 *
 * @author Jonathan Olson <olsonsjc@gmail.com>
 */

define( function( require ) {
  "use strict";

  var assert = require( 'ASSERT/assert' )( 'scenery' );

  var scenery = require( 'SCENERY/scenery' );
  require( 'SCENERY/layers/LayerBoundary' );
  require( 'SCENERY/util/Trail' );
  require( 'SCENERY/util/TrailPointer' );

  /*
   * Builds layer information between trails
   *
   * previousLayerType should be null if there is no previous layer.
   */
  scenery.LayerBuilder = function( scene, previousLayerType, previousSelfTrail, nextSelfTrail ) {

    /*---------------------------------------------------------------------------*
    * Initial state
    *----------------------------------------------------------------------------*/

    this.layerTypeStack = [];
    this.boundaries = [];
    this.pendingBoundary = new scenery.LayerBoundary();
    this.pendingBoundary.previousLayerType = previousLayerType;
    this.pendingBoundary.previousSelfTrail = previousSelfTrail;

    /*
     * The current layer type active, and whether it has been 'used' yet. A node with hasSelf() will trigger a 'used' action,
     * and if the layer hasn't been used, it will actually trigger a boundary creation. We want to collapse 'unused' layers
     * and boundaries together, so that every created layer has a node that displays something.
     */
    this.currentLayerType = previousLayerType;
    this.layerChangePending = previousSelfTrail === null;

    /*---------------------------------------------------------------------------*
    * Start / End pointers
    *----------------------------------------------------------------------------*/

    if ( previousSelfTrail ) {
      // Move our start pointer just past the previousSelfTrail, since our previousLayerType is presumably for that trail's node's self.
      // Anything after that self could have been collapsed, so we need to start there.
      this.startPointer = new scenery.TrailPointer( previousSelfTrail.copy(), true );
      this.startPointer.nestedForwards();
    } else {
      this.startPointer = new scenery.TrailPointer( new scenery.Trail( scene ), true );
    }

    if ( nextSelfTrail ) {
      // include the nextSelfTrail's 'before' in our iteration, so we can stitch properly with the next layer
      this.endPointer = new scenery.TrailPointer( nextSelfTrail.copy(), true );
    } else {
      this.endPointer = new scenery.TrailPointer( new scenery.Trail( scene ), false );
    }

    this.includesEndTrail = nextSelfTrail !== null;

    /*
     * LayerBoundary properties and assurances:
     *
     * previousLayerType  - initialized in constructor (in case there are no layer changes)
     *                      set in layerChange for "fresh" pending boundary
     * nextLayerType      - set and overwrites in switchToType, for collapsing layers
     *                      not set anywhere else, so we can leave it null
     * previousSelfTrail  - initialized in constructor
     *                      updated in markSelf if there is no pending change (don't set if there is a pending change)
     * nextSelfTrail      - set on layerChange for "stale" boundary
     *                      stays null if nextSelfTrail === null
     * previousEndPointer - (normal boundary) set in switchToType if there is no layer change pending
     *                      set in finalization if nextSelfTrail === null && !this.layerChangePending (previousEndPointer should be null in that case)
     * nextStartPointer   - set in switchToType (always), overwrites values so we collapse layers nicely
     */
  };
  var LayerBuilder = scenery.LayerBuilder;

  LayerBuilder.prototype = {
    constructor: LayerBuilder,

    // walks part of the state up to just before the startPointer. we want the preferred layer stack to be in place, but the rest is not important
    prepareLayerStack: function() {
      var pointer = new scenery.TrailPointer( new scenery.Trail( this.startPointer.trail.rootNode() ), true );
      while ( pointer.trail.length < this.startPointer.trail.length ) {
        var node = pointer.trail.lastNode();
        if ( node.layerStrategy.hasPreferredLayerType( pointer, this ) ) {
          this.pushPreferredLayerType( node.layerStrategy.getPreferredLayerType( pointer, this ) );
        }
        pointer.trail.addDescendant( this.startPointer.trail.nodes[pointer.trail.length] );
      }
    },

    run: function() {
      var builder = this;

      // push preferred layers for ancestors of our start pointer
      this.prepareLayerStack();

      console.log( '         stack: ' + _.map( builder.layerTypeStack, function( type ) { return type.name; } ).join( ', ' ) );

      builder.startPointer.depthFirstUntil( builder.endPointer, function( pointer ) {
        var node = pointer.trail.lastNode();

        if ( pointer.isBefore ) {
          console.log( 'builder: enter ' + pointer.toString() );
          node.layerStrategy.enter( pointer, builder );
        } else {
          console.log( 'builder: exit ' + pointer.toString() );
          node.layerStrategy.exit( pointer, builder );
        }
        console.log( '         stack: ' + _.map( builder.layerTypeStack, function( type ) { return type.name; } ).join( ', ' ) );
      }, false ); // include the endpoints

      // special case handling if we are at the 'end' of the scene, so that we create another 'wrapping' boundary
      if ( !this.includesEndTrail ) {
        console.log( 'builder: not including end trail' );
        this.pendingBoundary.previousEndPointer = builder.endPointer; // TODO: consider implications if we leave this null, to indicate that it is not ended?
        this.layerChange( null );
      }
    },

    // allows selfPointer === null at the end if the main iteration's nextSelfTrail === null (i.e. we are at the end of the scene)
    layerChange: function( selfPointer ) {
      this.layerChangePending = false;

      var confirmedBoundary = this.pendingBoundary;

      confirmedBoundary.nextSelfTrail = selfPointer ? selfPointer.trail.copy() : null;

      this.boundaries.push( confirmedBoundary );

      this.pendingBoundary = new scenery.LayerBoundary();
      this.pendingBoundary.previousLayerType = confirmedBoundary.nextLayerType;
      this.pendingBoundary.previousSelfTrail = confirmedBoundary.nextSelfTrail;
      console.log( 'builder:   added boundary' );
    },

    /*---------------------------------------------------------------------------*
    * API for layer strategy or other interaction
    *----------------------------------------------------------------------------*/

    switchToType: function( pointer, layerType ) {
      this.currentLayerType = layerType;

      this.pendingBoundary.nextLayerType = layerType;
      this.pendingBoundary.nextStartPointer = pointer.copy();
      if ( !this.layerChangePending ) {
        this.pendingBoundary.previousEndPointer = pointer.copy();
      }

      this.layerChangePending = true; // we wait until the first markSelf() call to create a boundary
    },

    // called so that we can finalize a layer switch (instead of collapsing unneeded layers)
    markSelf: function( pointer ) {
      if ( this.layerChangePending ) {
        this.layerChange( pointer );
      } else {
        // TODO: performance-wise, don't lookup indices on this copy? make a way to create a lightweight copy?
        this.pendingBoundary.previousSelfTrail = pointer.trail.copy();
      }
    },

    // can be null to indicate that there is no current layer type
    getCurrentLayerType: function() {
      return this.currentLayerType;
    },

    pushPreferredLayerType: function( layerType ) {
      this.layerTypeStack.push( layerType );
    },

    popPreferredLayerType: function() {
      this.layerTypeStack.pop();
    },

    getPreferredLayerType: function() {
      if ( this.layerTypeStack.length !== 0 ) {
        return this.layerTypeStack[this.layerTypeStack.length - 1];
      } else {
        return null;
      }
    },

    bestPreferredLayerTypeFor: function( renderers ) {
      for ( var i = this.layerTypeStack.length - 1; i >= 0; i-- ) {
        var preferredType = this.layerTypeStack[i];
        if ( _.some( renderers, function( renderer ) { return preferredType.supportsRenderer( renderer ); } ) ) {
          return preferredType;
        }
      }

      // none of our stored preferred layer types are able to support any of the default type options
      return null;
    }
  };

  return LayerBuilder;
} );
<commit_msg>Fixed subtle builder bug where exit() was being called and layerStack was one short<commit_after>// Copyright 2002-2012, University of Colorado

/**
 * A layer state is used to construct layer information (and later, layers), and is a state machine
 * that layer strategies from each node modify. Iterating through all of the nodes in a depth-first
 * manner will modify the LayerBuilder so that layer information can be retrieved.
 *
 * @author Jonathan Olson <olsonsjc@gmail.com>
 */

define( function( require ) {
  "use strict";

  var assert = require( 'ASSERT/assert' )( 'scenery' );

  var scenery = require( 'SCENERY/scenery' );
  require( 'SCENERY/layers/LayerBoundary' );
  require( 'SCENERY/util/Trail' );
  require( 'SCENERY/util/TrailPointer' );

  /*
   * Builds layer information between trails
   *
   * previousLayerType should be null if there is no previous layer.
   */
  scenery.LayerBuilder = function( scene, previousLayerType, previousSelfTrail, nextSelfTrail ) {

    /*---------------------------------------------------------------------------*
    * Initial state
    *----------------------------------------------------------------------------*/

    this.layerTypeStack = [];
    this.boundaries = [];
    this.pendingBoundary = new scenery.LayerBoundary();
    this.pendingBoundary.previousLayerType = previousLayerType;
    this.pendingBoundary.previousSelfTrail = previousSelfTrail;

    /*
     * The current layer type active, and whether it has been 'used' yet. A node with hasSelf() will trigger a 'used' action,
     * and if the layer hasn't been used, it will actually trigger a boundary creation. We want to collapse 'unused' layers
     * and boundaries together, so that every created layer has a node that displays something.
     */
    this.currentLayerType = previousLayerType;
    this.layerChangePending = previousSelfTrail === null;

    /*---------------------------------------------------------------------------*
    * Start / End pointers
    *----------------------------------------------------------------------------*/

    if ( previousSelfTrail ) {
      // Move our start pointer just past the previousSelfTrail, since our previousLayerType is presumably for that trail's node's self.
      // Anything after that self could have been collapsed, so we need to start there.
      this.startPointer = new scenery.TrailPointer( previousSelfTrail.copy(), true );
      this.startPointer.nestedForwards();
    } else {
      this.startPointer = new scenery.TrailPointer( new scenery.Trail( scene ), true );
    }

    if ( nextSelfTrail ) {
      // include the nextSelfTrail's 'before' in our iteration, so we can stitch properly with the next layer
      this.endPointer = new scenery.TrailPointer( nextSelfTrail.copy(), true );
    } else {
      this.endPointer = new scenery.TrailPointer( new scenery.Trail( scene ), false );
    }

    this.includesEndTrail = nextSelfTrail !== null;

    /*
     * LayerBoundary properties and assurances:
     *
     * previousLayerType  - initialized in constructor (in case there are no layer changes)
     *                      set in layerChange for "fresh" pending boundary
     * nextLayerType      - set and overwrites in switchToType, for collapsing layers
     *                      not set anywhere else, so we can leave it null
     * previousSelfTrail  - initialized in constructor
     *                      updated in markSelf if there is no pending change (don't set if there is a pending change)
     * nextSelfTrail      - set on layerChange for "stale" boundary
     *                      stays null if nextSelfTrail === null
     * previousEndPointer - (normal boundary) set in switchToType if there is no layer change pending
     *                      set in finalization if nextSelfTrail === null && !this.layerChangePending (previousEndPointer should be null in that case)
     * nextStartPointer   - set in switchToType (always), overwrites values so we collapse layers nicely
     */
  };
  var LayerBuilder = scenery.LayerBuilder;

  LayerBuilder.prototype = {
    constructor: LayerBuilder,

    // walks part of the state up to just before the startPointer. we want the preferred layer stack to be in place, but the rest is not important
    prepareLayerStack: function() {
      var pointer = new scenery.TrailPointer( new scenery.Trail( this.startPointer.trail.rootNode() ), true );

      // if the start pointer is going to execute an exit() instead of an enter() on its trail node, we need to bump up the layer stack an additional step
      var targetLength = this.startPointer.trail.length - ( this.startPointer.isBefore ? 1 : 0 );

      while ( pointer.trail.length <= targetLength ) {
        var node = pointer.trail.lastNode();
        if ( node.layerStrategy.hasPreferredLayerType( pointer, this ) ) {
          this.pushPreferredLayerType( node.layerStrategy.getPreferredLayerType( pointer, this ) );
        }
        pointer.trail.addDescendant( this.startPointer.trail.nodes[pointer.trail.length] );
      }
    },

    run: function() {
      var builder = this;

      // push preferred layers for ancestors of our start pointer
      this.prepareLayerStack();

      console.log( '         stack: ' + _.map( builder.layerTypeStack, function( type ) { return type.name; } ).join( ', ' ) );

      builder.startPointer.depthFirstUntil( builder.endPointer, function( pointer ) {
        var node = pointer.trail.lastNode();

        if ( pointer.isBefore ) {
          console.log( 'builder: enter ' + pointer.toString() );
          node.layerStrategy.enter( pointer, builder );
        } else {
          console.log( 'builder: exit ' + pointer.toString() );
          node.layerStrategy.exit( pointer, builder );
        }
        console.log( '         stack: ' + _.map( builder.layerTypeStack, function( type ) { return type.name; } ).join( ', ' ) );
      }, false ); // include the endpoints

      // special case handling if we are at the 'end' of the scene, so that we create another 'wrapping' boundary
      if ( !this.includesEndTrail ) {
        console.log( 'builder: not including end trail' );
        this.pendingBoundary.previousEndPointer = builder.endPointer; // TODO: consider implications if we leave this null, to indicate that it is not ended?
        this.layerChange( null );
      }
    },

    // allows selfPointer === null at the end if the main iteration's nextSelfTrail === null (i.e. we are at the end of the scene)
    layerChange: function( selfPointer ) {
      this.layerChangePending = false;

      var confirmedBoundary = this.pendingBoundary;

      confirmedBoundary.nextSelfTrail = selfPointer ? selfPointer.trail.copy() : null;

      this.boundaries.push( confirmedBoundary );

      this.pendingBoundary = new scenery.LayerBoundary();
      this.pendingBoundary.previousLayerType = confirmedBoundary.nextLayerType;
      this.pendingBoundary.previousSelfTrail = confirmedBoundary.nextSelfTrail;
      console.log( 'builder:   added boundary' );
    },

    /*---------------------------------------------------------------------------*
    * API for layer strategy or other interaction
    *----------------------------------------------------------------------------*/

    switchToType: function( pointer, layerType ) {
      this.currentLayerType = layerType;

      this.pendingBoundary.nextLayerType = layerType;
      this.pendingBoundary.nextStartPointer = pointer.copy();
      if ( !this.layerChangePending ) {
        this.pendingBoundary.previousEndPointer = pointer.copy();
      }

      this.layerChangePending = true; // we wait until the first markSelf() call to create a boundary
    },

    // called so that we can finalize a layer switch (instead of collapsing unneeded layers)
    markSelf: function( pointer ) {
      if ( this.layerChangePending ) {
        this.layerChange( pointer );
      } else {
        // TODO: performance-wise, don't lookup indices on this copy? make a way to create a lightweight copy?
        this.pendingBoundary.previousSelfTrail = pointer.trail.copy();
      }
    },

    // can be null to indicate that there is no current layer type
    getCurrentLayerType: function() {
      return this.currentLayerType;
    },

    pushPreferredLayerType: function( layerType ) {
      this.layerTypeStack.push( layerType );
    },

    popPreferredLayerType: function() {
      this.layerTypeStack.pop();
    },

    getPreferredLayerType: function() {
      if ( this.layerTypeStack.length !== 0 ) {
        return this.layerTypeStack[this.layerTypeStack.length - 1];
      } else {
        return null;
      }
    },

    bestPreferredLayerTypeFor: function( renderers ) {
      for ( var i = this.layerTypeStack.length - 1; i >= 0; i-- ) {
        var preferredType = this.layerTypeStack[i];
        if ( _.some( renderers, function( renderer ) { return preferredType.supportsRenderer( renderer ); } ) ) {
          return preferredType;
        }
      }

      // none of our stored preferred layer types are able to support any of the default type options
      return null;
    }
  };

  return LayerBuilder;
} );
<|endoftext|>


<commit_before>// Pattern which Plone livesearch functionality on an input
//
// Author: Ryan Foster
// Contact: ryan@rynamic.com
// Version: 1.0
//
// Adapted from livesearch.js in Plone.
//
// License:
//
// Copyright (C) 2013 Plone Foundation
//
// This program is free software; you can redistribute it and/or modify it
// under the terms of the GNU General Public License as published by the Free
// Software Foundation; either version 2 of the License.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
// more details.
//
// You should have received a copy of the GNU General Public License along with
// this program; if not, write to the Free Software Foundation, Inc., 51
// Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
//

/*jshint bitwise:true, curly:true, eqeqeq:true, immed:true, latedef:true,
  newcap:true, noarg:true, noempty:true, nonew:true, plusplus:true,
  undef:true, strict:true, trailing:true, browser:true, evil:true */
/*global define:false */

define([
  'jquery',
  'js/patterns/base',
  'js/patterns/toggle',
  'underscore',
  'js/patterns/select2',
  'js/patterns/queryhelper'
], function($, Base, Toggle, _, Select2, QueryHelper) {
  "use strict";

  var Livesearch = Base.extend({
    name: "livesearch",
    defaults: {
      multiple: true,
      closeOnSelect: false,
      minimumInputLength: 3,
      tokenSeparators: [",", " "],
      dropdownCssClass: 'pat-livesearch-dropdown',
      linkSelector: 'pat-livesearch-result-title',
      resultTemplate: '' +
        '<div class="pat-livesearch-result pat-livesearch-type-<%= Type %>">' +
          '<a class="pat-livesearch-result-title" href="<%= getURL %>">' +
            '<%= Title %>' +
          '' +
          '
<%= Description %>
' +
        '
',
      resultTemplateSelector: null,
      isTest: false,
      id: function(object) {
        return object.UID;
      }
    },

    init: function() {
      var self = this;
      self.query = new QueryHelper(self.$el, self.options);
      self.query.init();

      if (!self.query.valid) {
        $.error('No url provided for livesearch results ' + self.$el);
      }

      Select2.prototype.initializeValueMap.call(self);
      Select2.prototype.initializeTags.call(self);
      Select2.prototype.initializeOrdering.call(self);

      if(self.query.valid){
        self.options.ajax = self.query.selectAjax();
      }
      else {
        self.options.tags = [];
      }

      self.options.formatResult = function(item) {
        var result = $(self.applyTemplate('result', item));
        return $(result);
      };

      Select2.prototype.initializeSelect2.call(self);

      self.$el.on("select2-selecting", function(event, data) {
        event.preventDefault();
        self.select();
      });
    },

    applyTemplate: function(tpl, item) {
      var self = this;
      var template;
      if (self.options[tpl+'TemplateSelector']) {
        template = $(self.options[tpl+'TemplateSelector']).html();
        if (!template) {
          template = self.options[tpl+'Template'];
        }
      } else {
        template = self.options[tpl+'Template'];
      }
      return _.template(template, item);
    },

    select: function() {
      var self = this;
      var select2 = self.$el.data().select2;
      var dropdown = select2.dropdown;
      var selected = $('.select2-highlighted', dropdown);
      var link = $('.'+self.options.linkSelector, selected);
      var target = link.attr('href');
      if (target) {
        // There may be a better way to do this
        if (self.options.isTest) {
          self.testTarget = target;
        } else {
          window.location = target;
        }
      }
    }

  });

  return Livesearch;

});
<commit_msg>use basePattern<commit_after>// Pattern which Plone livesearch functionality on an input
//
// Author: Ryan Foster
// Contact: ryan@rynamic.com
// Version: 1.0
//
// Adapted from livesearch.js in Plone.
//
// License:
//
// Copyright (C) 2013 Plone Foundation
//
// This program is free software; you can redistribute it and/or modify it
// under the terms of the GNU General Public License as published by the Free
// Software Foundation; either version 2 of the License.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
// more details.
//
// You should have received a copy of the GNU General Public License along with
// this program; if not, write to the Free Software Foundation, Inc., 51
// Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
//

/*jshint bitwise:true, curly:true, eqeqeq:true, immed:true, latedef:true,
  newcap:true, noarg:true, noempty:true, nonew:true, plusplus:true,
  undef:true, strict:true, trailing:true, browser:true, evil:true */
/*global define:false */

define([
  'jquery',
  'js/patterns/base',
  'js/patterns/toggle',
  'underscore',
  'js/patterns/select2',
  'js/patterns/queryhelper'
], function($, Base, Toggle, _, Select2, QueryHelper) {
  "use strict";

  var Livesearch = Base.extend({
    name: "livesearch",
    defaults: {
      multiple: true,
      closeOnSelect: false,
      minimumInputLength: 3,
      tokenSeparators: [",", " "],
      dropdownCssClass: 'pat-livesearch-dropdown',
      linkSelector: 'pat-livesearch-result-title',
      resultTemplate: '' +
        '<div class="pat-livesearch-result pat-livesearch-type-<%= Type %>">' +
          '<a class="pat-livesearch-result-title" href="<%= getURL %>">' +
            '<%= Title %>' +
          '' +
          '
<%= Description %>
' +
        '
',
      resultTemplateSelector: null,
      isTest: false,
      id: function(object) {
        return object.UID;
      }
    },

    init: function() {
      var self = this;
      self.query = new QueryHelper(self.$el, self.options);
      self.query.init(self);

      if (!self.query.valid) {
        $.error('No url provided for livesearch results ' + self.$el);
      }

      Select2.prototype.initializeValueMap.call(self);
      Select2.prototype.initializeTags.call(self);
      Select2.prototype.initializeOrdering.call(self);

      if(self.query.valid){
        self.options.ajax = self.query.selectAjax();
      }
      else {
        self.options.tags = [];
      }

      self.options.formatResult = function(item) {
        var result = $(self.applyTemplate('result', item));
        return $(result);
      };

      Select2.prototype.initializeSelect2.call(self);

      self.$el.on("select2-selecting", function(event, data) {
        event.preventDefault();
        self.select();
      });
    },

    applyTemplate: function(tpl, item) {
      var self = this;
      var template;
      if (self.options[tpl+'TemplateSelector']) {
        template = $(self.options[tpl+'TemplateSelector']).html();
        if (!template) {
          template = self.options[tpl+'Template'];
        }
      } else {
        template = self.options[tpl+'Template'];
      }
      return _.template(template, item);
    },

    select: function() {
      var self = this;
      var select2 = self.$el.data().select2;
      var dropdown = select2.dropdown;
      var selected = $('.select2-highlighted', dropdown);
      var link = $('.'+self.options.linkSelector, selected);
      var target = link.attr('href');
      if (target) {
        // There may be a better way to do this
        if (self.options.isTest) {
          self.testTarget = target;
        } else {
          window.location = target;
        }
      }
    }

  });

  return Livesearch;

});
<|endoftext|>


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

    var Level1State = function(Level1) {
        // load sprites here
        this.player = gameManager.getSprite('player');

    };

    Level1State.prototype.preload = function() {
        // player
        this.player.preload();
        this.game.load.spritesheet('rato', 'assets/spritesheets/rato-sprite.png', 64, 64, 3);
        this.game.load.image('tiledFases', 'assets/spritesheets/tiled-fases.png');
        this.game.load.spritesheet('items', 'Assets/spritesheets/items.png', 32, 32, 16);
        this.game.load.spritesheet('enemies', 'Assets/spritesheets/enemies.png', 32, 32, 12);
        this.game.load.audio('environmentSound', 'assets/sounds/environment.ogg');

        //Tile maps
        this.game.load.tilemap('Level1','assets/maps/level1.json', null, Phaser.Tilemap.TILED_JSON);
    }

    Level1State.prototype.create = function() {
        this.game.physics.startSystem(Phaser.Physics.ARCADE);

        this.environmentSound = this.game.add.audio('environmentSound');
        this.environmentSound.loop = true;
        this.environmentSound.play();

        //Tile maps
        this.Level1 = this.game.add.tilemap('Level1');
        this.Level1.addTilesetImage('tiled-fases','tiledFases');

        this.bgLayer = this.Level1.createLayer('Bg');
        this.fireLayer = this.Level1.createLayer('Fire');
        this.wallsLayer = this.Level1.createLayer('Walls');
        this.wallsLayer.resizeWorld();

        //Tile maps - collision
        //this.Level1.setCollisionByExclusion([19,20,21,22,23,24], true, this.wallsLayer);
        this.Level1.setCollisionByExclusion([], true, this.wallsLayer);
        this.Level1.setCollisionByExclusion([], true, this.fireLayer);

        // setup initial player properties
        this.player.setup(this);
        this.player.sprite.x = this.game.world.centerX;
        this.player.sprite.y = 70;

        //Movimentacao de camera
        this.game.camera.follow(this.player.sprite);

        //Ratos
        this.ratos = this.game.add.physicsGroup();
        this.Level1.createFromObjects('Enemies', 'rato', 'rato', 8, true, false, this.ratos);
        this.ratos.forEach(function(rato){
            rato.anchor.setTo(0, 0);
            rato.body.immovable = true;
            rato.animations.add('walk', [1,2,3], 6, true);
            rato.animations.play('walk');
            rato.body.velocity.x = 100;
            rato.body.bounce.x = 1;
        });

        // Grupo de fireBullets
        this.fireBullets = this.game.add.physicsGroup();
        this.Level1.createFromObjects('Enemies', 'fireBullet', 'items', 5, true, false, this.fireBullets);

        // Para cada objeto do grupo, vamos executar uma função
        this.fireBullets.forEach(function(fireBullet){
            // body.immovable = true indica que o objeto não é afetado por forças externas
            fireBullet.body.immovable = true;
            // Adicionando animações; o parâmetro true indica que a animação é em loop
            fireBullet.animations.add('go', [10, 11, 10], 3, true);
            fireBullet.animations.play('go');
            fireBullet.body.velocity.x = 100;
            fireBullet.body.bounce.x = 1;
        });

        // Grupo de diamantes
        this.diamonds = this.game.add.physicsGroup();
        this.Level1.createFromObjects('Items', 'diamond', 'items', 5, true, false, this.diamonds);
        // Para cada objeto do grupo, vamos executar uma função
        this.diamonds.forEach(function(diamond){
            // body.immovable = true indica que o objeto não é afetado por forças externas
            diamond.body.immovable = true;
            // Adicionando animações; o parâmetro true indica que a animação é em loop
            diamond.animations.add('spin', [4, 5, 6, 7, 6, 5], 6, true);
            diamond.animations.play('spin');
        });

        // Grupo de inimigos
        this.bats = this.game.add.physicsGroup();

        this.Level1.createFromObjects('Enemies', 'bat', 'enemies', 8, true, false, this.bats);
        this.bats.forEach(function(bat){
            bat.anchor.setTo(0.5, 0.5);
            bat.body.immovable = true;
            bat.animations.add('fly', [8, 9, 10], 6, true);
            bat.animations.play('fly');
            // Velocidade inicial do inimigo
            bat.body.velocity.x = 100;
            // bounce.x=1 indica que, se o objeto tocar num objeto no eixo x, a força deverá
            // ficar no sentido contrário; em outras palavras, o objeto é perfeitamente elástico
            bat.body.bounce.x = 1;
        });

        //Fire effect with phaser particles
        var emitter;
        var pSize = this.game.world.width / 12.5;
        var bmpd = this.game.add.bitmapData(pSize, pSize);
        // Create a radial gradient, yellow-ish on the inside, orange
        // on the outside. Use it to draw a circle that will be used
        // by the FireParticle class.
        var grd = bmpd.ctx.createRadialGradient(
                    pSize / 2, pSize /2, 2,
                    pSize / 2, pSize / 2, pSize * 0.5);

        grd.addColorStop(0, 'rgba(193, 170, 30, 0.6)');
        grd.addColorStop(1, 'rgba(255, 100, 30, 0.1)');
        bmpd.ctx.fillStyle = grd;

        bmpd.ctx.arc(pSize / 2, pSize / 2 , pSize / 2, 0, Math.PI * 2);
        bmpd.ctx.fill();

        this.game.cache.addBitmapData('flame', bmpd);

        // Generate 100 particles
        emitter = this.game.add.emitter(this.game.world.centerX, this.game.world.height, 100);
        emitter.width = 11 * pSize;
        emitter.particleClass = FireParticle;

        // Magic happens here, bleding the colors of each particle
        // generates the bright light effect
        emitter.blendMode = PIXI.blendModes.ADD;
        emitter.makeParticles();
        emitter.minParticleSpeed.set(-15, -160);
        emitter.maxParticleSpeed.set(15, -200);
        emitter.setRotation(0, 0);
        // Make the flames taller than they are wide to simulate the
        // effect of flame tongues
        emitter.setScale(3, 1, 4, 3, 12000, Phaser.Easing.Quintic.Out);
        emitter.gravity = -20;
        emitter.start(false, 3000, 50);
    }

    function FireParticle(game, x, y) {
        Phaser.Particle.call(this, game, x, y, game.cache.getBitmapData('flame'));
    }

    FireParticle.prototype = Object.create(Phaser.Particle.prototype);
    FireParticle.prototype.constructor = FireParticle;

    Level1State.prototype.update = function() {
        this.game.physics.arcade.collide(this.player.sprite, this.fireLayer, this.fireDeath, null, this);

        this.game.physics.arcade.overlap(this.player.sprite, this.bats, this.batCollision, null, this);
        this.game.physics.arcade.collide(this.player.sprite, this.wallsLayer, this.player.groundCollision, null, this.player);
        this.game.physics.arcade.overlap(this.player.sprite, this.diamonds, this.diamondCollect, null, this);
        this.game.physics.arcade.overlap(this.player.sprite, this.fireBullets, this.fireBullet, null, this);
        this.game.physics.arcade.overlap(this.player.sprite, this.ratos, this.ratosCollision, null, this);
        this.game.physics.arcade.collide(this.bats, this.wallsLayer);
        this.game.physics.arcade.collide(this.ratos, this.wallsLayer);
        this.game.physics.arcade.collide(this.fireBullets, this.wallsLayer, this.fireBulletCollideWall, null, this);

        this.player.handleInputs();

        // Para cada morcego, verificar em que sentido ele está indo
        // Se a velocidade for positiva, a escala no eixo X será 1, caso
        // contrário -1
        this.bats.forEach(function(bat){
            if(bat.body.velocity.x != 0) {
                // Math.sign apenas retorna o sinal do parâmetro: positivo retorna 1, negativo -1
                bat.scale.x = 1 * Math.sign(bat.body.velocity.x);
            }
        });

        this.ratos.forEach(function(rato){
            if(rato.body.velocity.x != 0) {
                // Math.sign apenas retorna o sinal do parâmetro: positivo retorna 1, negativo -1
                rato.scale.x = 1 * Math.sign(rato.body.velocity.x);
            }
        });

        this.fireBullets.forEach(function(fireBullet){
            if(fireBullet.body.velocity.x != 0) {
                // Math.sign apenas retorna o sinal do parâmetro: positivo retorna 1, negativo -1
                fireBullet.scale.x = -1;
            }
        });

    }

    Level1State.prototype.diamondCollect = function(player, diamond){
        diamond.kill();
        this.game.state.start('level2');
    }

    Level1State.prototype.fireBulletCollideWall = function(fireBullet){
        fireBullet.kill();
    }

    Level1State.prototype.fireBullet = function(player, fireBullet){
        fireBullet.kill();
        this.player.decreaseLives.apply(this.player);
    }

    Level1State.prototype.batCollision = function(player, bat){
       bat.kill();
       this.player.decreaseLives.apply(this.player);
    }
    Level1State.prototype.ratosCollision = function(player, rato){
       rato.kill();
       this.player.decreaseLives.apply(this.player);
    }

    Level1State.prototype.fireDeath = function(player, fire){
        this.player.decreaseLives.apply(this.player);
    }

    gameManager.addState('level1', Level1State);

})();
<commit_msg>Add bullet collision with ratos level1<commit_after>(function () {
    'use strict';

    var Level1State = function(Level1) {
        // load sprites here
        this.player = gameManager.getSprite('player');

    };

    Level1State.prototype.preload = function() {
        // player
        this.player.preload();
        this.game.load.spritesheet('rato', 'assets/spritesheets/rato-sprite.png', 64, 64, 3);
        this.game.load.image('tiledFases', 'assets/spritesheets/tiled-fases.png');
        this.game.load.spritesheet('items', 'Assets/spritesheets/items.png', 32, 32, 16);
        this.game.load.spritesheet('enemies', 'Assets/spritesheets/enemies.png', 32, 32, 12);
        this.game.load.audio('environmentSound', 'assets/sounds/environment.ogg');

        //Tile maps
        this.game.load.tilemap('Level1','assets/maps/level1.json', null, Phaser.Tilemap.TILED_JSON);
    }

    Level1State.prototype.create = function() {
        this.game.physics.startSystem(Phaser.Physics.ARCADE);

        this.environmentSound = this.game.add.audio('environmentSound');
        this.environmentSound.loop = true;
        this.environmentSound.play();

        //Tile maps
        this.Level1 = this.game.add.tilemap('Level1');
        this.Level1.addTilesetImage('tiled-fases','tiledFases');

        this.bgLayer = this.Level1.createLayer('Bg');
        this.fireLayer = this.Level1.createLayer('Fire');
        this.wallsLayer = this.Level1.createLayer('Walls');
        this.wallsLayer.resizeWorld();

        //Tile maps - collision
        //this.Level1.setCollisionByExclusion([19,20,21,22,23,24], true, this.wallsLayer);
        this.Level1.setCollisionByExclusion([], true, this.wallsLayer);
        this.Level1.setCollisionByExclusion([], true, this.fireLayer);

        // setup initial player properties
        this.player.setup(this);
        this.player.sprite.x = this.game.world.centerX;
        this.player.sprite.y = 70;

        //Movimentacao de camera
        this.game.camera.follow(this.player.sprite);

        //Ratos
        this.ratos = this.game.add.physicsGroup();
        this.Level1.createFromObjects('Enemies', 'rato', 'rato', 8, true, false, this.ratos);
        this.ratos.forEach(function(rato){
            rato.anchor.setTo(0, 0);
            rato.body.immovable = true;
            rato.animations.add('walk', [1,2,3], 6, true);
            rato.animations.play('walk');
            rato.body.velocity.x = 100;
            rato.body.bounce.x = 1;
        });

        // Grupo de fireBullets
        this.fireBullets = this.game.add.physicsGroup();
        this.Level1.createFromObjects('Enemies', 'fireBullet', 'items', 5, true, false, this.fireBullets);

        // Para cada objeto do grupo, vamos executar uma função
        this.fireBullets.forEach(function(fireBullet){
            // body.immovable = true indica que o objeto não é afetado por forças externas
            fireBullet.body.immovable = true;
            // Adicionando animações; o parâmetro true indica que a animação é em loop
            fireBullet.animations.add('go', [10, 11, 10], 3, true);
            fireBullet.animations.play('go');
            fireBullet.body.velocity.x = 100;
            fireBullet.body.bounce.x = 1;
        });

        // Grupo de diamantes
        this.diamonds = this.game.add.physicsGroup();
        this.Level1.createFromObjects('Items', 'diamond', 'items', 5, true, false, this.diamonds);
        // Para cada objeto do grupo, vamos executar uma função
        this.diamonds.forEach(function(diamond){
            // body.immovable = true indica que o objeto não é afetado por forças externas
            diamond.body.immovable = true;
            // Adicionando animações; o parâmetro true indica que a animação é em loop
            diamond.animations.add('spin', [4, 5, 6, 7, 6, 5], 6, true);
            diamond.animations.play('spin');
        });

        // Grupo de inimigos
        this.bats = this.game.add.physicsGroup();

        this.Level1.createFromObjects('Enemies', 'bat', 'enemies', 8, true, false, this.bats);
        this.bats.forEach(function(bat){
            bat.anchor.setTo(0.5, 0.5);
            bat.body.immovable = true;
            bat.animations.add('fly', [8, 9, 10], 6, true);
            bat.animations.play('fly');
            // Velocidade inicial do inimigo
            bat.body.velocity.x = 100;
            // bounce.x=1 indica que, se o objeto tocar num objeto no eixo x, a força deverá
            // ficar no sentido contrário; em outras palavras, o objeto é perfeitamente elástico
            bat.body.bounce.x = 1;
        });

        //Fire effect with phaser particles
        var emitter;
        var pSize = this.game.world.width / 12.5;
        var bmpd = this.game.add.bitmapData(pSize, pSize);
        // Create a radial gradient, yellow-ish on the inside, orange
        // on the outside. Use it to draw a circle that will be used
        // by the FireParticle class.
        var grd = bmpd.ctx.createRadialGradient(
                    pSize / 2, pSize /2, 2,
                    pSize / 2, pSize / 2, pSize * 0.5);

        grd.addColorStop(0, 'rgba(193, 170, 30, 0.6)');
        grd.addColorStop(1, 'rgba(255, 100, 30, 0.1)');
        bmpd.ctx.fillStyle = grd;

        bmpd.ctx.arc(pSize / 2, pSize / 2 , pSize / 2, 0, Math.PI * 2);
        bmpd.ctx.fill();

        this.game.cache.addBitmapData('flame', bmpd);

        // Generate 100 particles
        emitter = this.game.add.emitter(this.game.world.centerX, this.game.world.height, 100);
        emitter.width = 11 * pSize;
        emitter.particleClass = FireParticle;

        // Magic happens here, bleding the colors of each particle
        // generates the bright light effect
        emitter.blendMode = PIXI.blendModes.ADD;
        emitter.makeParticles();
        emitter.minParticleSpeed.set(-15, -160);
        emitter.maxParticleSpeed.set(15, -200);
        emitter.setRotation(0, 0);
        // Make the flames taller than they are wide to simulate the
        // effect of flame tongues
        emitter.setScale(3, 1, 4, 3, 12000, Phaser.Easing.Quintic.Out);
        emitter.gravity = -20;
        emitter.start(false, 3000, 50);
    }

    function FireParticle(game, x, y) {
        Phaser.Particle.call(this, game, x, y, game.cache.getBitmapData('flame'));
    }

    FireParticle.prototype = Object.create(Phaser.Particle.prototype);
    FireParticle.prototype.constructor = FireParticle;

    Level1State.prototype.update = function() {
        this.game.physics.arcade.collide(this.player.sprite, this.fireLayer, this.fireDeath, null, this);

        this.game.physics.arcade.overlap(this.player.sprite, this.bats, this.batCollision, null, this);
        this.game.physics.arcade.collide(this.player.sprite, this.wallsLayer, this.player.groundCollision, null, this.player);
        this.game.physics.arcade.overlap(this.player.sprite, this.diamonds, this.diamondCollect, null, this);
        this.game.physics.arcade.overlap(this.player.sprite, this.fireBullets, this.fireBullet, null, this);
        this.game.physics.arcade.overlap(this.player.sprite, this.ratos, this.ratosCollision, null, this);
        this.game.physics.arcade.collide(this.bats, this.wallsLayer);
        this.game.physics.arcade.collide(this.ratos, this.wallsLayer);
        this.game.physics.arcade.collide(this.fireBullets, this.wallsLayer, this.fireBulletCollideWall, null, this);

        this.game.physics.arcade.overlap(this.ratos, this.player.bullets, this.playerBulletCollision, null, this);

        this.player.handleInputs();

        // Para cada morcego, verificar em que sentido ele está indo
        // Se a velocidade for positiva, a escala no eixo X será 1, caso
        // contrário -1
        this.bats.forEach(function(bat){
            if(bat.body.velocity.x != 0) {
                // Math.sign apenas retorna o sinal do parâmetro: positivo retorna 1, negativo -1
                bat.scale.x = 1 * Math.sign(bat.body.velocity.x);
            }
        });

        this.ratos.forEach(function(rato){
            if(rato.body.velocity.x != 0) {
                // Math.sign apenas retorna o sinal do parâmetro: positivo retorna 1, negativo -1
                rato.scale.x = 1 * Math.sign(rato.body.velocity.x);
            }
        });

        this.fireBullets.forEach(function(fireBullet){
            if(fireBullet.body.velocity.x != 0) {
                // Math.sign apenas retorna o sinal do parâmetro: positivo retorna 1, negativo -1
                fireBullet.scale.x = -1;
            }
        });

    }

    Level1State.prototype.playerBulletCollision = function(ratos, bullet) {
        bullet.kill();
        ratos.kill();
    }

    Level1State.prototype.diamondCollect = function(player, diamond){
        diamond.kill();
        this.game.state.start('level2');
    }

    Level1State.prototype.fireBulletCollideWall = function(fireBullet){
        fireBullet.kill();
    }

    Level1State.prototype.fireBullet = function(player, fireBullet){
        fireBullet.kill();
        this.player.decreaseLives.apply(this.player);
    }

    Level1State.prototype.batCollision = function(player, bat){
       bat.kill();
       this.player.decreaseLives.apply(this.player);
    }
    Level1State.prototype.ratosCollision = function(player, rato){
       rato.kill();
       this.player.decreaseLives.apply(this.player);
    }

    Level1State.prototype.fireDeath = function(player, fire){
        this.player.decreaseLives.apply(this.player);
    }

    gameManager.addState('level1', Level1State);

})();
<|endoftext|>


<commit_before>"use strict";

var assert = require("assert");
var Namespace = require("../namespace.js");
var cedParser = require("../cedParser.js");

describe('namespace', function(){
    describe('._define(names)', function(){
	it('should create a function for each given name', function(){
	    var foo = new Namespace('/foo');
	    foo._define(['bar', 'baz']);
	    assert.equal(typeof foo.bar, 'function');
	    assert.equal(typeof foo.baz, 'function');
	    // The defined functions should return term objects under that namespace
	    assert.deepEqual(foo.bar(1, 2), {name: '/foo#bar', args: [1, 2]});
	});
    });
    describe('._register(name, ctor)', function(){
	var parser = new cedParser.CedParser();
	var foo = new Namespace('/foo', parser);
	foo._register('plus', function(a, b) { return a+b; });
	var res = parser.parse(foo.plus(1, 2).toString());
	assert.equal(res, 3);
    });

    describe('.<concept>(args...)', function(){
	it('should return an object that has a .toString() method', function(){
	    var foo = new Namespace('/foo');
	    foo._define(['bar', 'baz']);
	    assert.equal(foo.bar().toString(), "'/foo#bar'");
	});
    });
});
<commit_msg>_register test case<commit_after>"use strict";

var assert = require("assert");
var Namespace = require("../namespace.js");
var cedParser = require("../cedParser.js");

describe('namespace', function(){
    describe('._define(names)', function(){
	it('should create a function for each given name', function(){
	    var foo = new Namespace('/foo');
	    foo._define(['bar', 'baz']);
	    assert.equal(typeof foo.bar, 'function');
	    assert.equal(typeof foo.baz, 'function');
	    // The defined functions should return term objects under that namespace
	    assert.deepEqual(foo.bar(1, 2), {name: '/foo#bar', args: [1, 2]});
	});
    });
    describe('._register(name, ctor)', function(){
	it('should register a meaning for a term', function(){
	    var parser = new cedParser.CedParser();
	    var foo = new Namespace('/foo', parser);
	    foo._register('plus', function(a, b) { return a+b; });
	    var res = parser.parse(foo.plus(1, 2).toString());
	    assert.equal(res, 3);
	});
    });

    describe('.<concept>(args...)', function(){
	it('should return an object that has a .toString() method', function(){
	    var foo = new Namespace('/foo');
	    foo._define(['bar', 'baz']);
	    assert.equal(foo.bar().toString(), "'/foo#bar'");
	});
    });
});
<|endoftext|>