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

  var app     = this.app
    , _       = require('lodash')
    , debug   = require('debug')('signalk-server:interfaces:ws')
    , Primus  = require('primus')
    , primus  = new Primus(app.server, {
      transformer: 'websockets',
      pathname: '/signalk/stream' })
  ;

  app.connections = {};

  debug('Starting Primus/WS interface');

  primus.on('connection', function(spark) {
    debug(spark.id + " connected with params " + JSON.stringify(spark.query));

    var onChange;
    var event;
    if (spark.query.stream === 'delta') {
      event = 'change:delta';
      onChange = function(data) {
        spark.write(data);
      }
    } else {
      event = 'change';
      onChange = function(data) {
        spark.write(app.signalk.retrieve());
      };
      spark.write(app.signalk.retrieve());//output tree after connect
    }

    app.signalk.on(event, function(data) {
      onChange(data);
    });
    spark.onDisconnect = function() {
      app.signalk.removeListener(event, onChange);
    }

    app.connections[spark.id] = spark;
  });

  primus.on('disconnection', function(spark) {
    spark.onDisconnect();
    debug(spark.id + " disconnected");
  });

}).call(global);<commit_msg>Add subscription protocol Add a way to subscribe to different SignalK messages by specifying stream=subscribe in the query string and then by sending a JSON command message the consumer can specify which SignalK paths it is interested. Current implementatin works only with deltas and ignores context, just considers the paths in the update message. See also https://github.com/SignalK/maptracker/blob/5cd3ba626188563640329253d6792aeee41a46fc/index.html#L158<commit_after>(function() {
  'use strict';

  var app     = this.app
    , _       = require('lodash')
    , debug   = require('debug')('signalk-server:interfaces:ws')
    , Primus  = require('primus')
    , primus  = new Primus(app.server, {
      transformer: 'websockets',
      pathname: '/signalk/stream' })
  ;

  app.connections = {};

  debug('Starting Primus/WS interface');

  primus.on('connection', function(spark) {
    debug(spark.id + " connected with params " + JSON.stringify(spark.query));

    var onChange;
    var event;
    if (spark.query.stream === 'delta') {
      event = 'change:delta';
      onChange = function(data) {
        spark.write(data);
      };
    } else if (spark.query.stream === 'subscribe') {
      debug('stream:subscribe');
      spark.paths = [];
      event = 'change:delta';
      onChange = function (delta) {
        var doSend = delta.updates.some(function (update) {
          return update.values.some(function (value) {
            return spark.paths.some(function (path) {
              return path === value.path;
            });
          });
        });
        if (doSend) {
          spark.write(delta);
        }
      };
      spark.on('data', function (msg) {
        debug("<" + JSON.stringify(msg));
        if (msg.command === 'subscribe') {
          spark.paths = spark.paths.concat(msg.paths);
        }
      });
    } else {
      event = 'change';
      onChange = function(data) {
        spark.write(app.signalk.retrieve());
      };
      spark.write(app.signalk.retrieve());//output tree after connect
    }

    app.signalk.on(event, function(data) {
      onChange(data);
    });
    spark.onDisconnect = function() {
      app.signalk.removeListener(event, onChange);
    }

    app.connections[spark.id] = spark;
  });

  primus.on('disconnection', function(spark) {
    spark.onDisconnect();
    debug(spark.id + " disconnected");
  });

}).call(global);<|endoftext|>


<commit_before>  'use strict';
  var BBPromise = require('bluebird');
  var config = require('config');
  var path = require('path');
  var errors = require('hoist-errors');
  var Context = require('./context');
  var Model = require('./model');
  var logger = require('hoist-logger');
  var Authorization = require('./authorization');
  var fs = require('fs');

  function ConnectorProxy(context, settings, ConnectorType) {
    this.context = context;
    this.settings = settings;
    this.connector = new ConnectorType(settings);
  }

  ConnectorProxy.prototype.get = function () {
    logger.info('in connector-pipeline get');
    if (typeof this.connector.get !== 'function') {
      throw new errors.connector.request.UnsupportedError('get method unsupported');
    }
    return this.connector.get.apply(this.connector, arguments);
  };

  ConnectorProxy.prototype.put = function () {
    logger.info('in connector-pipeline put');
    if (typeof this.connector.put !== 'function') {
      throw new errors.connector.request.UnsupportedError('put method unsupported');
    }
    return this.connector.put.apply(this.connector, arguments);
  };
  ConnectorProxy.prototype.post = function () {
    logger.info('in connector-pipeline post');
    if (typeof this.connector.post !== 'function') {
      throw new errors.connector.request.UnsupportedError('post method unsupported');
    }
    return this.connector.post.apply(this.connector, arguments);
  };
  ConnectorProxy.prototype.delete = function () {
    logger.info('in connector-pipeline delete');
    if (typeof this.connector.delete !== 'function') {
      throw new errors.connector.request.UnsupportedError('delete method unsupported');
    }
    return this.connector.delete.apply(this.connector, arguments);
  };
  ConnectorProxy.prototype.authorize = function (token) {
    if (typeof this.connector.authorize !== 'function') {
      return BBPromise.resolve(null);
    }
    return Model.instance().BouncerToken.findOneAsync({
      key: token
    }).bind(this).then(function (bouncerToken) {
      if (!bouncerToken) {
        throw new errors.connector.InvalidError('the authorization token provided is not valid');
      }
      return this.connector.authorize(new Authorization(bouncerToken));
    }).then(function () {
      return this;
    });
  };
  ConnectorProxy.loadConnector = function (type) {
    return BBPromise.try(function () {
      var connectorsPath = path.resolve(config.get('Hoist.connectors.path'));
      var connectorPath = path.join(connectorsPath, type, config.get('Hoist.connectors.currentDirectoryName'));
      connectorPath = fs.realpathSync(connectorPath);
      return require(connectorPath);
    }).catch(function (err) {
      /* istanbul ignore else */
      if (err.code === 'ENOENT') {
        throw new errors.connector.request.InvalidError(type + ' is not a valid connector type');
      } else {
        throw err;
      }
    });
  };
  ConnectorProxy.getSettings = function (context, key) {
    return Model.instance().ConnectorSetting.findOneAsync({
      key: key,
      environment: context.environment || 'live',
      application: context.application._id
    });
  };

  module.exports = function (key, callback) {
    return Context.instance().get()
      .then(function (context) {
        return ConnectorProxy.getSettings(context, key).then(function (settings) {
          if (!settings) {
            throw new errors.connector.request.InvalidError('no settings found with the key ' + key);
          }
          return ConnectorProxy.loadConnector(settings.connectorType).then(function (Connector) {
            return new ConnectorProxy(context, settings.settings, Connector);
          }).then(function (connectorProxy) {
            /* istanbul ignore next */
            if (context.bucket &&
              context.bucket.meta &&
              context.bucket.meta.authToken &&
              context.bucket.meta.authToken[key]) {
              return connectorProxy.authorize(context.bucket.meta.authToken[key])
                .catch(function (err) {
                  logger.error(err);
                  if (err instanceof errors.connector.InvalidError) {
                    return connectorProxy;
                  } else {
                    throw err;
                  }
                });
            } else if (context.user &&
              context.user.meta &&
              context.user.meta.authToken &&
              context.user.meta.authToken[key]) {
              return connectorProxy.authorize(context.user.meta.authToken[key])
                .catch(function (err) {
                  logger.error(err);
                  if (err instanceof errors.connector.InvalidError) {
                    return connectorProxy;
                  } else {
                    throw err;
                  }
                });
            } else {
              return connectorProxy;
            }
          });
        });
      }).nodeify(callback);
  };
  module.exports.ConnectorProxy = ConnectorProxy;
<commit_msg>InvalidError should be request.InvalidError<commit_after>  'use strict';
  var BBPromise = require('bluebird');
  var config = require('config');
  var path = require('path');
  var errors = require('hoist-errors');
  var Context = require('./context');
  var Model = require('./model');
  var logger = require('hoist-logger');
  var Authorization = require('./authorization');
  var fs = require('fs');

  function ConnectorProxy(context, settings, ConnectorType) {
    this.context = context;
    this.settings = settings;
    this.connector = new ConnectorType(settings);
  }

  ConnectorProxy.prototype.get = function () {
    logger.info('in connector-pipeline get');
    if (typeof this.connector.get !== 'function') {
      throw new errors.connector.request.UnsupportedError('get method unsupported');
    }
    return this.connector.get.apply(this.connector, arguments);
  };

  ConnectorProxy.prototype.put = function () {
    logger.info('in connector-pipeline put');
    if (typeof this.connector.put !== 'function') {
      throw new errors.connector.request.UnsupportedError('put method unsupported');
    }
    return this.connector.put.apply(this.connector, arguments);
  };
  ConnectorProxy.prototype.post = function () {
    logger.info('in connector-pipeline post');
    if (typeof this.connector.post !== 'function') {
      throw new errors.connector.request.UnsupportedError('post method unsupported');
    }
    return this.connector.post.apply(this.connector, arguments);
  };
  ConnectorProxy.prototype.delete = function () {
    logger.info('in connector-pipeline delete');
    if (typeof this.connector.delete !== 'function') {
      throw new errors.connector.request.UnsupportedError('delete method unsupported');
    }
    return this.connector.delete.apply(this.connector, arguments);
  };
  ConnectorProxy.prototype.authorize = function (token) {
    if (typeof this.connector.authorize !== 'function') {
      return BBPromise.resolve(null);
    }
    return Model.instance().BouncerToken.findOneAsync({
      key: token
    }).bind(this).then(function (bouncerToken) {
      if (!bouncerToken) {
        throw new errors.connector.request.InvalidError('the authorization token provided is not valid');
      }
      return this.connector.authorize(new Authorization(bouncerToken));
    }).then(function () {
      return this;
    });
  };
  ConnectorProxy.loadConnector = function (type) {
    return BBPromise.try(function () {
      var connectorsPath = path.resolve(config.get('Hoist.connectors.path'));
      var connectorPath = path.join(connectorsPath, type, config.get('Hoist.connectors.currentDirectoryName'));
      connectorPath = fs.realpathSync(connectorPath);
      return require(connectorPath);
    }).catch(function (err) {
      /* istanbul ignore else */
      if (err.code === 'ENOENT') {
        throw new errors.connector.request.InvalidError(type + ' is not a valid connector type');
      } else {
        throw err;
      }
    });
  };
  ConnectorProxy.getSettings = function (context, key) {
    return Model.instance().ConnectorSetting.findOneAsync({
      key: key,
      environment: context.environment || 'live',
      application: context.application._id
    });
  };

  module.exports = function (key, callback) {
    return Context.instance().get()
      .then(function (context) {
        return ConnectorProxy.getSettings(context, key).then(function (settings) {
          if (!settings) {
            throw new errors.connector.request.InvalidError('no settings found with the key ' + key);
          }
          return ConnectorProxy.loadConnector(settings.connectorType).then(function (Connector) {
            return new ConnectorProxy(context, settings.settings, Connector);
          }).then(function (connectorProxy) {
            /* istanbul ignore next */
            if (context.bucket &&
              context.bucket.meta &&
              context.bucket.meta.authToken &&
              context.bucket.meta.authToken[key]) {
              return connectorProxy.authorize(context.bucket.meta.authToken[key])
                .catch(function (err) {
                  logger.error(err);
                  if (err instanceof errors.connector.request.InvalidError) {
                    return connectorProxy;
                  } else {
                    throw err;
                  }
                });
            } else if (context.user &&
              context.user.meta &&
              context.user.meta.authToken &&
              context.user.meta.authToken[key]) {
              return connectorProxy.authorize(context.user.meta.authToken[key])
                .catch(function (err) {
                  logger.error(err);
                  if (err instanceof errors.connector.request.InvalidError) {
                    return connectorProxy;
                  } else {
                    throw err;
                  }
                });
            } else {
              return connectorProxy;
            }
          });
        });
      }).nodeify(callback);
  };
  module.exports.ConnectorProxy = ConnectorProxy;
<|endoftext|>


<commit_before>/**
 * Copyright 2015-present OpenCB
 *
 * 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.
 */

import {LitElement, html} from "lit";
import UtilsNew from "../../../core/utilsNew.js";

export default class CustomWelcome extends LitElement {

    createRenderRoot() {
        return this;
    }

    static get properties() {
        return {
            app: {
                type: Object
            },
            opencgaSession: {
                type: Object
            },
            version: {
                type: String
            },
            config: {
                type: Object
            }
        };
    }

    onChangeApp(e) {
        this.dispatchEvent(new CustomEvent("changeApp", {
            detail: {
                id: e.currentTarget.dataset.id,
                e: e,
            },
            bubbles: true,
            composed: true,
        }));
    }

    isWelcomeSuite() {
        return !this.app || this.app?.id === "suite";
    }

    getWelcomePageConfig() {
        return this.isWelcomeSuite() ? this.config.welcomePage : this.app.welcomePage;
    }

    renderApplicationsOrTools() {
        const session = this.opencgaSession;

        if (this.isWelcomeSuite()) {
            // Render applications list
            const visibleApps = (this.config.apps || []).filter(app => {
                return UtilsNew.isAppVisible(app, session);
            });

            return html`
                ${visibleApps.map(item => html`

                            ${item.name}

                `)}
            `;
        } else {
            // Render tools list
            const featuredTools = [];
            (this.app.menu || []).forEach(item => {
                if (UtilsNew.isAppVisible(item, session)) {
                    // Check if the primary menu item is featured
                    if (item.featured) {
                        featuredTools.push(item);
                    }

                    // Check for submenu items
                    (item.submenu || []).forEach(subitem => {
                        if (UtilsNew.isAppVisible(subitem) && subitem.featured) {
                            featuredTools.push(subitem);
                        }
                    });
                }
            });

            return html`
                ${featuredTools.map(item => {
                    const itemLink = `${item.id}/${session?.project ? `${session.project.id}/${session.study.id}`: ""}`;
                    return html`

                                ${item.name}

                    `;
                })}
            `;
        }
    }

    render() {
        const welcomePage = this.getWelcomePageConfig();

        return html`

                ${welcomePage?.logo ? html`

                ` : null}

                ${welcomePage?.title ? html`

                        ${welcomePage.title}

                `: null}

                ${welcomePage?.subtitle ? html`

                        ${welcomePage.subtitle}

                ` : null}

                ${welcomePage?.content ? html`

                        ${UtilsNew.renderHTML(welcomePage.content)}

                ` : null}

                    ${this.renderApplicationsOrTools()}

                    ${(welcomePage?.links || []).map(link => html`
                        ${link.title}
                    `)}

        `;
    }

}

customElements.define("custom-welcome", CustomWelcome);
<commit_msg>wc: implement new featured tools section (#227)<commit_after>/**
 * Copyright 2015-present OpenCB
 *
 * 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.
 */

import {LitElement, html} from "lit";
import UtilsNew from "../../../core/utilsNew.js";

export default class CustomWelcome extends LitElement {

    createRenderRoot() {
        return this;
    }

    static get properties() {
        return {
            app: {
                type: Object
            },
            opencgaSession: {
                type: Object
            },
            version: {
                type: String
            },
            config: {
                type: Object
            }
        };
    }

    onChangeApp(e) {
        this.dispatchEvent(new CustomEvent("changeApp", {
            detail: {
                id: e.currentTarget.dataset.id,
                e: e,
            },
            bubbles: true,
            composed: true,
        }));
    }

    isWelcomeSuite() {
        return !this.app || this.app?.id === "suite";
    }

    getWelcomePageConfig() {
        return this.isWelcomeSuite() ? this.config.welcomePage : this.app.welcomePage;
    }

    renderApplicationsOrTools() {
        const session = this.opencgaSession;

        if (this.isWelcomeSuite()) {
            // Render applications list
            const visibleApps = (this.config.apps || []).filter(app => {
                return UtilsNew.isAppVisible(app, session);
            });

            return html`

                ${visibleApps.map(item => html`

                            ${item.name}

                `)}

            `;
        } else {
            // Render tools list
            const featuredTools = [];
            (this.app.menu || []).forEach(item => {
                if (UtilsNew.isAppVisible(item, session)) {
                    // Check if the primary menu item is featured
                    if (item.featured) {
                        featuredTools.push(item);
                    }

                    // Check for submenu items
                    (item.submenu || []).forEach(subitem => {
                        if (UtilsNew.isAppVisible(subitem) && subitem.featured) {
                            featuredTools.push(subitem);
                        }
                    });
                }
            });

            return html`

                ${featuredTools.map(item => {
                    const itemLink = `${item.id}/${session?.project ? `${session.project.id}/${session.study.id}`: ""}`;
                    return html`

                                        ${item.name}

                                    ${item.description ? UtilsNew.renderHTML(item.description) : ""}

                                        Enter

                    `;
                })}

            `;
        }
    }

    render() {
        const welcomePage = this.getWelcomePageConfig();

        return html`

                ${welcomePage?.logo ? html`

                ` : null}

                ${welcomePage?.title ? html`

                        ${welcomePage.title}

                `: null}

                ${welcomePage?.subtitle ? html`

                        ${welcomePage.subtitle}

                ` : null}

                ${welcomePage?.content ? html`

                        ${UtilsNew.renderHTML(welcomePage.content)}

                ` : null}

                ${this.renderApplicationsOrTools()}

                    ${(welcomePage?.links || []).map(link => html`
                        ${link.title}
                    `)}

        `;
    }

}

customElements.define("custom-welcome", CustomWelcome);
<|endoftext|>


<commit_before>import macro from 'vtk.js/Sources/macro';

import vtkActor from 'vtk.js/Sources/Rendering/Core/Actor';
import vtkBoundingBox from 'vtk.js/Sources/Common/DataModel/BoundingBox';
import vtkMapper from 'vtk.js/Sources/Rendering/Core/Mapper';
import vtkMath from 'vtk.js/Sources/Common/Core/Math';
import vtkProp3D from 'vtk.js/Sources/Rendering/Core/Prop3D';
import vtkProperty from 'vtk.js/Sources/Rendering/Core/Property';
import vtkResliceCursorPolyDataAlgorithm from 'vtk.js/Sources/Interaction/Widgets/ResliceCursor/ResliceCursorPolyDataAlgorithm';

// ----------------------------------------------------------------------------
// vtkResliceCursorActor methods
// ----------------------------------------------------------------------------

function vtkResliceCursorActor(publicAPI, model) {
  // Set our className
  model.classHierarchy.push('vtkResliceCursorActor');

  const superClass = Object.assign({}, publicAPI);

  publicAPI.getActors = () => {
    if (model.cursorAlgorithm.getResliceCursor()) {
      publicAPI.updateViewProps();
    }
    return [...model.cursorCenterlineActor];
  };

  publicAPI.getNestedProps = () => publicAPI.getActors();

  publicAPI.updateViewProps = () => {
    if (!model.cursorAlgorithm.getResliceCursor()) {
      return;
    }
    model.cursorAlgorithm.update();

    const axisNormal = model.cursorAlgorithm.getReslicePlaneNormal();
    const axis1 = model.cursorAlgorithm.getPlaneAxis1();
    const axis2 = model.cursorAlgorithm.getPlaneAxis2();

    model.cursorCenterlineMapper[axis1].setInputData(
      model.cursorAlgorithm.getOutputData(0)
    );
    model.cursorCenterlineMapper[axis2].setInputData(
      model.cursorAlgorithm.getOutputData(1)
    );

    model.cursorCenterlineActor[axis1].setVisibility(model.visibility);
    model.cursorCenterlineActor[axis2].setVisibility(model.visibility);
    model.cursorCenterlineActor[axisNormal].setVisibility(0);

    model.cursorCenterlineActor[axis1]
      .getProperty()
      .setEdgeVisibility(model.visibility);
    model.cursorCenterlineActor[axis2]
      .getProperty()
      .setEdgeVisibility(model.visibility);
    model.cursorCenterlineActor[axisNormal].getProperty().setEdgeVisibility(0);
  };

  publicAPI.getBounds = () => {
    vtkMath.uninitializeBounds(model.bounds);
    publicAPI.updateViewProps();

    const boundingBox = vtkBoundingBox.newInstance();

    let bounds = [];
    for (let i = 0; i < 3; i++) {
      if (
        model.cursorCenterlineActor[i].getVisibility() &&
        model.cursorCenterlineActor[i].getUseBounds()
      ) {
        bounds = model.cursorCenterlineActor[i].getBounds();
        boundingBox.addBounds(
          bounds[0],
          bounds[1],
          bounds[2],
          bounds[3],
          bounds[4],
          bounds[5]
        );
      }
    }

    model.bounds = boundingBox.getBounds();

    return model.bounds;
  };

  publicAPI.getMTime = () => {
    let mTime = superClass.getMTime();

    if (model.cursorAlgorithm) {
      const time = model.cursorAlgorithm.getMTime();

      if (time > mTime) {
        mTime = time;
      }
    }

    return mTime;
  };

  publicAPI.getCenterlineProperty = (i) => model.centerlineProperty[i];
  publicAPI.getCenterlineActor = (i) => model.cursorCenterlineActor[i];

  publicAPI.setUserMatrix = (matrix) => {
    model.cursorCenterlineActor[0].setUserMatrix(matrix);
    model.cursorCenterlineActor[1].setUserMatrix(matrix);
    model.cursorCenterlineActor[2].setUserMatrix(matrix);

    superClass.setUserMatrix(matrix);
  };

  //----------------------------------------------------------------------------
  // Public API methods
  //----------------------------------------------------------------------------
}

// ----------------------------------------------------------------------------
// Object factory
// ----------------------------------------------------------------------------

const DEFAULT_VALUES = {};

// ----------------------------------------------------------------------------

export function extend(publicAPI, model, initialValues = {}) {
  Object.assign(model, DEFAULT_VALUES, initialValues);

  vtkProp3D.extend(publicAPI, model, initialValues);

  model.cursorAlgorithm = vtkResliceCursorPolyDataAlgorithm.newInstance();
  model.cursorCenterlineMapper = [];
  model.cursorCenterlineActor = [];
  model.centerlineProperty = [];

  for (let i = 0; i < 3; i++) {
    model.cursorCenterlineMapper[i] = vtkMapper.newInstance();
    model.cursorCenterlineMapper[i].setScalarVisibility(false);

    model.cursorCenterlineActor[i] = vtkActor.newInstance();
    model.cursorCenterlineActor[i].setMapper(model.cursorCenterlineMapper[i]);

    model.centerlineProperty[i] = vtkProperty.newInstance();
    model.cursorCenterlineActor[i].setProperty(model.centerlineProperty[i]);
  }

  model.centerlineProperty[0].setColor(1, 0, 0);
  model.centerlineProperty[1].setColor(0, 1, 0);
  model.centerlineProperty[2].setColor(0, 0, 1);

  model.centerlineProperty[0].setEdgeColor(1, 0, 0);
  model.centerlineProperty[1].setEdgeColor(0, 1, 0);
  model.centerlineProperty[2].setEdgeColor(0, 0, 1);

  model.centerlineProperty[0].setEdgeVisibility(1);
  model.centerlineProperty[1].setEdgeVisibility(1);
  model.centerlineProperty[2].setEdgeVisibility(1);

  macro.get(publicAPI, model, ['cursorAlgorithm']);

  // Object methods
  vtkResliceCursorActor(publicAPI, model);
}

// ----------------------------------------------------------------------------

export const newInstance = macro.newInstance(extend, 'vtkResliceCursorActor');

// ----------------------------------------------------------------------------

export default { newInstance, extend };
<commit_msg>fix(ResliceCursor): Fix randomly hidden axes<commit_after>import macro from 'vtk.js/Sources/macro';

import vtkActor from 'vtk.js/Sources/Rendering/Core/Actor';
import vtkBoundingBox from 'vtk.js/Sources/Common/DataModel/BoundingBox';
import vtkMapper from 'vtk.js/Sources/Rendering/Core/Mapper';
import vtkMath from 'vtk.js/Sources/Common/Core/Math';
import vtkProp3D from 'vtk.js/Sources/Rendering/Core/Prop3D';
import vtkProperty from 'vtk.js/Sources/Rendering/Core/Property';
import vtkResliceCursorPolyDataAlgorithm from 'vtk.js/Sources/Interaction/Widgets/ResliceCursor/ResliceCursorPolyDataAlgorithm';

// ----------------------------------------------------------------------------
// vtkResliceCursorActor methods
// ----------------------------------------------------------------------------

function vtkResliceCursorActor(publicAPI, model) {
  // Set our className
  model.classHierarchy.push('vtkResliceCursorActor');

  const superClass = Object.assign({}, publicAPI);

  publicAPI.getActors = () => {
    if (model.cursorAlgorithm.getResliceCursor()) {
      publicAPI.updateViewProps();
    }
    return [...model.cursorCenterlineActor];
  };

  publicAPI.getNestedProps = () => publicAPI.getActors();

  publicAPI.updateViewProps = () => {
    if (!model.cursorAlgorithm.getResliceCursor()) {
      return;
    }
    model.cursorAlgorithm.update();

    const axisNormal = model.cursorAlgorithm.getReslicePlaneNormal();
    const axis1 = model.cursorAlgorithm.getPlaneAxis1();
    const axis2 = model.cursorAlgorithm.getPlaneAxis2();

    model.cursorCenterlineMapper[axis1].setInputData(
      model.cursorAlgorithm.getOutputData(0)
    );
    model.cursorCenterlineMapper[axis2].setInputData(
      model.cursorAlgorithm.getOutputData(1)
    );

    model.cursorCenterlineActor[axis1].setVisibility(model.visibility);
    model.cursorCenterlineActor[axis2].setVisibility(model.visibility);
    model.cursorCenterlineActor[axisNormal].setVisibility(0);

    model.cursorCenterlineActor[axis1]
      .getProperty()
      .setEdgeVisibility(model.visibility);
    model.cursorCenterlineActor[axis2]
      .getProperty()
      .setEdgeVisibility(model.visibility);
    model.cursorCenterlineActor[axisNormal].getProperty().setEdgeVisibility(0);
  };

  publicAPI.getBounds = () => {
    vtkMath.uninitializeBounds(model.bounds);
    publicAPI.updateViewProps();

    const boundingBox = vtkBoundingBox.newInstance();

    let bounds = [];
    for (let i = 0; i < 3; i++) {
      if (
        model.cursorCenterlineActor[i].getVisibility() &&
        model.cursorCenterlineActor[i].getUseBounds()
      ) {
        bounds = model.cursorCenterlineActor[i].getBounds();
        boundingBox.addBounds(
          bounds[0],
          bounds[1],
          bounds[2],
          bounds[3],
          bounds[4],
          bounds[5]
        );
      }
    }

    model.bounds = boundingBox.getBounds();

    return model.bounds;
  };

  publicAPI.getMTime = () => {
    let mTime = superClass.getMTime();

    if (model.cursorAlgorithm) {
      const time = model.cursorAlgorithm.getMTime();

      if (time > mTime) {
        mTime = time;
      }
    }

    return mTime;
  };

  publicAPI.getCenterlineProperty = (i) => model.centerlineProperty[i];
  publicAPI.getCenterlineActor = (i) => model.cursorCenterlineActor[i];

  publicAPI.setUserMatrix = (matrix) => {
    model.cursorCenterlineActor[0].setUserMatrix(matrix);
    model.cursorCenterlineActor[1].setUserMatrix(matrix);
    model.cursorCenterlineActor[2].setUserMatrix(matrix);

    superClass.setUserMatrix(matrix);
  };

  //----------------------------------------------------------------------------
  // Public API methods
  //----------------------------------------------------------------------------
}

// ----------------------------------------------------------------------------
// Object factory
// ----------------------------------------------------------------------------

const DEFAULT_VALUES = {};

// ----------------------------------------------------------------------------

export function extend(publicAPI, model, initialValues = {}) {
  Object.assign(model, DEFAULT_VALUES, initialValues);

  vtkProp3D.extend(publicAPI, model, initialValues);

  model.cursorAlgorithm = vtkResliceCursorPolyDataAlgorithm.newInstance();
  model.cursorCenterlineMapper = [];
  model.cursorCenterlineActor = [];
  model.centerlineProperty = [];

  for (let i = 0; i < 3; i++) {
    model.cursorCenterlineMapper[i] = vtkMapper.newInstance();
    model.cursorCenterlineMapper[i].setScalarVisibility(false);
    model.cursorCenterlineMapper[i].setResolveCoincidentTopology(true);
    model.cursorCenterlineMapper[
      i
    ].setResolveCoincidentTopologyPolygonOffsetParameters(-1, -1);

    model.cursorCenterlineActor[i] = vtkActor.newInstance();
    model.cursorCenterlineActor[i].setMapper(model.cursorCenterlineMapper[i]);

    model.centerlineProperty[i] = vtkProperty.newInstance();
    model.cursorCenterlineActor[i].setProperty(model.centerlineProperty[i]);
  }

  model.centerlineProperty[0].setColor(1, 0, 0);
  model.centerlineProperty[1].setColor(0, 1, 0);
  model.centerlineProperty[2].setColor(0, 0, 1);

  model.centerlineProperty[0].setEdgeColor(1, 0, 0);
  model.centerlineProperty[1].setEdgeColor(0, 1, 0);
  model.centerlineProperty[2].setEdgeColor(0, 0, 1);

  model.centerlineProperty[0].setEdgeVisibility(1);
  model.centerlineProperty[1].setEdgeVisibility(1);
  model.centerlineProperty[2].setEdgeVisibility(1);

  macro.get(publicAPI, model, ['cursorAlgorithm']);

  // Object methods
  vtkResliceCursorActor(publicAPI, model);
}

// ----------------------------------------------------------------------------

export const newInstance = macro.newInstance(extend, 'vtkResliceCursorActor');

// ----------------------------------------------------------------------------

export default { newInstance, extend };
<|endoftext|>


<commit_before>/// <reference path="../typings/jquery/jquery.d.ts"/>
/// <reference path="../typings/angularjs/angular.d.ts"/>
angular.module('MyModule', ['ngRoute']);

angular.module('MyModule').config(function ($routeProvider) {
   $routeProvider.when("/main", {
      controller: "maincontroller",
      templateUrl: "app/views/main.html"
   });
$.get();
   $routeProvider.when("/collisions", {
      controller: "collisioncontroller",
      templateUrl: "app/views/shapes.html"
   });

   $routeProvider.when("/velocity", {
       controller: "velocitycontroller",
       templateUrl: "app/views/shapes.html"
   });

   $routeProvider.when("/ballpit", {
       controller: "ballpitcontroller",
       templateUrl: "app/views/ballpit.html"
   });

   $routeProvider.when("/facing", {
       controller: "facingcontroller",
       templateUrl: "app/views/facing.html"
   });

   $routeProvider.when("/follow", {
       controller: "followcontroller",
       templateUrl: "app/views/follow.html"
   });

   $routeProvider.when("/flock", {
       controller: "flockcontroller",
       templateUrl: "app/views/flock.html"
   });

   $routeProvider.otherwise({ redirectTo: "/ballpit" });
});<commit_msg>Removed unused jquery hint reference.<commit_after>/// <reference path="../typings/angularjs/angular.d.ts"/>
angular.module('MyModule', ['ngRoute']);

angular.module('MyModule').config(function ($routeProvider) {
   $routeProvider.when("/main", {
      controller: "maincontroller",
      templateUrl: "app/views/main.html"
   });

   $routeProvider.when("/collisions", {
      controller: "collisioncontroller",
      templateUrl: "app/views/shapes.html"
   });

   $routeProvider.when("/velocity", {
       controller: "velocitycontroller",
       templateUrl: "app/views/shapes.html"
   });

   $routeProvider.when("/ballpit", {
       controller: "ballpitcontroller",
       templateUrl: "app/views/ballpit.html"
   });

   $routeProvider.when("/facing", {
       controller: "facingcontroller",
       templateUrl: "app/views/facing.html"
   });

   $routeProvider.when("/follow", {
       controller: "followcontroller",
       templateUrl: "app/views/follow.html"
   });

   $routeProvider.when("/flock", {
       controller: "flockcontroller",
       templateUrl: "app/views/flock.html"
   });

   $routeProvider.otherwise({ redirectTo: "/ballpit" });
});<|endoftext|>


<commit_before>'use strict';

const _ = require('lodash');
const P = require('bluebird');
const EventEmitter = require('events').EventEmitter;
const joi = require('joi');
const Stream = require('stream').Stream;
const QueryResult = require('./query-result').QueryResult;
const FieldConfigurator = require('./field-configurator').FieldConfigurator;

var $ = require('highland');

const SCHEMA = joi.object({
    preHandlers: joi.array().items(joi.func()).default([]),
    postHandlers: joi.array().items(joi.func()).default([]),
    throughHandlers: joi.array().items(joi.alternatives([joi.func(), joi.object().type(Stream)])).default([]),
    errorHandlers: joi.array().items(joi.func()).default([]),
    handler: joi.func().required(),
    payload: joi.any(),
    user: joi.any(),
    fields: joi.object(),
    limit: joi.number().integer().default(-1),
    language: joi.string(),
    options: joi.object().default({}),
    dataTypes: joi.object().default({}),
    params: joi.object().default({}).empty(null),
    plugins: joi.array().items(joi.func()).default([]),
    listeners: joi.array().items(joi.array().items(joi.string(), joi.func())).default([])
});

/**
 * @extends EventEmitter
 */
class Query extends EventEmitter {
    constructor() {
        super();

        // properties declared here for jsdoc purposes
        this.limit = -1;
        this.preHandlers = this.postHandlers = this.throughHandlers = this.errorHandlers = [];
        this.options = {};
        this.params = {};
    }

    /**
     * Configures the query from a defn descriptor
     * @param {{}} defn the definition descriptor
     * @return {Query}
     */
    configure(defn) {
        defn = joi.attempt(defn, SCHEMA);
         _.assign(this, _.omit(defn, 'plugins', 'listeners'));
        defn.plugins.forEach(p => p(this));
        defn.listeners.forEach(l => this.on(l[0], l[1]));
        return this;
    }

    /**
     * Adds a through stream handler
     * @param through
     * @return {Query}
     */
    through(through) {
        this.throughHandlers = this.throughHandlers.concat(through);
        return this;
    }

    /**
     * Adds a pre handler
     * @param handler
     * @return {Query}
     */
    pre(handler) {
        this.preHandlers = this.preHandlers.concat(handler);
        return this;
    }

    /**
     * Adds a post handler
     * @param handler
     * @return {Query}
     */
    post(handler) {
        this.postHandlers = this.postHandlers.concat(handler);
        return this;
    }

    /**
     * Adds an error handler
     * @param handler
     * @return {Query}
     */
    error (handler) {
        this.errorHandlers = this.errorHandlers.concat(handler);
        return this;
    }

    /**
     * Sets the valid types
     * @param types
     */
    types(types) {
        this.dataTypes = types;
        return this;
    }

    /**
     * Registers a plugin with the query
     * @param {function} plugin the plugin registration function
     * @return {Query}
     */
    use(plugin) {
        plugin(this);

        return this;
    }

    /**
     * Configures a field
     * @param {string} field the field name
     * @param {function=} callback an optional callback function for accessing the field configurator
     * @example
     * // with a callback
     * qr
     *  .field('location', fc => fc.type('geo_point').label('Coordinates'))
     *  .field('firstName', fc => fc.label('First Name'));
     *  .field('lastName', fc => fc.label('Last Name'));
     *
     *  // without a callback
     *  qr.field('location').type('geo_point');
     *  qr.field('firstName').label('First Name');
     *  qr.field('lastName').label('Last Name');
     *
     * @return {FieldConfigurator|Query}
     */
    field(field, callback) {
        const fc = new FieldConfigurator(this.fields, field);
        if (callback) {
            callback(fc);
            return this;
        }

        return fc;
    }

    /**
     * Assigns default configuration to fields
     * @param defaults
     * @return {Query}
     */
    fieldDefaults(defaults) {
        _.defaults(this.fields, defaults);
        return this;
    }

    /**
     * Creates a promise chain for invoking interceptors, ignoring any return value
     * @param {[]} interceptors the interceptor functions
     * @return {Function}
     * @private
     */
    _tapChain(interceptors) {
        return function(value) {
            return interceptors.reduce(function (p, interceptor) {
                return p.tap(interceptor);
            }, P.resolve(value));
        };
    }

    /**
     * Invokes the query's handler function and is responsible for initializing the result.
     * @param {function(Query, function)} handler the handler function
     * @return {Promise.<QueryResult>}
     * @private
     */
    _invokeHandler(handler) {
        const self = this;

        // short circuit the handler if already cancelled
        if (this.cancelled) return P.resolve(new QueryResult(this));

        return new P(function (resolve, reject) {

            // the reply function passed to the query handler
            const reply = _.once(function (err, data) {

                // errors thrown in the handler will have same effect
                if (err && err instanceof Error) return reject(err);

                // init the result
                const qr = new QueryResult(self, data || err);

                // give the handler a moment to configure field metadata before processing the results
                setImmediate(() => resolve(qr));

                // return the configuration shim
                return qr.shim();
            });

            self.on('cancel', reply);
            handler(self, reply);
        });
    }

    /**
     * Emits a 'queryError' event, taps the collection of error
     * handlers, then re-throws the error to propagate it up
     * @param err
     * @return {Promise.}
     * @private
     */
    _handleError (err) {
        this.emit('queryError', err);
        return this._tapChain(this.errorHandlers)(err)
            .finally(() => {
                throw err;
            });
    }

    _setResult (result) {
        this.result = result;
    }

    /**
     * Runs the query with the supplied parameters, returning a promise to a QueryResult.
     * An Error while invoking the handler causing a rejection will cause the collection of
     * error handlers to be tapped before the error is re-thrown.
     * @param {*} params runtime query params
     * @return {Promise.<QueryResult>}
     */
    execute(params) {
        this.params = _.assign({}, this.params, params);

        if (this._promise) return this._promise;

        if (!this.handler) return P.reject('No handler defined');

        return this._promise = P.bind(this)
            .tap(() => this.emit('execute'))
            .tap(() => this._tapChain(this.preHandlers)(this))
            .then(() => this._invokeHandler(this.handler)
                .catch(err => this._handleError(err)))
            .tap(r => this._setResult(r))
            .tap(r => this._tapChain(this.postHandlers)(r))
            .tap(r => this.emit('result', r));
    }

    /**
     * Cancels a running query. NOTE: this method is overridden to call QueryResult.cancel() once the reply() callback
     * is called.
     *
     * Handlers should detect early termination of queries in two ways:
     *
     *

     *     function handler(query, reply) {
     *          let conn = getConnection();
     *
     *          // a cancellation event on query indicates that the query is still running (we haven't called reply yet)
     *          query.on('cancel', () => conn.end())
     *
     *          conn.query(query.payload)
     *              .then(function(result) {
     *                  // an end event on the reply is emitted when the results are consumed or the client cancels
     *                  // the query result
     *                  reply(result.stream()).on('end', () => conn.end());
     *              });
     *     }
     *

     */
    cancel() {
        this.cancelled = true;
        this.emit('cancel');
        if (this.result) this.result.cancel();
        return this;
    }

    /**
     * Emits a progress event
     * @param progress
     * @return {boolean|*}
     */
    progress(progress) {
        return this.emit('progress', progress);
    }

    /**
     * Executes the query, synchronously returning a stream bound (eventually) to the result's stream
     * @return {Stream}
     */
    stream() {
        return $.sequence(this.execute().then(r => r.stream()));
    }

    /**
     * Executes the query returning a promise that resolves to an array containing all results
     * @return {Promise.<{}[]>}
     */
    toArray() {
        return this.execute().then(r => r.toArray());
    }
}

exports.Query = Query;<commit_msg>added function query.option(name, val)<commit_after>'use strict';

const _ = require('lodash');
const P = require('bluebird');
const EventEmitter = require('events').EventEmitter;
const joi = require('joi');
const Stream = require('stream').Stream;
const QueryResult = require('./query-result').QueryResult;
const FieldConfigurator = require('./field-configurator').FieldConfigurator;

var $ = require('highland');

const SCHEMA = joi.object({
    preHandlers: joi.array().items(joi.func()).default([]),
    postHandlers: joi.array().items(joi.func()).default([]),
    throughHandlers: joi.array().items(joi.alternatives([joi.func(), joi.object().type(Stream)])).default([]),
    errorHandlers: joi.array().items(joi.func()).default([]),
    handler: joi.func().required(),
    payload: joi.any(),
    user: joi.any(),
    fields: joi.object(),
    limit: joi.number().integer().default(-1),
    language: joi.string(),
    options: joi.object().default({}),
    dataTypes: joi.object().default({}),
    params: joi.object().default({}).empty(null),
    plugins: joi.array().items(joi.func()).default([]),
    listeners: joi.array().items(joi.array().items(joi.string(), joi.func())).default([])
});

/**
 * @extends EventEmitter
 */
class Query extends EventEmitter {
    constructor() {
        super();

        // properties declared here for jsdoc purposes
        this.limit = -1;
        this.preHandlers = this.postHandlers = this.throughHandlers = this.errorHandlers = [];
        this.options = {};
        this.params = {};
    }

    /**
     * Configures the query from a defn descriptor
     * @param {{}} defn the definition descriptor
     * @return {Query}
     */
    configure(defn) {
        defn = joi.attempt(defn, SCHEMA);
        _.assign(this, _.omit(defn, 'plugins', 'listeners'));
        defn.plugins.forEach(p => p(this));
        defn.listeners.forEach(l => this.on(l[0], l[1]));
        return this;
    }

    option(name, value) {
        this.options = _.set(this.options, [name], value);
        return this;
    }

    /**
     * Adds a through stream handler
     * @param through
     * @return {Query}
     */
    through(through) {
        this.throughHandlers = this.throughHandlers.concat(through);
        return this;
    }

    /**
     * Adds a pre handler
     * @param handler
     * @return {Query}
     */
    pre(handler) {
        this.preHandlers = this.preHandlers.concat(handler);
        return this;
    }

    /**
     * Adds a post handler
     * @param handler
     * @return {Query}
     */
    post(handler) {
        this.postHandlers = this.postHandlers.concat(handler);
        return this;
    }

    /**
     * Adds an error handler
     * @param handler
     * @return {Query}
     */
    error (handler) {
        this.errorHandlers = this.errorHandlers.concat(handler);
        return this;
    }

    /**
     * Sets the valid types
     * @param types
     */
    types(types) {
        this.dataTypes = types;
        return this;
    }

    /**
     * Registers a plugin with the query
     * @param {function} plugin the plugin registration function
     * @return {Query}
     */
    use(plugin) {
        plugin(this);

        return this;
    }

    /**
     * Configures a field
     * @param {string} field the field name
     * @param {function=} callback an optional callback function for accessing the field configurator
     * @example
     * // with a callback
     * qr
     *  .field('location', fc => fc.type('geo_point').label('Coordinates'))
     *  .field('firstName', fc => fc.label('First Name'));
     *  .field('lastName', fc => fc.label('Last Name'));
     *
     *  // without a callback
     *  qr.field('location').type('geo_point');
     *  qr.field('firstName').label('First Name');
     *  qr.field('lastName').label('Last Name');
     *
     * @return {FieldConfigurator|Query}
     */
    field(field, callback) {
        const fc = new FieldConfigurator(this.fields, field);
        if (callback) {
            callback(fc);
            return this;
        }

        return fc;
    }

    /**
     * Assigns default configuration to fields
     * @param defaults
     * @return {Query}
     */
    fieldDefaults(defaults) {
        _.defaults(this.fields, defaults);
        return this;
    }

    /**
     * Creates a promise chain for invoking interceptors, ignoring any return value
     * @param {[]} interceptors the interceptor functions
     * @return {Function}
     * @private
     */
    _tapChain(interceptors) {
        return function(value) {
            return interceptors.reduce(function (p, interceptor) {
                return p.tap(interceptor);
            }, P.resolve(value));
        };
    }

    /**
     * Invokes the query's handler function and is responsible for initializing the result.
     * @param {function(Query, function)} handler the handler function
     * @return {Promise.<QueryResult>}
     * @private
     */
    _invokeHandler(handler) {
        const self = this;

        // short circuit the handler if already cancelled
        if (this.cancelled) return P.resolve(new QueryResult(this));

        return new P(function (resolve, reject) {

            // the reply function passed to the query handler
            const reply = _.once(function (err, data) {

                // errors thrown in the handler will have same effect
                if (err && err instanceof Error) return reject(err);

                // init the result
                const qr = new QueryResult(self, data || err);

                // give the handler a moment to configure field metadata before processing the results
                setImmediate(() => resolve(qr));

                // return the configuration shim
                return qr.shim();
            });

            self.on('cancel', reply);
            handler(self, reply);
        });
    }

    /**
     * Emits a 'queryError' event, taps the collection of error
     * handlers, then re-throws the error to propagate it up
     * @param err
     * @return {Promise.}
     * @private
     */
    _handleError (err) {
        this.emit('queryError', err);
        return this._tapChain(this.errorHandlers)(err)
            .finally(() => {
                throw err;
            });
    }

    _setResult (result) {
        this.result = result;
    }

    /**
     * Runs the query with the supplied parameters, returning a promise to a QueryResult.
     * An Error while invoking the handler causing a rejection will cause the collection of
     * error handlers to be tapped before the error is re-thrown.
     * @param {*} params runtime query params
     * @return {Promise.<QueryResult>}
     */
    execute(params) {
        this.params = _.assign({}, this.params, params);

        if (this._promise) return this._promise;

        if (!this.handler) return P.reject('No handler defined');

        return this._promise = P.bind(this)
            .tap(() => this.emit('execute'))
            .tap(() => this._tapChain(this.preHandlers)(this))
            .then(() => this._invokeHandler(this.handler)
                .catch(err => this._handleError(err)))
            .tap(r => this._setResult(r))
            .tap(r => this._tapChain(this.postHandlers)(r))
            .tap(r => this.emit('result', r));
    }

    /**
     * Cancels a running query. NOTE: this method is overridden to call QueryResult.cancel() once the reply() callback
     * is called.
     *
     * Handlers should detect early termination of queries in two ways:
     *
     *

     *     function handler(query, reply) {
     *          let conn = getConnection();
     *
     *          // a cancellation event on query indicates that the query is still running (we haven't called reply yet)
     *          query.on('cancel', () => conn.end())
     *
     *          conn.query(query.payload)
     *              .then(function(result) {
     *                  // an end event on the reply is emitted when the results are consumed or the client cancels
     *                  // the query result
     *                  reply(result.stream()).on('end', () => conn.end());
     *              });
     *     }
     *

     */
    cancel() {
        this.cancelled = true;
        this.emit('cancel');
        if (this.result) this.result.cancel();
        return this;
    }

    /**
     * Emits a progress event
     * @param progress
     * @return {boolean|*}
     */
    progress(progress) {
        return this.emit('progress', progress);
    }

    /**
     * Executes the query, synchronously returning a stream bound (eventually) to the result's stream
     * @return {Stream}
     */
    stream() {
        return $.sequence(this.execute().then(r => r.stream()));
    }

    /**
     * Executes the query returning a promise that resolves to an array containing all results
     * @return {Promise.<{}[]>}
     */
    toArray() {
        return this.execute().then(r => r.toArray());
    }
}

exports.Query = Query;<|endoftext|>


<commit_before>#!/usr/bin/env node

require("../lib/main").run();

<commit_msg>Added edit option<commit_after>#!/usr/bin/env node

var should_edit = false;
if (process.argv[1] && process.argv[1] === "edit") {
  should_edit = true;
}

if (process.argv[2] && process.argv[2] === "edit") {
  should_edit = true;
}

require("../lib/main").run(should_edit);

<|endoftext|>


<commit_before>// Dependencies
var querystring = require('querystring'),
    format = require('./utils/format');

// Expose
exports.createQuery = function(){
   return new Query();
}

var Query = function(){
   this.parameters = [];
   this.query = '';
}

Query.prototype.defType = function(type){
   var self = this;
   var parameter = 'defType=' + type;
   this.parameters.push(parameter);
   return self;
}

Query.prototype.dismax = function(){
   var self = this;
   var parameter = 'defType=dismax' ;
   this.parameters.push(parameter);
   return self;
}

Query.prototype.q = function(q){
   var self = this;
   var parameter ='q=';
   if ( typeof(q) === 'string' ){
      parameter += encodeURIComponent(q);
   }else{
      parameter += querystring.stringify(q, '%20',':');
   }
   this.parameters.push(parameter);
   return self;
}

Query.prototype.start = function(start){
   var self = this;
   var parameter = 'start=' + start ;
   this.parameters.push(parameter);
   return self;
}

// Maximun number of rows returned in the result

Query.prototype.rows = function(rows){
   var self = this;
   var parameter = 'rows=' + rows ;
   this.parameters.push(parameter);
   return self;
}

/**
 * Query Fields
 *
 * List of fields and the "boosts" to associate with each of them when building DisjunctionMaxQueries from the user's query.
 *
 */

Query.prototype.qf = function(obj){
   var self = this;
   var parameter = 'qf=' ;
   parameter += querystring.stringify(obj, '%20' , '^');
   this.parameters.push(parameter);
   return self;
}

/**
 * Minimum 'Should' Match
 *
 */

Query.prototype.mm = function(minimum){
   var self = this;
   var parameter = 'mm=' + minimum;
   this.parameters.push(parameter);
   return self;
}

/**
 * Phrase Fields
 *
 * Once the list of matching documents has been identified using the "fq" and "qf" params, the "pf" param can be used to "boost" the score of documents in cases where all of the terms
 * in the "q" param appear in close proximity.
 *
 */

Query.prototype.pf = function(obj){
   var self = this;
   var parameter = 'pf=' ;
   parameter += querystring.stringify(obj, '%20' , '^');
   this.parameters.push(parameter);
   return self;
}

/**
 * Boost Query
 *
 * A raw query string (in the SolrQuerySyntax) that will be included with the user's query to influence the score. If this is a BooleanQuery
 * with a default boost (1.0f) then the individual clauses will be added directly to the main query. Otherwise, the query will be included as is.
 *
 */
Query.prototype.bq = function(obj){
   var self = this;
   var parameter = 'bq=' ;
   parameter += querystring.stringify(obj, '%20' , '^');
   this.parameters.push(parameter);
   return self;
}

/**
 * Used to sort a result in descending or ascending order depending of one or more fields.
 *
 * @param {Object} obj - An object is expected with the following structure { fieldName : 'asc|desc' , ... }
 *
 */

Query.prototype.sort = function(obj){
 var self = this;
 var parameter = 'sort=';
 parameter += querystring.stringify(obj, ',' , '%20');
 this.parameters.push(parameter);
 return self;
}

/**
 * Used to specify a query that can be used to restrict the super set of documents that can be returned, without influencing score. Correspond to the fq parameter for Solr.
 *
 * @param {Array|Object} params -  An object or an array are expected as following { field : 'name', start : '10' , end : '*|30' } [ {field : 'name' , start : '10' end : '*|30' } , ... ]
 *
 */

Query.prototype.rangeFilter = function(params){
   var self = this;
   params = format.dateISOify(params);
   var parameter = 'fq=';
   if(Array.isArray(params)){
      var filters = params.map(function(param){
         var key = param.field;
         var filter = {};
         filter[key] = '[' + encodeURIComponent(param.start) + '%20TO%20' + encodeURIComponent(param.end) + ']';
         return format.stringify(filter, '',':');
      });
      parameter += filters.join('%20');
   }else{
      var key = params.field;
      var filter = {};
      filter[key] = '[' + encodeURIComponent(params.start) + '%20TO%20' + encodeURIComponent(params.end) + ']';
      parameter += format.stringify(filter, '',':');
   }
   this.parameters.push(parameter);
   return self;
}

Query.prototype.matchFilter = function(field,value){
   var self = this;
   value = format.dateISOify(value);
   var parameter = 'fq=';
   parameter += field + ':' + encodeURIComponent(value);
   this.parameters.push(parameter);
   return self;
}

/**
 * Used to specify a set of fields to return, limiting the amount of information in the response. Correspond to the fl parameter for Solr.
 *
 * @param {string|Array} fields - one field name or an array of fields
 */

Query.prototype.restrict = function(fields){
   var self = this;
   var parameter = 'fl=';
   if(typeof(fields) === 'string'){
      parameter += fields;
   }else{
      parameter += fields.join(',');
   }
   this.parameters.push(parameter);
   return self;
}

Query.prototype.timeout = function(time){
   var self = this;
   var parameter = 'timeAllowed=' + time;
   this.parameters.push(parameter);
   return self;
}

/**
 * Shorcut command to groupBy a specified field
 * @param {String} - field name
 *
 * @return {Query}
 */

Query.prototype.groupBy = function(field){
   var self = this;
   this.group({
      'field': field
   });
   return self;
}

/**
 * Field Collapsing and Result Grouping.
 * @param {Object} options - properties considered
 *    on : [Boolean] ,
 *    field : [String],
 *    limit : [Number], // Default to 1, that's is a solr default value.
 *    offset : [Number],
 *    sort : [sortspec], // Default "score desc", solr default value
 *    format : [grouped|simple]
 *    main : [Boolean]
 *    ngroups : [Boolean], // Default false, solr default value
 *    truncate : [Boolean], // Default false, solr default value
 *    cache : [0-100] // Default is 0, solr default value
 *
 * @return {Query}
 */

Query.prototype.group = function(options){
   var self = this;
   if(options.on === false){
      this.parameters.push('group=false');
   }else if(options.on){
      this.parameters.push('group=true');
   }
   if( options.field ){
      this.parameters.push('group.field=' + options.field);
   }
   if( options.limit ){
      this.parameters.push('group.limit=' + options.limit);
   }
   if( options.offset ){
      this.parameters.push('group.offset=' + options.offset);
   }
   if( options.sort ){
      this.parameters.push('group.sort=' + encodeURIComponent(options.sort));
   }
   if( options.format ){
      this.parameters.push('group.format=' + encodeURIComponent(options.format));
   }
   if( options.main ){
      this.parameters.push('group.main=' + options.main);
   }
   if( options.ngroups ){
      this.parameters.push('group.ngroups=' + options.ngroups);
   }
   if( options.truncate ){
      this.parameters.push('group.truncate=' + options.truncate);
   }
   if( options.cache ){
      this.parameters.push('group.cache.percent=' + options.cache);
   }
   return self;
}
//TODO
Query.prototype.ps = function(){}

Query.prototype.qs = function(){}

Query.prototype.tie = function(){}

Query.prototype.bf = function(){}

Query.prototype.build = function(){
   return this.parameters.join('&');
}
<commit_msg>FIX: `on` options of `group` is by default equals to true.<commit_after>// Dependencies
var querystring = require('querystring'),
    format = require('./utils/format');

// Expose
exports.createQuery = function(){
   return new Query();
}

var Query = function(){
   this.parameters = [];
   this.query = '';
}

Query.prototype.defType = function(type){
   var self = this;
   var parameter = 'defType=' + type;
   this.parameters.push(parameter);
   return self;
}

Query.prototype.dismax = function(){
   var self = this;
   var parameter = 'defType=dismax' ;
   this.parameters.push(parameter);
   return self;
}

Query.prototype.q = function(q){
   var self = this;
   var parameter ='q=';
   if ( typeof(q) === 'string' ){
      parameter += encodeURIComponent(q);
   }else{
      parameter += querystring.stringify(q, '%20',':');
   }
   this.parameters.push(parameter);
   return self;
}

Query.prototype.start = function(start){
   var self = this;
   var parameter = 'start=' + start ;
   this.parameters.push(parameter);
   return self;
}

// Maximun number of rows returned in the result

Query.prototype.rows = function(rows){
   var self = this;
   var parameter = 'rows=' + rows ;
   this.parameters.push(parameter);
   return self;
}

/**
 * Query Fields
 *
 * List of fields and the "boosts" to associate with each of them when building DisjunctionMaxQueries from the user's query.
 *
 */

Query.prototype.qf = function(obj){
   var self = this;
   var parameter = 'qf=' ;
   parameter += querystring.stringify(obj, '%20' , '^');
   this.parameters.push(parameter);
   return self;
}

/**
 * Minimum 'Should' Match
 *
 */

Query.prototype.mm = function(minimum){
   var self = this;
   var parameter = 'mm=' + minimum;
   this.parameters.push(parameter);
   return self;
}

/**
 * Phrase Fields
 *
 * Once the list of matching documents has been identified using the "fq" and "qf" params, the "pf" param can be used to "boost" the score of documents in cases where all of the terms
 * in the "q" param appear in close proximity.
 *
 */

Query.prototype.pf = function(obj){
   var self = this;
   var parameter = 'pf=' ;
   parameter += querystring.stringify(obj, '%20' , '^');
   this.parameters.push(parameter);
   return self;
}

/**
 * Boost Query
 *
 * A raw query string (in the SolrQuerySyntax) that will be included with the user's query to influence the score. If this is a BooleanQuery
 * with a default boost (1.0f) then the individual clauses will be added directly to the main query. Otherwise, the query will be included as is.
 *
 */
Query.prototype.bq = function(obj){
   var self = this;
   var parameter = 'bq=' ;
   parameter += querystring.stringify(obj, '%20' , '^');
   this.parameters.push(parameter);
   return self;
}

/**
 * Used to sort a result in descending or ascending order depending of one or more fields.
 *
 * @param {Object} obj - An object is expected with the following structure { fieldName : 'asc|desc' , ... }
 *
 */

Query.prototype.sort = function(obj){
 var self = this;
 var parameter = 'sort=';
 parameter += querystring.stringify(obj, ',' , '%20');
 this.parameters.push(parameter);
 return self;
}

/**
 * Used to specify a query that can be used to restrict the super set of documents that can be returned, without influencing score. Correspond to the fq parameter for Solr.
 *
 * @param {Array|Object} params -  An object or an array are expected as following { field : 'name', start : '10' , end : '*|30' } [ {field : 'name' , start : '10' end : '*|30' } , ... ]
 *
 */

Query.prototype.rangeFilter = function(params){
   var self = this;
   params = format.dateISOify(params);
   var parameter = 'fq=';
   if(Array.isArray(params)){
      var filters = params.map(function(param){
         var key = param.field;
         var filter = {};
         filter[key] = '[' + encodeURIComponent(param.start) + '%20TO%20' + encodeURIComponent(param.end) + ']';
         return format.stringify(filter, '',':');
      });
      parameter += filters.join('%20');
   }else{
      var key = params.field;
      var filter = {};
      filter[key] = '[' + encodeURIComponent(params.start) + '%20TO%20' + encodeURIComponent(params.end) + ']';
      parameter += format.stringify(filter, '',':');
   }
   this.parameters.push(parameter);
   return self;
}

Query.prototype.matchFilter = function(field,value){
   var self = this;
   value = format.dateISOify(value);
   var parameter = 'fq=';
   parameter += field + ':' + encodeURIComponent(value);
   this.parameters.push(parameter);
   return self;
}

/**
 * Used to specify a set of fields to return, limiting the amount of information in the response. Correspond to the fl parameter for Solr.
 *
 * @param {string|Array} fields - one field name or an array of fields
 */

Query.prototype.restrict = function(fields){
   var self = this;
   var parameter = 'fl=';
   if(typeof(fields) === 'string'){
      parameter += fields;
   }else{
      parameter += fields.join(',');
   }
   this.parameters.push(parameter);
   return self;
}

Query.prototype.timeout = function(time){
   var self = this;
   var parameter = 'timeAllowed=' + time;
   this.parameters.push(parameter);
   return self;
}

/**
 * Shorcut command to groupBy a specified field
 * @param {String} - field name
 *
 * @return {Query}
 */

Query.prototype.groupBy = function(field){
   var self = this;
   this.group({
      'field': field
   });
   return self;
}

/**
 * Field Collapsing and Result Grouping.
 * @param {Object} options - properties considered
 *    on : [Boolean] , // Default true
 *    field : [String],
 *    limit : [Number], // Default to 1, that's is a solr default value.
 *    offset : [Number],
 *    sort : [sortspec], // Default "score desc", solr default value
 *    format : [grouped|simple]
 *    main : [Boolean]
 *    ngroups : [Boolean], // Default false, solr default value
 *    truncate : [Boolean], // Default false, solr default value
 *    cache : [0-100] // Default is 0, solr default value
 *
 * @return {Query}
 */

Query.prototype.group = function(options){
   var self = this;
   if(options.on === false){
      this.parameters.push('group=false');
   }else{
      this.parameters.push('group=true');
   }
   if( options.field ){
      this.parameters.push('group.field=' + options.field);
   }
   if( options.limit ){
      this.parameters.push('group.limit=' + options.limit);
   }
   if( options.offset ){
      this.parameters.push('group.offset=' + options.offset);
   }
   if( options.sort ){
      this.parameters.push('group.sort=' + encodeURIComponent(options.sort));
   }
   if( options.format ){
      this.parameters.push('group.format=' + encodeURIComponent(options.format));
   }
   if( options.main ){
      this.parameters.push('group.main=' + options.main);
   }
   if( options.ngroups ){
      this.parameters.push('group.ngroups=' + options.ngroups);
   }
   if( options.truncate ){
      this.parameters.push('group.truncate=' + options.truncate);
   }
   if( options.cache ){
      this.parameters.push('group.cache.percent=' + options.cache);
   }
   return self;
}
//TODO
Query.prototype.ps = function(){}

Query.prototype.qs = function(){}

Query.prototype.tie = function(){}

Query.prototype.bf = function(){}

Query.prototype.build = function(){
   return this.parameters.join('&');
}
<|endoftext|>


<commit_before>var CardCreatorApp = angular.module('CardCreatorApp', ['printService', 'ui.router']);

CardCreatorApp.config(function($stateProvider, $urlRouterProvider, $locationProvider) {

	// $locationProvider.html5Mode(true);

	// ================================================
	// Define all routes
	// ================================================

	$urlRouterProvider.otherwise('/');

	$stateProvider
		.state('uploader', {
			url: '/',
			templateUrl: 'views/uploader.html'
		})
		.state('print', {
			url: '/print',
			templateUrl: 'views/print.html'
		})
});

CardCreatorApp.controller('uploaderCtrl', ['$scope', 'Print', function($scope, Print) {

	var deckJSON = {};

	$scope.printDeck = function() {
		Print.storeDeck(deckJSON);
	}

	$scope.fileName = 'No file';

	var papaParseFile = function(file) {
		Papa.parse(file, {
			header: true,
			dynamicTyping: true,
			complete: function(results) {
				var deckList = [];
				for (var index = 0; index < results.data.length; index++) {
					var card = results.data[index];
					card.Effect = card.Effect.replace(RegExp("//","g"), "\n");
					for (var i = 0; i < card.Quantity; i++) {
						deckList.push(card);
					};
				};

				deckJSON = JSON.stringify(deckList);
				deckJSON = JSON.parse(deckJSON);

				console.log("================================================");
				console.log("CSV TO JSON RESULTS");
				console.log("================================================");
				console.log(deckJSON);
				console.log("================================================");
			}
		});
	}

	document.getElementById("deck-file-pseudo").addEventListener("click", function(event) {
		document.getElementById("deck-file").click();
	});

	document.getElementById("deck-file").addEventListener("change", function(event) {
		$scope.fileName = event.target.files[0].name;
		$scope.$apply();

		papaParseFile(event.target.files[0]);
	});

}]);

CardCreatorApp.controller('printCtrl', ['$scope', 'Print', function($scope, Print) {

	vm = this;
	vm.deck = Print.loadDeck();

	$scope.hasValue = function(field) {
		return field.toString().length > 0;
	}

}]);

<commit_msg>Finally patch regex newline error<commit_after>var CardCreatorApp = angular.module('CardCreatorApp', ['printService', 'ui.router']);

CardCreatorApp.config(function($stateProvider, $urlRouterProvider, $locationProvider) {

	// $locationProvider.html5Mode(true);

	// ================================================
	// Define all routes
	// ================================================

	$urlRouterProvider.otherwise('/');

	$stateProvider
		.state('uploader', {
			url: '/',
			templateUrl: 'views/uploader.html'
		})
		.state('print', {
			url: '/print',
			templateUrl: 'views/print.html'
		})
});

CardCreatorApp.controller('uploaderCtrl', ['$scope', 'Print', function($scope, Print) {

	var deckJSON = {};

	$scope.printDeck = function() {
		Print.storeDeck(deckJSON);
	}

	$scope.fileName = 'No file';

	var papaParseFile = function(file) {
		Papa.parse(file, {
			header: true,
			dynamicTyping: true,
			complete: function(results) {
				var deckList = [];
				for (var index = 0; index < results.data.length - 1 ; index++) {
					var card = results.data[index];
					card.Effect = card.Effect.replace(RegExp("//","g"), "\n");
					for (var i = 0; i < card.Quantity; i++) {
						deckList.push(card);
					};
				};

				deckJSON = JSON.stringify(deckList);
				deckJSON = JSON.parse(deckJSON);

				console.log("================================================");
				console.log("CSV TO JSON RESULTS");
				console.log("================================================");
				console.log(deckJSON);
				console.log("================================================");
			}
		});
	}

	document.getElementById("deck-file-pseudo").addEventListener("click", function(event) {
		document.getElementById("deck-file").click();
	});

	document.getElementById("deck-file").addEventListener("change", function(event) {
		$scope.fileName = event.target.files[0].name;
		$scope.$apply();

		papaParseFile(event.target.files[0]);
	});

}]);

CardCreatorApp.controller('printCtrl', ['$scope', 'Print', function($scope, Print) {

	vm = this;
	vm.deck = Print.loadDeck();

	$scope.hasValue = function(field) {
		return field.toString().length > 0;
	}

}]);

<|endoftext|>


<commit_before>/**
 * Constant that identifies the map canvas.
 * @type {string}
 */
var MAP_ELEMENT = "map_canvas";

var channel = "mobile";

/**
 * Callback that is called when the location couldn't be retrieved.
 * @param error
 */
function errorLocationCallback (error) {
	// error callback
	userLocation.moveToLocation(this.DEFAULT_LAT, this.DEFAULT_LONG);
    alert('There was an error obtaining your position. Message: ' + error.message);
	//TODO: show hint that location couldn't be retrieved
}

function addMarker (location) {
    // calculate latitude and longitude
    var latitude = parseFloat(location.latitude._int) * Math.pow(10, location.latitude._exp);
    var longitude = parseFloat(location.longitude._int) * Math.pow(10, location.longitude._exp);

    var entryCount = location.entries.length;
    if (entryCount > 9) {
        entryCount = 0;
    }
    // if not already on the map, display marker
    if (!userLocation.markers.hasOwnProperty(location.id)) {
        var marker = new google.maps.Marker({
            map: userLocation.map,
            position: new google.maps.LatLng(latitude, longitude),
            title: location.label,
            icon: "/static/stadtgedaechtnis/img/marker_" + entryCount + ".png",
            animation: google.maps.Animation.DROP
        });

        location.marker = marker;
        createInfobox(location, 0);

        userLocation.markers[location.id] = location;
    }
}

/**
 * Creates an infobox for this location.
 * @param location
 * @param index index of entry for this infobox
 */
function createInfobox(location, index) {
    var infoBoxContent = "
" + location.entries[index].abstract + "
";

    var infoBox = new google.maps.InfoWindow({
        content: infoBoxContent,
        maxWidth: 225
    })

    location.infobox = infoBox;
    google.maps.event.clearListeners(location.marker, 'click');
    google.maps.event.addListener(location.marker, 'click', function () {
        openEntry(location, index, false);
    });
    google.maps.event.addListener(infoBox, 'closeclick', closeEntry);
}

/**
 * Reloads a new infobox and displays the content of
 * the next story.
 * @param location
 * @param index
 */
function reloadInfobox(location, index) {
    if (index >= location.entries.length) {
        index = 0;
    } else if (index < 0) {
        index = location.entries.length - 1;
    }

    createInfobox(location, index);
    openEntry(location, index, true);
}

/**
 * Loads the complete entry for the given location and entry index.
 * @param location
 * @param index
 */
function loadAdditionalEntry(location, index) {
    $("article#entry-more").html("");
    $("img#load-more").show();
    $.get("../stadtgedaechtnis/entry/" + location.entries[index].id + "/", function (data) {
        $("article#entry-more").html(data);
        $("img#load-more").hide();
    });
}

/**
 * Opens an infobox for the first entry in this
 * location and pops up the pop up with the
 * correct heading and image. Handles click
 * events on the marker.
 * @param entry
 */
function openEntry(location, index, reload) {
    if (!reload) {
        var entryList = "";
        for (var i = 0; i < location.entries.length; i++) {
            entryList += "

" + location.entries[i].title + "

";
        }
        $("div.article-heading div.entry-list ul").html(entryList);
        $("section#article-section h3#single-heading").text(location.entries[index].title);
    }
    if (location.entries[index].image !== undefined) {
        $("section#article-section img#entry-first").show().attr({
            src: location.entries[index].image,
            alt: location.entries[index].alt
        });
    } else {
        $("section#article-section img#entry-first").hide();
    }

    loadAdditionalEntry(location, index);

    if (userLocation.currentInfobox === null) {
        var footer = $("section#article-section");
        var footerHeading = $("section#article-section h3");
        footer.css("padding", "0.8rem");

        if ($(window).width() < 768) {
            // mobile
            channel = "mobile";
            footer.transition({height: footerHeight}, 200, "ease");
            footerHeading.swipe("enable");
            $("main").transition({paddingBottom: footerHeight, marginBottom: "-" + footerHeight}, 200, "ease", function() {
                    $("section#article-section div.entry-list").unslider();
            });
        } else {
            // desktop
            footerHeading.swipe("disable");
            channel = "desktop";
            footer.css({
                height: "100%",
                width: "0%"
            });
            $("section.max_map").transition({width: "80%"}, 200, "ease");
            footer.transition({width: "20%"}, 200, "ease", function() {
                    $("section#article-section div.entry-list").unslider();
            });
            footer.css("overflow-y", "auto");
        }
    } else {
        userLocation.currentInfobox.close();
    }

    userLocation.currentInfobox = location.infobox;
    location.infobox.open(userLocation.map, location.marker);

    if (location.entries.length > 1) {
        $("section#article-section h3#single-heading").hide();
        $("div.article-heading").show();
        $("div.article-heading img#previous").unbind("click").click(function() {
            $("section#article-section div.entry-list").data("unslider").next();
            reloadInfobox(location, index + 1);
        });
        $("div.article-heading img#next").unbind("click").click(function() {
            $("section#article-section div.entry-list").data("unslider").prev();
            reloadInfobox(location, index - 1);
        })

    } else {
        $("div.article-heading").hide();
        $("section#article-section h3#single-heading").show();
    }
}

function closeEntry() {
    var footer = $("section#article-section");

    if (channel === "mobile") {
        // mobile
        footer.transition({height: 0}, 200, "ease");
        $("main").transition({paddingBottom: "0px", marginBottom: "0px"}, 200, "ease" , function() {
            footer.css("padding", "0rem");
        });
    } else {
        // desktop
        footer.transition({width: "0%"}, 200, "ease", function() {
            footer.css({
                height: "100%",
                padding: "0rem",
                width: "auto"
            });
        });
        $("section.max_map").transition({width: "100%"}, 200, "ease");
        footer.css("overflow-y", "hidden");
    }

    if (userLocation.currentInfobox !== null) {
        userLocation.currentInfobox.close();
        userLocation.currentInfobox = null;
    }
}

/**
 * Callback that is called when the viewport changed
 */
function searchForEntries () {
    // calculate bounds to search for
    var bounds = userLocation.map.getBounds()
    var max_lat = bounds.getNorthEast().lat().toFixed(10)
    var max_lon = bounds.getNorthEast().lng().toFixed(10)
    var min_lat = bounds.getSouthWest().lat().toFixed(10)
    var min_lon = bounds.getSouthWest().lng().toFixed(10)
    // get nearby locations
    $.getJSON("../stadtgedaechtnis/services/get-nearby-locations/" + min_lat + "/" + max_lat + "/" + min_lon + "/" + max_lon + "/", function (data) {
        $.each(data, function (index, value) {
            addMarker(value);
        })
    });
}

/**
 * Location object to enable/disable tracking the location and to retrieve the current or fallback location.
 * @param trackLocation
 * @constructor
 */
function Location() {
	this.DEFAULT_LAT = 50.258;
	this.DEFAULT_LONG = 10.965;
	this.DEFAULT_LOCATION = new google.maps.LatLng(50.258, 10.965);
	this.positionMarker = null;
    this.markers = {}
    this.currentInfobox = null;
}

/**
 * Move the map to the current location or the fallback
 * @returns {google.maps.LatLng|*}
 */
Location.prototype.moveToCurrentLocationOrFallback = function () {
	if (Modernizr.geolocation) {
	    google.maps.event.addListenerOnce(this.positionMarker, 'position_changed', function() {
            this.map.setCenter(this.getPosition());
            this.map.fitBounds(this.getBounds());
            searchForEntries();
        });
	} else {
		this.moveToLocation(this.DEFAULT_LAT, this.DEFAULT_LONG);
		//TODO: show hint that browser doesn't support location
	}
};

/**
 * Moves the map to the given location
 * @param lat
 * @param long
 */
Location.prototype.moveToLocation = function(position) {
	if (this.map) {
		this.map.panTo(position);
        searchForEntries();
	}
}

var userLocation = new Location();

/**
 * Global map Options
 * @type {{center: google.maps.LatLng, zoom: number, mapTypeId: *, disableDefaultUI: boolean, zoomControl: boolean}}
 */
var mapOptions = {
	center: userLocation.DEFAULT_LOCATION,
	zoom: 17,
    mapTypeControl: true,
	mapTypeId: google.maps.MapTypeId.SATELLITE,
	disableDefaultUI: true,
	zoomControl: true
};

/**
 * Initializes the map
 */
function initialize_Map() {
	userLocation.map = new google.maps.Map(document.getElementById(MAP_ELEMENT),
		mapOptions);
    userLocation.positionMarker = new GeolocationMarker(userLocation.map)
    userLocation.moveToCurrentLocationOrFallback();
    google.maps.event.addListener(userLocation.positionMarker, 'geolocation_error', errorLocationCallback);
    google.maps.event.addListener(userLocation.map, 'idle', searchForEntries)
    google.maps.event.addListener(userLocation.map, 'click', closeEntry);
}<commit_msg>Desktop: Entryslider fixed width<commit_after>/**
 * Constant that identifies the map canvas.
 * @type {string}
 */
var MAP_ELEMENT = "map_canvas";

var channel = "mobile";

/**
 * Callback that is called when the location couldn't be retrieved.
 * @param error
 */
function errorLocationCallback (error) {
	// error callback
	userLocation.moveToLocation(this.DEFAULT_LAT, this.DEFAULT_LONG);
    alert('There was an error obtaining your position. Message: ' + error.message);
	//TODO: show hint that location couldn't be retrieved
}

function addMarker (location) {
    // calculate latitude and longitude
    var latitude = parseFloat(location.latitude._int) * Math.pow(10, location.latitude._exp);
    var longitude = parseFloat(location.longitude._int) * Math.pow(10, location.longitude._exp);

    var entryCount = location.entries.length;
    if (entryCount > 9) {
        entryCount = 0;
    }
    // if not already on the map, display marker
    if (!userLocation.markers.hasOwnProperty(location.id)) {
        var marker = new google.maps.Marker({
            map: userLocation.map,
            position: new google.maps.LatLng(latitude, longitude),
            title: location.label,
            icon: "/static/stadtgedaechtnis/img/marker_" + entryCount + ".png",
            animation: google.maps.Animation.DROP
        });

        location.marker = marker;
        createInfobox(location, 0);

        userLocation.markers[location.id] = location;
    }
}

/**
 * Creates an infobox for this location.
 * @param location
 * @param index index of entry for this infobox
 */
function createInfobox(location, index) {
    var infoBoxContent = "
" + location.entries[index].abstract + "
";

    var infoBox = new google.maps.InfoWindow({
        content: infoBoxContent,
        maxWidth: 225
    })

    location.infobox = infoBox;
    google.maps.event.clearListeners(location.marker, 'click');
    google.maps.event.addListener(location.marker, 'click', function () {
        openEntry(location, index, false);
    });
    google.maps.event.addListener(infoBox, 'closeclick', closeEntry);
}

/**
 * Reloads a new infobox and displays the content of
 * the next story.
 * @param location
 * @param index
 */
function reloadInfobox(location, index) {
    if (index >= location.entries.length) {
        index = 0;
    } else if (index < 0) {
        index = location.entries.length - 1;
    }

    createInfobox(location, index);
    openEntry(location, index, true);
}

/**
 * Loads the complete entry for the given location and entry index.
 * @param location
 * @param index
 */
function loadAdditionalEntry(location, index) {
    $("article#entry-more").html("");
    $("img#load-more").show();
    $.get("../stadtgedaechtnis/entry/" + location.entries[index].id + "/", function (data) {
        $("article#entry-more").html(data);
        $("img#load-more").hide();
    });
}

/**
 * Opens an infobox for the first entry in this
 * location and pops up the pop up with the
 * correct heading and image. Handles click
 * events on the marker.
 * @param entry
 */
function openEntry(location, index, reload) {
    if (!reload) {
        var entryList = "";
        for (var i = 0; i < location.entries.length; i++) {
            entryList += "

" + location.entries[i].title + "

";
        }
        $("div.article-heading div.entry-list ul").html(entryList);
        $("section#article-section h3#single-heading").text(location.entries[index].title);
    }
    if (location.entries[index].image !== undefined) {
        $("section#article-section img#entry-first").show().attr({
            src: location.entries[index].image,
            alt: location.entries[index].alt
        });
    } else {
        $("section#article-section img#entry-first").hide();
    }

    loadAdditionalEntry(location, index);

    if (userLocation.currentInfobox === null) {
        var footer = $("section#article-section");
        var footerHeading = $("section#article-section h3");
        footer.css("padding", "0.8rem");

        if ($(window).width() < 768) {
            // mobile
            channel = "mobile";
            footer.transition({height: footerHeight}, 200, "ease");
            footerHeading.swipe("enable");
            $("main").transition({paddingBottom: footerHeight, marginBottom: "-" + footerHeight}, 200, "ease", function() {
                    $("section#article-section div.entry-list").unslider();
            });
        } else {
            // desktop
            footerHeading.swipe("disable");
            channel = "desktop";
            footer.css({
                height: "100%",
                width: "0%"
            });
            var map = $("section.max_map");
            var map_width = map.width();
            map.transition({width: map_width - 380 + "px"}, 200, "ease");
            footer.transition({width: "380px"}, 200, "ease", function() {
                    $("section#article-section div.entry-list").unslider();
            });
            footer.css("overflow-y", "auto");
        }
    } else {
        userLocation.currentInfobox.close();
    }

    userLocation.currentInfobox = location.infobox;
    location.infobox.open(userLocation.map, location.marker);

    if (location.entries.length > 1) {
        $("section#article-section h3#single-heading").hide();
        $("div.article-heading").show();
        $("div.article-heading img#previous").unbind("click").click(function() {
            $("section#article-section div.entry-list").data("unslider").next();
            reloadInfobox(location, index + 1);
        });
        $("div.article-heading img#next").unbind("click").click(function() {
            $("section#article-section div.entry-list").data("unslider").prev();
            reloadInfobox(location, index - 1);
        })

    } else {
        $("div.article-heading").hide();
        $("section#article-section h3#single-heading").show();
    }
}

function closeEntry() {
    var footer = $("section#article-section");

    if (channel === "mobile") {
        // mobile
        footer.transition({height: 0}, 200, "ease");
        $("main").transition({paddingBottom: "0px", marginBottom: "0px"}, 200, "ease" , function() {
            footer.css("padding", "0rem");
        });
    } else {
        // desktop
        footer.transition({width: "0%"}, 200, "ease", function() {
            footer.css({
                height: "100%",
                padding: "0rem",
                width: "auto"
            });
        });
        $("section.max_map").transition({width: "100%"}, 200, "ease");
        footer.css("overflow-y", "hidden");
    }

    if (userLocation.currentInfobox !== null) {
        userLocation.currentInfobox.close();
        userLocation.currentInfobox = null;
    }
}

/**
 * Callback that is called when the viewport changed
 */
function searchForEntries () {
    // calculate bounds to search for
    var bounds = userLocation.map.getBounds()
    var max_lat = bounds.getNorthEast().lat().toFixed(10)
    var max_lon = bounds.getNorthEast().lng().toFixed(10)
    var min_lat = bounds.getSouthWest().lat().toFixed(10)
    var min_lon = bounds.getSouthWest().lng().toFixed(10)
    // get nearby locations
    $.getJSON("../stadtgedaechtnis/services/get-nearby-locations/" + min_lat + "/" + max_lat + "/" + min_lon + "/" + max_lon + "/", function (data) {
        $.each(data, function (index, value) {
            addMarker(value);
        })
    });
}

/**
 * Location object to enable/disable tracking the location and to retrieve the current or fallback location.
 * @param trackLocation
 * @constructor
 */
function Location() {
	this.DEFAULT_LAT = 50.258;
	this.DEFAULT_LONG = 10.965;
	this.DEFAULT_LOCATION = new google.maps.LatLng(50.258, 10.965);
	this.positionMarker = null;
    this.markers = {}
    this.currentInfobox = null;
}

/**
 * Move the map to the current location or the fallback
 * @returns {google.maps.LatLng|*}
 */
Location.prototype.moveToCurrentLocationOrFallback = function () {
	if (Modernizr.geolocation) {
	    google.maps.event.addListenerOnce(this.positionMarker, 'position_changed', function() {
            this.map.setCenter(this.getPosition());
            this.map.fitBounds(this.getBounds());
            searchForEntries();
        });
	} else {
		this.moveToLocation(this.DEFAULT_LAT, this.DEFAULT_LONG);
		//TODO: show hint that browser doesn't support location
	}
};

/**
 * Moves the map to the given location
 * @param lat
 * @param long
 */
Location.prototype.moveToLocation = function(position) {
	if (this.map) {
		this.map.panTo(position);
        searchForEntries();
	}
}

var userLocation = new Location();

/**
 * Global map Options
 * @type {{center: google.maps.LatLng, zoom: number, mapTypeId: *, disableDefaultUI: boolean, zoomControl: boolean}}
 */
var mapOptions = {
	center: userLocation.DEFAULT_LOCATION,
	zoom: 17,
    mapTypeControl: true,
	mapTypeId: google.maps.MapTypeId.SATELLITE,
	disableDefaultUI: true,
	zoomControl: true
};

/**
 * Initializes the map
 */
function initialize_Map() {
	userLocation.map = new google.maps.Map(document.getElementById(MAP_ELEMENT),
		mapOptions);
    userLocation.positionMarker = new GeolocationMarker(userLocation.map)
    userLocation.moveToCurrentLocationOrFallback();
    google.maps.event.addListener(userLocation.positionMarker, 'geolocation_error', errorLocationCallback);
    google.maps.event.addListener(userLocation.map, 'idle', searchForEntries)
    google.maps.event.addListener(userLocation.map, 'click', closeEntry);
}<|endoftext|>


<commit_before>var log          = require('./logger');
var assert       = require('assert-plus');
var escapeZOQL   = require('./xml').escapeZOQL;
var common       = require('./common');
var makeError    = require('./common').makeError;

'use strict';

/**
 * Query
 *
 * Runs a Zuora ZOQL query.
 *
 * More on ZOQL is available here: https://knowledgecenter.zuora.com/BC_Developers/SOAP_API/M_Zuora_Object_Query_Language
 *
 * @param {String} querystring is a ZOQL query string like 'select id from account where name = "Homer"'
 * @param {Object} options     is a hash of options for Zuora methods
 * @param {Function} cb        is a callback function to handle response (function(error, result){})
 *
 * queryOptions:
 *   batchSize      - (default: 0 or 2000) sets the number of results returned per call by the client.
 *   caseSensitive  - sets if matching is case-sensitive
 *   fastQuery      - query read-only table
 *   More info: https://knowledgecenter.zuora.com/BC_Developers/SOAP_API/F_SOAP_API_Complex_Types/QueryOptions
 *
 * requestOptions:
 *   timeout   (default: infinity) sets the time to wait for a single HTTP request or until OS closes socket
 *   More info: https://github.com/request/request#requestoptions-callback
 *
 */
function query (querystring, options, cb) {
  if (typeof options === 'function') {
    cb = options;
    options = {};
  }
  assert.equal(typeof cb, 'function', 'query requires callback');
  assert.ok(querystring, 'query is missing required querystring');
  assert.ok(typeof querystring === 'string' || querystring instanceof String, 'querystring must be a string');

  assert.ok(this.client._client.ZuoraService.Soap, 'missing `ZuoraService.Soap` on client reference');
  var client = this.client;

  var results = [];
  // TODO: create a stream for output
  // var resultStream;

  var zObject = {
    'queryString': escapeZOQL(querystring)
  };

  var add = function(result) {
    if (!result) { return; }
    result.map(removeAttributes);
    results.push.apply(results, result);
    // resultStream.push() // TODO: push onto stream
  };

  var onQueryResponse = function(err, res) {
    // https://knowledgecenter.zuora.com/BC_Developers/SOAP_API/E_SOAP_API_Calls/queryMore_call

    common.printDebugMessages(client, err, res);

    if (err) {
      return cb(makeError(err, {
        lastRequest:  client.lastRequest,
        lastResponse: client.lastResponse
      }));
    }
    if (res) {
      add(res.records);
      if (!res.done) {
        log.debug('Next queryLocator is ' + res.queryLocator + ' of ' + res.size);

        var zMorePls = {
          'queryLocator': res.queryLocator
        };
        var doQueryMore = makeQueryMore(zMorePls);
        var makeQueryMore = function(zQueryLocator) {
          return function () {
            log.debug('Requesting with:\n' + JSON.stringify(zQueryLocator) );
            client.runSoapMethod('queryMore', zQueryLocator, options, onQueryResponse);
          };
        };
        doQueryMore();
      } else {
        return cb(null, results);
      }
    } else {
      return cb(new Error('Query results missing'));
    }
  };

  function doQuery() {
    client.runSoapMethod('query', zObject, options, onQueryResponse);
  }

  doQuery();

}

function attachQuery(xmasTree) {
  xmasTree.query = query;
  return xmasTree;
}

function removeAttributes(record) {
  delete record.attributes;
  return record;
}

module.exports = attachQuery;
<commit_msg>Fixed out of order function declaration<commit_after>var log          = require('./logger');
var assert       = require('assert-plus');
var escapeZOQL   = require('./xml').escapeZOQL;
var common       = require('./common');
var makeError    = require('./common').makeError;

'use strict';

/**
 * Query
 *
 * Runs a Zuora ZOQL query.
 *
 * More on ZOQL is available here: https://knowledgecenter.zuora.com/BC_Developers/SOAP_API/M_Zuora_Object_Query_Language
 *
 * @param {String} querystring is a ZOQL query string like 'select id from account where name = "Homer"'
 * @param {Object} options     is a hash of options for Zuora methods
 * @param {Function} cb        is a callback function to handle response (function(error, result){})
 *
 * queryOptions:
 *   batchSize      - (default: 0 or 2000) sets the number of results returned per call by the client.
 *   caseSensitive  - sets if matching is case-sensitive
 *   fastQuery      - query read-only table
 *   More info: https://knowledgecenter.zuora.com/BC_Developers/SOAP_API/F_SOAP_API_Complex_Types/QueryOptions
 *
 * requestOptions:
 *   timeout   (default: infinity) sets the time to wait for a single HTTP request or until OS closes socket
 *   More info: https://github.com/request/request#requestoptions-callback
 *
 */
function query (querystring, options, cb) {
  if (typeof options === 'function') {
    cb = options;
    options = {};
  }
  assert.equal(typeof cb, 'function', 'query requires callback');
  assert.ok(querystring, 'query is missing required querystring');
  assert.ok(typeof querystring === 'string' || querystring instanceof String, 'querystring must be a string');

  assert.ok(this.client._client.ZuoraService.Soap, 'missing `ZuoraService.Soap` on client reference');
  var client = this.client;

  var results = [];
  // TODO: create a stream for output
  // var resultStream;

  var zObject = {
    'queryString': escapeZOQL(querystring)
  };

  var add = function(result) {
    if (!result) { return; }
    result.map(removeAttributes);
    results.push.apply(results, result);
    // resultStream.push() // TODO: push onto stream
  };

  var onQueryResponse = function(err, res) {
    // https://knowledgecenter.zuora.com/BC_Developers/SOAP_API/E_SOAP_API_Calls/queryMore_call

    common.printDebugMessages(client, err, res);

    if (err) {
      return cb(makeError(err, {
        lastRequest:  client.lastRequest,
        lastResponse: client.lastResponse
      }));
    }
    if (res) {
      add(res.records);
      if (!res.done) {
        log.debug('Next queryLocator is ' + res.queryLocator + ' of ' + res.size);

        var makeQueryMore = function(zQueryLocator) {
          return function () {
            log.debug('Requesting with:\n' + JSON.stringify(zQueryLocator) );
            client.runSoapMethod('queryMore', zQueryLocator, options, onQueryResponse);
          };
        };
        var zMorePls = {
          'queryLocator': res.queryLocator
        };
        var doQueryMore = makeQueryMore(zMorePls);
        doQueryMore();
      } else {
        return cb(null, results);
      }
    } else {
      return cb(new Error('Query results missing'));
    }
  };

  function doQuery() {
    client.runSoapMethod('query', zObject, options, onQueryResponse);
  }

  doQuery();

}

function attachQuery(xmasTree) {
  xmasTree.query = query;
  return xmasTree;
}

function removeAttributes(record) {
  delete record.attributes;
  return record;
}

module.exports = attachQuery;
<|endoftext|>