<commit_before>import Ember from 'ember';
import TaskInstance from './-task-instance';
import TaskStateMixin from './-task-state-mixin';
import { TaskGroup } from './-task-group';
import { propertyModifiers, resolveScheduler } from './-property-modifiers-mixin';
import { objectAssign, INVOKE, _cleanupOnDestroy, _ComputedProperty } from './utils';
import EncapsulatedTask from './-encapsulated-task';

const { getOwner } = Ember;

/**
  The `Task` object lives on a host Ember object (e.g.
  a Component, Route, or Controller). You call the
  {@linkcode Task#perform .perform()} method on this object
  to create run individual {@linkcode TaskInstance}s,
  and at any point, you can call the {@linkcode Task#cancelAll .cancelAll()}
  method on this object to cancel all running or enqueued
  {@linkcode TaskInstance}s.

  <style>
    .ignore-this--this-is-here-to-hide-constructor,
    #Task{ display: none }
  </style>

  @class Task
*/
export const Task = Ember.Object.extend(TaskStateMixin, {
  /**
   * `true` if any current task instances are running.
   *
   * @memberof Task
   * @member {boolean} isRunning
   * @instance
   * @readOnly
   */

  /**
   * `true` if any future task instances are queued.
   *
   * @memberof Task
   * @member {boolean} isQueued
   * @instance
   * @readOnly
   */

  /**
   * `true` if the task is not in the running or queued state.
   *
   * @memberof Task
   * @member {boolean} isIdle
   * @instance
   * @readOnly
   */

  /**
   * The current state of the task: `"running"`, `"queued"` or `"idle"`.
   *
   * @memberof Task
   * @member {string} state
   * @instance
   * @readOnly
   */

  /**
   * The most recently started task instance.
   *
   * @memberof Task
   * @member {TaskInstance} last
   * @instance
   * @readOnly
   */

  /**
   * The most recent task instance that is currently running.
   *
   * @memberof Task
   * @member {TaskInstance} lastRunning
   * @instance
   * @readOnly
   */

  /**
   * The most recently performed task instance.
   *
   * @memberof Task
   * @member {TaskInstance} lastPerformed
   * @instance
   * @readOnly
   */

  /**
   * The most recent task instance that succeeded.
   *
   * @memberof Task
   * @member {TaskInstance} lastSuccessful
   * @instance
   * @readOnly
   */

  /**
   * The most recently completed task instance.
   *
   * @memberof Task
   * @member {TaskInstance} lastComplete
   * @instance
   * @readOnly
   */

  /**
   * The most recent task instance that errored.
   *
   * @memberof Task
   * @member {TaskInstance} lastErrored
   * @instance
   * @readOnly
   */

  /**
   * The most recently canceled task instance.
   *
   * @memberof Task
   * @member {TaskInstance} lastCanceled
   * @instance
   * @readOnly
   */

  /**
   * The most recent task instance that is incomplete.
   *
   * @memberof Task
   * @member {TaskInstance} lastIncomplete
   * @instance
   * @readOnly
   */

  /**
   * The number of times this task has been performed.
   *
   * @memberof Task
   * @member {number} performCount
   * @instance
   * @readOnly
   */

  fn: null,
  context: null,
  _observes: null,
  _curryArgs: null,

  init() {
    this._super(...arguments);

    if (typeof this.fn === 'object') {
      let owner = getOwner(this.context);
      let ownerInjection = owner ? owner.ownerInjection() : {};
      this._taskInstanceFactory = EncapsulatedTask.extend(ownerInjection, this.fn);
    }

    _cleanupOnDestroy(this.context, this, 'cancelAll');
  },

  _curry(...args) {
    let task = this._clone();
    task._curryArgs = [...(this._curryArgs || []), ...args];
    return task;
  },

  _clone() {
    return Task.create({
      fn: this.fn,
      context: this.context,
      _origin: this._origin,
      _taskGroupPath: this._taskGroupPath,
      _scheduler: this._scheduler,
      _propertyName: this._propertyName,
      _debugCallback: this._debugCallback,
    });
  },

  /**
   * This property is true if this task is NOT running, i.e. the number
   * of currently running TaskInstances is zero.
   *
   * This property is useful for driving the state/style of buttons
   * and loading UI, among other things.
   *
   * @memberof Task
   * @instance
   * @readOnly
   */

  /**
   * This property is true if this task is running, i.e. the number
   * of currently running TaskInstances is greater than zero.
   *
   * This property is useful for driving the state/style of buttons
   * and loading UI, among other things.
   *
   * @memberof Task
   * @instance
   * @readOnly
   */

  /**
   * EXPERIMENTAL
   *
   * This value describes what would happen to the TaskInstance returned
   * from .perform() if .perform() were called right now.  Returns one of
   * the following values:
   *
   * - `succeed`: new TaskInstance will start running immediately
   * - `drop`: new TaskInstance will be dropped
   * - `enqueue`: new TaskInstance will be enqueued for later execution
   *
   * @memberof Task
   * @instance
   * @private
   * @readOnly
   */

  /**
   * EXPERIMENTAL
   *
   * Returns true if calling .perform() right now would immediately start running
   * the returned TaskInstance.
   *
   * @memberof Task
   * @instance
   * @private
   * @readOnly
   */

  /**
   * EXPERIMENTAL
   *
   * Returns true if calling .perform() right now would immediately cancel (drop)
   * the returned TaskInstance.
   *
   * @memberof Task
   * @instance
   * @private
   * @readOnly
   */

  /**
   * EXPERIMENTAL
   *
   * Returns true if calling .perform() right now would enqueue the TaskInstance
   * rather than execute immediately.
   *
   * @memberof Task
   * @instance
   * @private
   * @readOnly
   */

  /**
   * EXPERIMENTAL
   *
   * Returns true if calling .perform() right now would cause a previous task to be canceled
   *
   * @memberof Task
   * @instance
   * @private
   * @readOnly
   */

  /**
   * The current number of active running task instances. This
   * number will never exceed maxConcurrency.
   *
   * @memberof Task
   * @instance
   * @readOnly
   */

  /**
   * Cancels all running or queued `TaskInstance`s for this Task.
   * If you're trying to cancel a specific TaskInstance (rather
   * than all of the instances running under this task) call
   * `.cancel()` on the specific TaskInstance.
   *
   * @method cancelAll
   * @memberof Task
   * @instance
   */

  toString() {
    return `<Task:${this._propertyName}>`;
  },

  _taskInstanceFactory: TaskInstance,

  /**
   * Creates a new {@linkcode TaskInstance} and attempts to run it right away.
   * If running this task instance would increase the task's concurrency
   * to a number greater than the task's maxConcurrency, this task
   * instance might be immediately canceled (dropped), or enqueued
   * to run at later time, after the currently running task(s) have finished.
   *
   * @method perform
   * @memberof Task
   * @param {*} arg* - args to pass to the task function
   * @instance
   */
  perform(...args) {
    let fullArgs = this._curryArgs ? [...this._curryArgs, ...args] : args;
    let taskInstance = this._taskInstanceFactory.create({
      fn: this.fn,
      args: fullArgs,
      context: this.context,
      owner: this.context,
      task: this,
      _origin: this,
      _debugCallback: this._debugCallback,
    });

    if (this.context.isDestroying) {
      taskInstance.cancel();
    }

    this._scheduler.schedule(taskInstance);
    return taskInstance;
  },

  [INVOKE](...args) {
    return this.perform(...args);
  },
});

/**
  A {@link TaskProperty} is the Computed Property-like object returned
  from the {@linkcode task} function. You can call Task Modifier methods
  on this object to configure the behavior of the {@link Task}.

  See [Managing Task Concurrency](/#/docs/task-concurrency) for an
  overview of all the different task modifiers you can use and how
  they impact automatic cancelation / enqueueing of task instances.

  <style>
    .ignore-this--this-is-here-to-hide-constructor,
    #TaskProperty { display: none }
  </style>

  @class TaskProperty
*/
export function TaskProperty(taskFn) {
  let tp = this;
  _ComputedProperty.call(this, function(_propertyName) {
    return Task.create({
      fn: tp.taskFn,
      context: this,
      _origin: this,
      _taskGroupPath: tp._taskGroupPath,
      _scheduler: resolveScheduler(tp, this, TaskGroup),
      _propertyName,
      _debugCallback: tp._debugCallback,
    });
  });

  this.taskFn = taskFn;
  this.eventNames = null;
  this.cancelEventNames = null;
  this._debugCallback = null;
  this._observes = null;
}

TaskProperty.prototype = Object.create(_ComputedProperty.prototype);
objectAssign(TaskProperty.prototype, propertyModifiers, {
  constructor: TaskProperty,

  setup(proto, taskName) {
    if (this._maxConcurrency !== Infinity && !this._hasSetBufferPolicy) {
      Ember.Logger.warn(`The use of maxConcurrency() without a specified task modifier is deprecated and won't be supported in future versions of ember-concurrency. Please specify a task modifier instead, e.g. \`${taskName}: task(...).enqueue().maxConcurrency(${this._maxConcurrency})\``);
    }

    registerOnPrototype(Ember.addListener, proto, this.eventNames, taskName, 'perform', false);
    registerOnPrototype(Ember.addListener, proto, this.cancelEventNames, taskName, 'cancelAll', false);
    registerOnPrototype(Ember.addObserver, proto, this._observes, taskName, 'perform', true);
  },

  /**
   * Calling `task(...).on(eventName)` configures the task to be
   * automatically performed when the specified events fire. In
   * this way, it behaves like
   * [Ember.on](http://emberjs.com/api/classes/Ember.html#method_on).
   *
   * You can use `task(...).on('init')` to perform the task
   * when the host object is initialized.
   *
   * ```js
   * export default Ember.Component.extend({
   *   pollForUpdates: task(function * () {
   *     // ... this runs when the Component is first created
   *     // because we specified .on('init')
   *   }).on('init'),
   *
   *   handleFoo: task(function * (a, b, c) {
   *     // this gets performed automatically if the 'foo'
   *     // event fires on this Component,
   *     // e.g., if someone called component.trigger('foo')
   *   }).on('foo'),
   * });
   * ```
   *
   * [See the Writing Tasks Docs for more info](/#/docs/writing-tasks)
   *
   * @method on
   * @memberof TaskProperty
   * @param {String} eventNames*
   * @instance
   */
  on() {
    this.eventNames = this.eventNames || [];
    this.eventNames.push.apply(this.eventNames, arguments);
    return this;
  },

  /**
   * This behaves like the {@linkcode TaskProperty#on task(...).on() modifier},
   * but instead will cause the task to be canceled if any of the
   * specified events fire on the parent object.
   *
   * [See the Live Example](/#/docs/examples/route-tasks/1)
   *
   * @method cancelOn
   * @memberof TaskProperty
   * @param {String} eventNames*
   * @instance
   */
  cancelOn() {
    this.cancelEventNames = this.cancelEventNames || [];
    this.cancelEventNames.push.apply(this.cancelEventNames, arguments);
    return this;
  },

  observes(...properties) {
    this._observes = properties;
    return this;
  },

  /**
   * Configures the task to cancel old currently task instances
   * to make room for a new one to perform. Sets default
   * maxConcurrency to 1.
   *
   * [See the Live Example](/#/docs/examples/route-tasks/1)
   *
   * @method restartable
   * @memberof TaskProperty
   * @instance
   */

  /**
   * Configures the task to run task instances one-at-a-time in
   * the order they were `.perform()`ed. Sets default
   * maxConcurrency to 1.
   *
   * @method enqueue
   * @memberof TaskProperty
   * @instance
   */

  /**
   * Configures the task to immediately cancel (i.e. drop) any
   * task instances performed when the task is already running
   * at maxConcurrency. Sets default maxConcurrency to 1.
   *
   * @method drop
   * @memberof TaskProperty
   * @instance
   */

  /**
   * Configures the task to drop all but the most recently
   * performed {@linkcode TaskInstance }.
   *
   * @method keepLatest
   * @memberof TaskProperty
   * @instance
   */

  /**
   * Sets the maximum number of task instances that are allowed
   * to run at the same time. By default, with no task modifiers
   * applied, this number is Infinity (there is no limit
   * to the number of tasks that can run at the same time).
   * {@linkcode TaskProperty#restartable .restartable()},
   * {@linkcode TaskProperty#enqueue .enqueue()}, and
   * {@linkcode TaskProperty#drop .drop()} set the default
   * maxConcurrency to 1, but you can override this value
   * to set the maximum number of concurrently running tasks
   * to a number greater than 1.
   *
   * [See the AJAX Throttling example](/#/docs/examples/ajax-throttling)
   *
   * The example below uses a task with `maxConcurrency(3)` to limit
   * the number of concurrent AJAX requests (for anyone using this task)
   * to 3.
   *
   * ```js
   * doSomeAjax: task(function * (url) {
   *   return Ember.$.getJSON(url).promise();
   * }).maxConcurrency(3),
   *
   * elsewhere() {
   *   this.get('doSomeAjax').perform("http://www.example.com/json");
   * },
   * ```
   *
   * @method maxConcurrency
   * @memberof TaskProperty
   * @param {Number} n The maximum number of concurrently running tasks
   * @instance
   */

  _debug(cb) {
    this._debugCallback = cb || defaultDebugCallback;
    return this;
  },
});

function defaultDebugCallback(payload) {
  console.log(payload);
}

function registerOnPrototype(addListenerOrObserver, proto, names, taskName, taskMethod, once) {
  if (names) {
    for (let i = 0; i < names.length; ++i) {
      let name = names[i];
      addListenerOrObserver(proto, name, null, makeTaskCallback(taskName, taskMethod, once));
    }
  }
}

function makeTaskCallback(taskName, method, once) {
  return function() {
    let task = this.get(taskName);

    if (once) {
      Ember.run.scheduleOnce('actions', task, method, ...arguments);
    } else {
      task[method].apply(task, arguments);
    }
  };
}
<commit_msg>tag the task gen fn displayName for nicer Chrome debugging<commit_after>import Ember from 'ember';
import TaskInstance from './-task-instance';
import TaskStateMixin from './-task-state-mixin';
import { TaskGroup } from './-task-group';
import { propertyModifiers, resolveScheduler } from './-property-modifiers-mixin';
import { objectAssign, INVOKE, _cleanupOnDestroy, _ComputedProperty } from './utils';
import EncapsulatedTask from './-encapsulated-task';

const { getOwner } = Ember;

/**
  The `Task` object lives on a host Ember object (e.g.
  a Component, Route, or Controller). You call the
  {@linkcode Task#perform .perform()} method on this object
  to create run individual {@linkcode TaskInstance}s,
  and at any point, you can call the {@linkcode Task#cancelAll .cancelAll()}
  method on this object to cancel all running or enqueued
  {@linkcode TaskInstance}s.

  <style>
    .ignore-this--this-is-here-to-hide-constructor,
    #Task{ display: none }
  </style>

  @class Task
*/
export const Task = Ember.Object.extend(TaskStateMixin, {
  /**
   * `true` if any current task instances are running.
   *
   * @memberof Task
   * @member {boolean} isRunning
   * @instance
   * @readOnly
   */

  /**
   * `true` if any future task instances are queued.
   *
   * @memberof Task
   * @member {boolean} isQueued
   * @instance
   * @readOnly
   */

  /**
   * `true` if the task is not in the running or queued state.
   *
   * @memberof Task
   * @member {boolean} isIdle
   * @instance
   * @readOnly
   */

  /**
   * The current state of the task: `"running"`, `"queued"` or `"idle"`.
   *
   * @memberof Task
   * @member {string} state
   * @instance
   * @readOnly
   */

  /**
   * The most recently started task instance.
   *
   * @memberof Task
   * @member {TaskInstance} last
   * @instance
   * @readOnly
   */

  /**
   * The most recent task instance that is currently running.
   *
   * @memberof Task
   * @member {TaskInstance} lastRunning
   * @instance
   * @readOnly
   */

  /**
   * The most recently performed task instance.
   *
   * @memberof Task
   * @member {TaskInstance} lastPerformed
   * @instance
   * @readOnly
   */

  /**
   * The most recent task instance that succeeded.
   *
   * @memberof Task
   * @member {TaskInstance} lastSuccessful
   * @instance
   * @readOnly
   */

  /**
   * The most recently completed task instance.
   *
   * @memberof Task
   * @member {TaskInstance} lastComplete
   * @instance
   * @readOnly
   */

  /**
   * The most recent task instance that errored.
   *
   * @memberof Task
   * @member {TaskInstance} lastErrored
   * @instance
   * @readOnly
   */

  /**
   * The most recently canceled task instance.
   *
   * @memberof Task
   * @member {TaskInstance} lastCanceled
   * @instance
   * @readOnly
   */

  /**
   * The most recent task instance that is incomplete.
   *
   * @memberof Task
   * @member {TaskInstance} lastIncomplete
   * @instance
   * @readOnly
   */

  /**
   * The number of times this task has been performed.
   *
   * @memberof Task
   * @member {number} performCount
   * @instance
   * @readOnly
   */

  fn: null,
  context: null,
  _observes: null,
  _curryArgs: null,

  init() {
    this._super(...arguments);

    if (typeof this.fn === 'object') {
      let owner = getOwner(this.context);
      let ownerInjection = owner ? owner.ownerInjection() : {};
      this._taskInstanceFactory = EncapsulatedTask.extend(ownerInjection, this.fn);
    }

    _cleanupOnDestroy(this.context, this, 'cancelAll');
  },

  _curry(...args) {
    let task = this._clone();
    task._curryArgs = [...(this._curryArgs || []), ...args];
    return task;
  },

  _clone() {
    return Task.create({
      fn: this.fn,
      context: this.context,
      _origin: this._origin,
      _taskGroupPath: this._taskGroupPath,
      _scheduler: this._scheduler,
      _propertyName: this._propertyName,
      _debugCallback: this._debugCallback,
    });
  },

  /**
   * This property is true if this task is NOT running, i.e. the number
   * of currently running TaskInstances is zero.
   *
   * This property is useful for driving the state/style of buttons
   * and loading UI, among other things.
   *
   * @memberof Task
   * @instance
   * @readOnly
   */

  /**
   * This property is true if this task is running, i.e. the number
   * of currently running TaskInstances is greater than zero.
   *
   * This property is useful for driving the state/style of buttons
   * and loading UI, among other things.
   *
   * @memberof Task
   * @instance
   * @readOnly
   */

  /**
   * EXPERIMENTAL
   *
   * This value describes what would happen to the TaskInstance returned
   * from .perform() if .perform() were called right now.  Returns one of
   * the following values:
   *
   * - `succeed`: new TaskInstance will start running immediately
   * - `drop`: new TaskInstance will be dropped
   * - `enqueue`: new TaskInstance will be enqueued for later execution
   *
   * @memberof Task
   * @instance
   * @private
   * @readOnly
   */

  /**
   * EXPERIMENTAL
   *
   * Returns true if calling .perform() right now would immediately start running
   * the returned TaskInstance.
   *
   * @memberof Task
   * @instance
   * @private
   * @readOnly
   */

  /**
   * EXPERIMENTAL
   *
   * Returns true if calling .perform() right now would immediately cancel (drop)
   * the returned TaskInstance.
   *
   * @memberof Task
   * @instance
   * @private
   * @readOnly
   */

  /**
   * EXPERIMENTAL
   *
   * Returns true if calling .perform() right now would enqueue the TaskInstance
   * rather than execute immediately.
   *
   * @memberof Task
   * @instance
   * @private
   * @readOnly
   */

  /**
   * EXPERIMENTAL
   *
   * Returns true if calling .perform() right now would cause a previous task to be canceled
   *
   * @memberof Task
   * @instance
   * @private
   * @readOnly
   */

  /**
   * The current number of active running task instances. This
   * number will never exceed maxConcurrency.
   *
   * @memberof Task
   * @instance
   * @readOnly
   */

  /**
   * Cancels all running or queued `TaskInstance`s for this Task.
   * If you're trying to cancel a specific TaskInstance (rather
   * than all of the instances running under this task) call
   * `.cancel()` on the specific TaskInstance.
   *
   * @method cancelAll
   * @memberof Task
   * @instance
   */

  toString() {
    return `<Task:${this._propertyName}>`;
  },

  _taskInstanceFactory: TaskInstance,

  /**
   * Creates a new {@linkcode TaskInstance} and attempts to run it right away.
   * If running this task instance would increase the task's concurrency
   * to a number greater than the task's maxConcurrency, this task
   * instance might be immediately canceled (dropped), or enqueued
   * to run at later time, after the currently running task(s) have finished.
   *
   * @method perform
   * @memberof Task
   * @param {*} arg* - args to pass to the task function
   * @instance
   */
  perform(...args) {
    let fullArgs = this._curryArgs ? [...this._curryArgs, ...args] : args;
    let taskInstance = this._taskInstanceFactory.create({
      fn: this.fn,
      args: fullArgs,
      context: this.context,
      owner: this.context,
      task: this,
      _origin: this,
      _debugCallback: this._debugCallback,
    });

    if (this.context.isDestroying) {
      taskInstance.cancel();
    }

    this._scheduler.schedule(taskInstance);
    return taskInstance;
  },

  [INVOKE](...args) {
    return this.perform(...args);
  },
});

/**
  A {@link TaskProperty} is the Computed Property-like object returned
  from the {@linkcode task} function. You can call Task Modifier methods
  on this object to configure the behavior of the {@link Task}.

  See [Managing Task Concurrency](/#/docs/task-concurrency) for an
  overview of all the different task modifiers you can use and how
  they impact automatic cancelation / enqueueing of task instances.

  <style>
    .ignore-this--this-is-here-to-hide-constructor,
    #TaskProperty { display: none }
  </style>

  @class TaskProperty
*/
export function TaskProperty(taskFn) {
  let tp = this;
  _ComputedProperty.call(this, function(_propertyName) {
    taskFn.displayName = `${_propertyName} (task)`;
    return Task.create({
      fn: tp.taskFn,
      context: this,
      _origin: this,
      _taskGroupPath: tp._taskGroupPath,
      _scheduler: resolveScheduler(tp, this, TaskGroup),
      _propertyName,
      _debugCallback: tp._debugCallback,
    });
  });

  this.taskFn = taskFn;
  this.eventNames = null;
  this.cancelEventNames = null;
  this._debugCallback = null;
  this._observes = null;
}

TaskProperty.prototype = Object.create(_ComputedProperty.prototype);
objectAssign(TaskProperty.prototype, propertyModifiers, {
  constructor: TaskProperty,

  setup(proto, taskName) {
    if (this._maxConcurrency !== Infinity && !this._hasSetBufferPolicy) {
      Ember.Logger.warn(`The use of maxConcurrency() without a specified task modifier is deprecated and won't be supported in future versions of ember-concurrency. Please specify a task modifier instead, e.g. \`${taskName}: task(...).enqueue().maxConcurrency(${this._maxConcurrency})\``);
    }

    registerOnPrototype(Ember.addListener, proto, this.eventNames, taskName, 'perform', false);
    registerOnPrototype(Ember.addListener, proto, this.cancelEventNames, taskName, 'cancelAll', false);
    registerOnPrototype(Ember.addObserver, proto, this._observes, taskName, 'perform', true);
  },

  /**
   * Calling `task(...).on(eventName)` configures the task to be
   * automatically performed when the specified events fire. In
   * this way, it behaves like
   * [Ember.on](http://emberjs.com/api/classes/Ember.html#method_on).
   *
   * You can use `task(...).on('init')` to perform the task
   * when the host object is initialized.
   *
   * ```js
   * export default Ember.Component.extend({
   *   pollForUpdates: task(function * () {
   *     // ... this runs when the Component is first created
   *     // because we specified .on('init')
   *   }).on('init'),
   *
   *   handleFoo: task(function * (a, b, c) {
   *     // this gets performed automatically if the 'foo'
   *     // event fires on this Component,
   *     // e.g., if someone called component.trigger('foo')
   *   }).on('foo'),
   * });
   * ```
   *
   * [See the Writing Tasks Docs for more info](/#/docs/writing-tasks)
   *
   * @method on
   * @memberof TaskProperty
   * @param {String} eventNames*
   * @instance
   */
  on() {
    this.eventNames = this.eventNames || [];
    this.eventNames.push.apply(this.eventNames, arguments);
    return this;
  },

  /**
   * This behaves like the {@linkcode TaskProperty#on task(...).on() modifier},
   * but instead will cause the task to be canceled if any of the
   * specified events fire on the parent object.
   *
   * [See the Live Example](/#/docs/examples/route-tasks/1)
   *
   * @method cancelOn
   * @memberof TaskProperty
   * @param {String} eventNames*
   * @instance
   */
  cancelOn() {
    this.cancelEventNames = this.cancelEventNames || [];
    this.cancelEventNames.push.apply(this.cancelEventNames, arguments);
    return this;
  },

  observes(...properties) {
    this._observes = properties;
    return this;
  },

  /**
   * Configures the task to cancel old currently task instances
   * to make room for a new one to perform. Sets default
   * maxConcurrency to 1.
   *
   * [See the Live Example](/#/docs/examples/route-tasks/1)
   *
   * @method restartable
   * @memberof TaskProperty
   * @instance
   */

  /**
   * Configures the task to run task instances one-at-a-time in
   * the order they were `.perform()`ed. Sets default
   * maxConcurrency to 1.
   *
   * @method enqueue
   * @memberof TaskProperty
   * @instance
   */

  /**
   * Configures the task to immediately cancel (i.e. drop) any
   * task instances performed when the task is already running
   * at maxConcurrency. Sets default maxConcurrency to 1.
   *
   * @method drop
   * @memberof TaskProperty
   * @instance
   */

  /**
   * Configures the task to drop all but the most recently
   * performed {@linkcode TaskInstance }.
   *
   * @method keepLatest
   * @memberof TaskProperty
   * @instance
   */

  /**
   * Sets the maximum number of task instances that are allowed
   * to run at the same time. By default, with no task modifiers
   * applied, this number is Infinity (there is no limit
   * to the number of tasks that can run at the same time).
   * {@linkcode TaskProperty#restartable .restartable()},
   * {@linkcode TaskProperty#enqueue .enqueue()}, and
   * {@linkcode TaskProperty#drop .drop()} set the default
   * maxConcurrency to 1, but you can override this value
   * to set the maximum number of concurrently running tasks
   * to a number greater than 1.
   *
   * [See the AJAX Throttling example](/#/docs/examples/ajax-throttling)
   *
   * The example below uses a task with `maxConcurrency(3)` to limit
   * the number of concurrent AJAX requests (for anyone using this task)
   * to 3.
   *
   * ```js
   * doSomeAjax: task(function * (url) {
   *   return Ember.$.getJSON(url).promise();
   * }).maxConcurrency(3),
   *
   * elsewhere() {
   *   this.get('doSomeAjax').perform("http://www.example.com/json");
   * },
   * ```
   *
   * @method maxConcurrency
   * @memberof TaskProperty
   * @param {Number} n The maximum number of concurrently running tasks
   * @instance
   */

  _debug(cb) {
    this._debugCallback = cb || defaultDebugCallback;
    return this;
  },
});

function defaultDebugCallback(payload) {
  console.log(payload);
}

function registerOnPrototype(addListenerOrObserver, proto, names, taskName, taskMethod, once) {
  if (names) {
    for (let i = 0; i < names.length; ++i) {
      let name = names[i];
      addListenerOrObserver(proto, name, null, makeTaskCallback(taskName, taskMethod, once));
    }
  }
}

function makeTaskCallback(taskName, method, once) {
  return function() {
    let task = this.get(taskName);

    if (once) {
      Ember.run.scheduleOnce('actions', task, method, ...arguments);
    } else {
      task[method].apply(task, arguments);
    }
  };
}
<|endoftext|>


<commit_before>/*
TLDR: Save yourself from headaches and just use Harmony (ES6), Typescript or FB flow classes

Class emulation library / Pseudo-Classical Inheritance
Javascript is a prototype language, and as such doesn't include a native class implementation (ES6 has but we're using ES5)

Rather than class defitions, JavaScript has constructor functions and the new operator.
A constructor function can specify an object's initial properties and values when it is intantiated. Any JavaScript function
can be considered a constructor. Use the new operator with a constructor function to create a new instance.

---
Everything in JavaScript is an object and objects are plain and simple dictionaries (or hashes as commonly said)
That means, we can access and set their properties with an index or using the dot operator
Ex:
a = {} // create and empty object/hash
a['b'] = 1; // assign a value to and index
a.b = 1 // access that value using the dot operator

delete a['b'] // delete the added index
---
Adding [static] class functions to a constructor is the same as adding a property to an object.
Ex:
Person.find = function(id){ ... }
var person = Person.find(1);

To add instance functions to a constructor is the same as adding them to the constructors prototype
Ex:
Person.prototype.run = function(){...}
var person = new Person();
person.run();
---
To inherit from another class, is to make the descendants class prototype equal to the parents prototype.
because that way we can call the parent's methods (through the prototype)
Ex:
var Animal = function(speciesName){

}

var Person = function(name){...}
Person.prototype = new Animal();
---------
Prototypa way
var obj = Object.create(Constructor.prototype);

if(typeof Object.create !== 'function'){
  Object.create = function(proto){
    function F(){};
    F.prototype = proto;
    return new();
  }
}
*/

var Class = function(parent){
	var klass = function(){
		this.init.apply(this, arguments)
	}

	// change klass' prototype
	if(parent){
		var subclass = function(){}
		subclass.prototype = parent.prototype;
		klass.prototype = new subclass;
	}

	klass.prototype.init = function(){};

	// Shortcuts
	klass.fn = klass.prototype;
	klass.fn.parent = klass;
	klass._super = klass.__proto__;

	// Adding class properties
	klass.extend = function(obj){
		var extended = obj.extended;
		for(var i in obj){
			if(obj.hasOwnProperty(i)){
				klass[i] = obj[i];
			}
		}

		// call extended callback
		if (extended) extended(klass);
	}

	// Adding Instance Properties
	klass.include = function(obj){
		var included = obj.included;
		for(var i in obj){
			klass.fn[i] = obj[i];
		}
		if (included) included(klass);
	}

	return klass;
};

var ORM = {
	save: function(){}
}

var Person = new Class;

Person.prototype.init = function(){
	// Called on Person instantiation;
};

// Usage:
Person.include(ORM);
var person = new Person;

/* Simple JavaScript Inheritance
 * By John Resig http://ejohn.org/
 * MIT Licensed.
 */
// Inspired by base2 and Prototype
// Taken from: http://ejohn.org/blog/simple-javascript-inheritance
(function(){
  var initializing = false, fnTest = /xyz/.test(function(){xyz;}) ? /\b_super\b/ : /.*/;

  // The base Class implementation (does nothing)
  this.Class = function(){};

  // Create a new Class that inherits from this class
  Class.extend = function(prop) {
    var _super = this.prototype;

    // Instantiate a base class (but only create the instance,
    // don't run the init constructor)
    initializing = true;
    var prototype = new this();
    initializing = false;

    // Copy the properties over onto the new prototype
    for (var name in prop) {
      // Check if we're overwriting an existing function
      prototype[name] = typeof prop[name] == "function" &&
        typeof _super[name] == "function" && fnTest.test(prop[name]) ?
        (function(name, fn){
          return function() {
            var tmp = this._super;

            // Add a new ._super() method that is the same method
            // but on the super-class
            this._super = _super[name];

            // The method only need to be bound temporarily, so we
            // remove it when we're done executing
            var ret = fn.apply(this, arguments);
            this._super = tmp;

            return ret;
          };
        })(name, prop[name]) :
        prop[name];
    }

    // The dummy class constructor
    function Class() {
      // All construction is actually done in the init method
      if ( !initializing && this.init )
        this.init.apply(this, arguments);
    }

    // Populate our constructed prototype object
    Class.prototype = prototype;

    // Enforce the constructor to be what we expect
    Class.prototype.constructor = Class;

    // And make this class extendable
    Class.extend = arguments.callee;

    return Class;
  };
})();

// --------
// Object.create support test, and fallback for browsers without it
if ( typeof Object.create !== 'function' ) {
    Object.create = function (o) {
        function F() {}
        F.prototype = o;
        return new F();
    };
}

function extend(child, parent){
  child.prototype = inherit(parent.prototype);
  child.prototype.constructor = child;
  child.prototype.super = parent.prototype;
}

function inherit(proto){
  function F(){}
  F.prototype = proto;
  return new F();
}

/*
  Base.js, version 1.1a
  Copyright 2006-2010, Dean Edwards
  License: http://www.opensource.org/licenses/mit-license.php
*/

var Base = function() {
  // dummy
};

Base.extend = function(_instance, _static) { // subclass
  var extend = Base.prototype.extend;

  // build the prototype
  Base._prototyping = true;
  var proto = new this;
  extend.call(proto, _instance);
  proto.base = function() {
    // call this method from any other method to invoke that method's ancestor
  };
  delete Base._prototyping;

  // create the wrapper for the constructor function
  //var constructor = proto.constructor.valueOf(); //-dean
  var constructor = proto.constructor;
  var klass = proto.constructor = function() {
    if (!Base._prototyping) {
      if (this._constructing || this.constructor == klass) { // instantiation
        this._constructing = true;
        constructor.apply(this, arguments);
        delete this._constructing;
      } else if (arguments[0] != null) { // casting
        return (arguments[0].extend || extend).call(arguments[0], proto);
      }
    }
  };

  // build the class interface
  klass.ancestor = this;
  klass.extend = this.extend;
  klass.forEach = this.forEach;
  klass.implement = this.implement;
  klass.prototype = proto;
  klass.toString = this.toString;
  klass.valueOf = function(type) {
    //return (type == "object") ? klass : constructor; //-dean
    return (type == "object") ? klass : constructor.valueOf();
  };
  extend.call(klass, _static);
  // class initialisation
  if (typeof klass.init == "function") klass.init();
  return klass;
};

Base.prototype = {
  extend: function(source, value) {
    if (arguments.length > 1) { // extending with a name/value pair
      var ancestor = this[source];
      if (ancestor && (typeof value == "function") && // overriding a method?
        // the valueOf() comparison is to avoid circular references
        (!ancestor.valueOf || ancestor.valueOf() != value.valueOf()) &&
        /\bbase\b/.test(value)) {
        // get the underlying method
        var method = value.valueOf();
        // override
        value = function() {
          var previous = this.base || Base.prototype.base;
          this.base = ancestor;
          var returnValue = method.apply(this, arguments);
          this.base = previous;
          return returnValue;
        };
        // point to the underlying method
        value.valueOf = function(type) {
          return (type == "object") ? value : method;
        };
        value.toString = Base.toString;
      }
      this[source] = value;
    } else if (source) { // extending with an object literal
      var extend = Base.prototype.extend;
      // if this object has a customised extend method then use it
      if (!Base._prototyping && typeof this != "function") {
        extend = this.extend || extend;
      }
      var proto = {toSource: null};
      // do the "toString" and other methods manually
      var hidden = ["constructor", "toString", "valueOf"];
      // if we are prototyping then include the constructor
      var i = Base._prototyping ? 0 : 1;
      while (key = hidden[i++]) {
        if (source[key] != proto[key]) {
          extend.call(this, key, source[key]);

        }
      }
      // copy each of the source object's properties to this object
      for (var key in source) {
        if (!proto[key]) extend.call(this, key, source[key]);
      }
    }
    return this;
  }
};

// initialise
Base = Base.extend({
  constructor: function() {
    this.extend(arguments[0]);
  }
}, {
  ancestor: Object,
  version: "1.1",

  forEach: function(object, block, context) {
    for (var key in object) {
      if (this.prototype[key] === undefined) {
        block.call(context, object[key], key, object);
      }
    }
  },

  implement: function() {
    for (var i = 0; i < arguments.length; i++) {
      if (typeof arguments[i] == "function") {
        // if it's a function, call it
        arguments[i](this.prototype);
      } else {
        // add the interface using the extend method
        this.prototype.extend(arguments[i]);
      }
    }
    return this;
  },

  toString: function() {
    return String(this.valueOf());
  }
});
<commit_msg>nuke class extension<commit_after><|endoftext|>


<commit_before>const turf = require('turf-inside')

function get(longitude, latitude, office = 'bucharest') {
  return turf({
    "type": "Feature",
    "properties": {},
    "geometry": {
      "type": "Point",
      "coordinates": [
        longitude,
        latitude
      ]
    }
  }, require(`./${office}-office`))
}
<commit_msg>Module exports.<commit_after>const turf = require('turf-inside')

module.exports = (longitude, latitude, office = 'bucharest') => {
  return turf({
    "type": "Feature",
    "properties": {},
    "geometry": {
      "type": "Point",
      "coordinates": [
        longitude,
        latitude
      ]
    }
  }, require(`./${office}-office`))
}
<|endoftext|>


<commit_before>/**
Image modifier utilities

Sample modifier strings, separated by a dash

  - /s50/path/to/image.png
  - /s50-gne/path/to/image.png
  - /w300-h200/path/to/image.png
  - /image.jpg
  - /path/to/image.png
  - /path/to/image.png.json

Supported modifiers are:

  - height:       eg. h500
  - width:        eg. w200
  - square:       eg. s50
  - crop:         eg. cfill
  - top:          eg. y12
  - left:         eg. x200
  - gravity:      eg. gs, gne
  - filter:       eg. fsepia
  - external:     eg. efacebook

Crop modifiers:
  fit
     - maintain original proportions
     - resize so image fits wholly into new dimensions
         - eg: h400-w500 - 400x600 -> 333x500
     - default option
  fill
     - maintain original proportions
     - resize via smallest dimension, crop the largest
     - crop image all dimensions that dont fit
         - eg: h400-w500 - 400x600 -> 400x500
  cut
     - maintain original proportions
     - no resize, crop to gravity or x/y
  scale
     - do not maintain original proportions
     - force image to be new dimensions (squishing the image)

*/
'use strict';

var _, string, filters, sources, filterKeys, sourceKeys, modifierMap,
    modKeys, env, fs, namedModifierMap;

_          = require('lodash');
string     = require('../utils/string');
filters    = require('../streams/filters');
sources    = require('../streams/sources');
filterKeys = _.keys(filters);
sourceKeys = _.keys(sources);
env        = require('../config/environment_vars');
fs         = require('fs');

modifierMap = [
  {
    key: 'h',
    desc: 'height',
    type: 'integer'
  },
  {
    key: 'w',
    desc: 'width',
    type: 'integer'
  },
  {
    key: 's',
    desc: 'square',
    type: 'integer'
  },
  {
    key: 'y',
    desc: 'top',
    type: 'integer'
  },
  {
    key: 'x',
    desc: 'left',
    type: 'integer'
  },
  {
    key: 'g',
    desc: 'gravity',
    type: 'string',
    values: ['c','n','s','e','w','ne','nw','se','sw'],
    default: 'c'
  },
  {
    key: 'c',
    desc: 'crop',
    type: 'string',
    values: ['fit','fill','cut','scale'],
    default: 'fit'
  },
  {
    key: 'e',
    desc: 'external',
    type: 'string',
    values: sourceKeys,
    default: env.DEFAULT_SOURCE
  },
  {
    key: 'f',
    desc: 'filter',
    type: 'string',
    values: filterKeys
  }
];

exports.map = modifierMap;

modKeys = _.map(modifierMap, function(value){
  return value.key;
});

function inArray(key, array){
  return _.indexOf(array, key) > -1;
}

function getModifier(key){
  var i, mod;

  for (i in modifierMap){
    mod = modifierMap[i];
    if (mod.key === key){
      return mod;
    }
  }
  return null;
}

exports.mod = getModifier;

// Check to see if there is a config file of named modifier aliases
if (fs.existsSync(process.cwd() + '/named_modifiers.json')){
  var file = fs.readFileSync(process.cwd() + '/named_modifiers.json');
  namedModifierMap = JSON.parse(file);
}

// Take an array of modifiers and parse the keys and values into mods hash
function parseModifiers(mods, modArr) {
  var key, value, mod;

  _.each(modArr, function(item){
    key = item[0];
    value = item.slice(1);

    if (inArray(key, modKeys)){

      // get the modifier object that responds to the listed key
      mod = getModifier(key);

      switch(mod.desc){
      case 'height':
        mods.height = string.sanitize(value) || null;
        break;
      case 'width':
        mods.width = string.sanitize(value) || null;
        break;
      case 'square':
        mods.action = 'square';
        mods.height = string.sanitize(value);
        mods.width = string.sanitize(value);
        break;
      case 'gravity':
        value = string.sanitize(value, 'alpha');
        if (inArray(value.toLowerCase(), mod.values)){
          mods.gravity = value.toLowerCase();
        }
        break;
      case 'top':
        mods.y = string.sanitize(value);
        break;
      case 'left':
        mods.x = string.sanitize(value);
        break;
      case 'crop':
        value = string.sanitize(value, 'alpha');
        if (inArray(value.toLowerCase(), mod.values)){
          mods.crop = value.toLowerCase();
        }
        break;
      case 'external':
        value = string.sanitize(value, 'alpha');
        if (inArray(value.toLowerCase(), mod.values)){
          mods.external = value.toLowerCase();
        }
        break;
      case 'filter':
        value = string.sanitize(value, 'alpha');
        if (inArray(value.toLowerCase(), mod.values)){
          mods.filter = value.toLowerCase();
        }
        break;
      }

    }
  });

  return mods;
}

// Exposed method to parse an incoming URL for modifiers, can add a map of
// named (preset) modifiers if need be (mostly just for unit testing). Named
// modifiers are usually added via config json file in root of application.
exports.parse = function(requestUrl, namedMods){
  var segments, mods, modStr, image, gravity, crop;

  gravity   = getModifier('g');
  crop      = getModifier('c');
  segments  = requestUrl.replace(/^\//,'').split('/');
  modStr    = _.first(segments);
  image     = _.last(segments).toLowerCase();
  namedMods = typeof namedMods === 'undefined' ? namedModifierMap : namedMods;

  // set the mod keys and defaults
  mods = {
    action: 'original',
    height: null,
    width: null,
    gravity: gravity.default,
    crop: crop.default
  };

  // check the request to see if it includes a named modifier
  if (namedMods && !_.isEmpty(namedMods)){
    if (_.has(namedMods, modStr)){
      _.forEach(namedMods[modStr], function(value, key){
        if (key === 'square'){
          mods.action = 'square';
          mods.height = value;
          mods.width = value;
        } else {
          mods[key] = value;
        }
      });
    }
  }

  // check the request for available modifiers, unless we are restricting to
  // only named modifiers.
  if (!env.NAMED_MODIFIERS_ONLY) {
    mods = parseModifiers(mods, modStr.split('-'));
  }

  // check to see if this a metadata call, it trumps all other requested mods
  if (image.slice(-5) === '.json'){
    mods.action = 'json';
    return mods;
  }

  if (mods.action === 'square'){
    // make sure crop is set to the default
    mods.crop = 'fill';
    return mods;
  }

  if (mods.height !== null || mods.width !== null){
    mods.action = 'resize';

    if (mods.crop !== crop.default){
      mods.action = 'crop';
    }
    if (mods.gravity !== gravity.default) {
      mods.action = 'crop';
    }
    if (_.has(mods, 'x') || _.has(mods, 'y')) {
      mods.action = 'crop';
    }
  }

  return mods;
};
<commit_msg>Disable json modifier<commit_after>/**
Image modifier utilities

Sample modifier strings, separated by a dash

  - /s50/path/to/image.png
  - /s50-gne/path/to/image.png
  - /w300-h200/path/to/image.png
  - /image.jpg
  - /path/to/image.png
  - /path/to/image.png.json

Supported modifiers are:

  - height:       eg. h500
  - width:        eg. w200
  - square:       eg. s50
  - crop:         eg. cfill
  - top:          eg. y12
  - left:         eg. x200
  - gravity:      eg. gs, gne
  - filter:       eg. fsepia
  - external:     eg. efacebook

Crop modifiers:
  fit
     - maintain original proportions
     - resize so image fits wholly into new dimensions
         - eg: h400-w500 - 400x600 -> 333x500
     - default option
  fill
     - maintain original proportions
     - resize via smallest dimension, crop the largest
     - crop image all dimensions that dont fit
         - eg: h400-w500 - 400x600 -> 400x500
  cut
     - maintain original proportions
     - no resize, crop to gravity or x/y
  scale
     - do not maintain original proportions
     - force image to be new dimensions (squishing the image)

*/
'use strict';

var _, string, filters, sources, filterKeys, sourceKeys, modifierMap,
    modKeys, env, fs, namedModifierMap;

_          = require('lodash');
string     = require('../utils/string');
filters    = require('../streams/filters');
sources    = require('../streams/sources');
filterKeys = _.keys(filters);
sourceKeys = _.keys(sources);
env        = require('../config/environment_vars');
fs         = require('fs');

modifierMap = [
  {
    key: 'h',
    desc: 'height',
    type: 'integer'
  },
  {
    key: 'w',
    desc: 'width',
    type: 'integer'
  },
  {
    key: 's',
    desc: 'square',
    type: 'integer'
  },
  {
    key: 'y',
    desc: 'top',
    type: 'integer'
  },
  {
    key: 'x',
    desc: 'left',
    type: 'integer'
  },
  {
    key: 'g',
    desc: 'gravity',
    type: 'string',
    values: ['c','n','s','e','w','ne','nw','se','sw'],
    default: 'c'
  },
  {
    key: 'c',
    desc: 'crop',
    type: 'string',
    values: ['fit','fill','cut','scale'],
    default: 'fit'
  },
  {
    key: 'e',
    desc: 'external',
    type: 'string',
    values: sourceKeys,
    default: env.DEFAULT_SOURCE
  },
  {
    key: 'f',
    desc: 'filter',
    type: 'string',
    values: filterKeys
  }
];

exports.map = modifierMap;

modKeys = _.map(modifierMap, function(value){
  return value.key;
});

function inArray(key, array){
  return _.indexOf(array, key) > -1;
}

function getModifier(key){
  var i, mod;

  for (i in modifierMap){
    mod = modifierMap[i];
    if (mod.key === key){
      return mod;
    }
  }
  return null;
}

exports.mod = getModifier;

// Check to see if there is a config file of named modifier aliases
if (fs.existsSync(process.cwd() + '/named_modifiers.json')){
  var file = fs.readFileSync(process.cwd() + '/named_modifiers.json');
  namedModifierMap = JSON.parse(file);
}

// Take an array of modifiers and parse the keys and values into mods hash
function parseModifiers(mods, modArr) {
  var key, value, mod;

  _.each(modArr, function(item){
    key = item[0];
    value = item.slice(1);

    if (inArray(key, modKeys)){

      // get the modifier object that responds to the listed key
      mod = getModifier(key);

      switch(mod.desc){
      case 'height':
        mods.height = string.sanitize(value) || null;
        break;
      case 'width':
        mods.width = string.sanitize(value) || null;
        break;
      case 'square':
        mods.action = 'square';
        mods.height = string.sanitize(value);
        mods.width = string.sanitize(value);
        break;
      case 'gravity':
        value = string.sanitize(value, 'alpha');
        if (inArray(value.toLowerCase(), mod.values)){
          mods.gravity = value.toLowerCase();
        }
        break;
      case 'top':
        mods.y = string.sanitize(value);
        break;
      case 'left':
        mods.x = string.sanitize(value);
        break;
      case 'crop':
        value = string.sanitize(value, 'alpha');
        if (inArray(value.toLowerCase(), mod.values)){
          mods.crop = value.toLowerCase();
        }
        break;
      case 'external':
        value = string.sanitize(value, 'alpha');
        if (inArray(value.toLowerCase(), mod.values)){
          mods.external = value.toLowerCase();
        }
        break;
      case 'filter':
        value = string.sanitize(value, 'alpha');
        if (inArray(value.toLowerCase(), mod.values)){
          mods.filter = value.toLowerCase();
        }
        break;
      }

    }
  });

  return mods;
}

// Exposed method to parse an incoming URL for modifiers, can add a map of
// named (preset) modifiers if need be (mostly just for unit testing). Named
// modifiers are usually added via config json file in root of application.
exports.parse = function(requestUrl, namedMods){
  var segments, mods, modStr, image, gravity, crop;

  gravity   = getModifier('g');
  crop      = getModifier('c');
  segments  = requestUrl.replace(/^\//,'').split('/');
  modStr    = _.first(segments);
  image     = _.last(segments).toLowerCase();
  namedMods = typeof namedMods === 'undefined' ? namedModifierMap : namedMods;

  // set the mod keys and defaults
  mods = {
    action: 'original',
    height: null,
    width: null,
    gravity: gravity.default,
    crop: crop.default
  };

  // check the request to see if it includes a named modifier
  if (namedMods && !_.isEmpty(namedMods)){
    if (_.has(namedMods, modStr)){
      _.forEach(namedMods[modStr], function(value, key){
        if (key === 'square'){
          mods.action = 'square';
          mods.height = value;
          mods.width = value;
        } else {
          mods[key] = value;
        }
      });
    }
  }

  // check the request for available modifiers, unless we are restricting to
  // only named modifiers.
  if (!env.NAMED_MODIFIERS_ONLY) {
    mods = parseModifiers(mods, modStr.split('-'));
  }

  // check to see if this a metadata call, it trumps all other requested mods
  // disabled
  // if (image.slice(-5) === '.json'){
  //   mods.action = 'json';
  //   return mods;
  // }

  if (mods.action === 'square'){
    // make sure crop is set to the default
    mods.crop = 'fill';
    return mods;
  }

  if (mods.height !== null || mods.width !== null){
    mods.action = 'resize';

    if (mods.crop !== crop.default){
      mods.action = 'crop';
    }
    if (mods.gravity !== gravity.default) {
      mods.action = 'crop';
    }
    if (_.has(mods, 'x') || _.has(mods, 'y')) {
      mods.action = 'crop';
    }
  }

  return mods;
};
<|endoftext|>


<commit_before>var EventEmitter = require('events').EventEmitter
var inherits     = require('util').inherits
var sqlite3      = require('sqlite3')
var Transaction  = require('any-db').Transaction;

module.exports = SQLite3

inherits(SQLite3, EventEmitter)
function SQLite3(db) {
	EventEmitter.call(this)
	this._db = db
	var self = this
	this._db.on('open',  function ()    { self.emit('open', self) })
	this._db.on('close', function ()    { self.emit('end') })
	this._db.on('error', function (err) { self.emit('error', err) })
}

SQLite3.createConnection = function (opts, callback) {
  requireDriver();

	var filename;

	if (opts.host) {
		filename = opts.host + (opts.database || '')
	} else {
		filename = opts.database
	}

	if (!filename || filename == '/:memory') filename = ':memory:'

  var mode = Object.keys(opts).map(function (k) {
    return (k == k.toUpperCase() && sqlite3[k]) | 0;
  }).reduce(function (mode, flag) {
    return mode | flag;
  }, 0)

	if (!mode) mode = (sqlite3.OPEN_READWRITE | sqlite3.OPEN_CREATE)

	var db = new sqlite3.Database(filename, mode)
    , adapter = new SQLite3(db)

	if (callback) {
		db.on('open', function () { callback(null, adapter) })
	}

	db.serialize()

	return adapter
}

SQLite3.createQuery = function (text, values, callback) {
  requireDriver();
	if (text instanceof Query) return text
	return new Query(text, values, callback)
}

SQLite3.prototype.query = function (text, values, callback) {
	var query = text
		, rowError = false
		;

  if (!(query instanceof Query)) {
    query = SQLite3.createQuery(text, values, callback);
  }

  if (query.text.match(/^\s*insert\s+/i)) {
    this._db.run(
      query.text,
      query.values,
      function onComplete(err) {
        if (err) return query.handleError(err)
        var result = { rows: [], rowCount: 0, lastInsertId: this.lastID }
        if (query._callback) query._callback(null, result)
        query.emit('end', result)
      }
    )
  }
  else {
    this._db.each(
      query.text,
      query.values,
      function onRow(err, row) {
        if (rowError) return
        rowError = err
        query.handleRow(row)
      },
      function onComplete(err, count) {
        if (err || rowError) return query.handleError(err || rowError)
        var result = {rows: query._rows, rowCount: count, lastInsertId: this.lastID}
        if (query._callback) query._callback(null, result)
        query.emit('end', result)
      }
    )
  }

	return query
}

SQLite3.prototype.begin = Transaction.createBeginMethod(SQLite3.createQuery)

SQLite3.prototype.end = function (callback) {
	if (callback) this.on('end', callback)
	this._db.close()
}

function requireDriver() {
  if (sqlite3) return;
  throw new Error("sqlite3 driver failed to load, please `npm install sqlite3`")
}

inherits(Query, EventEmitter)
function Query(text, values, callback) {
	EventEmitter.call(this)
	this._rows = []
	this._buffer = true
	this.text = text
	if (typeof values == 'function') {
		this._callback = values
		this.values = []
	} else {
		this.values = values
		this._callback = callback
	}
}

Query.prototype.handleRow = function (row) {
	if (this._callback) this._rows.push(row)
	this.emit('row', row)
}

Query.prototype.handleError = function (err) {
	if (this._callback) this._callback(err)
	else this.emit('error', err)
}
<commit_msg>Expose sqlite3's verbose option<commit_after>var EventEmitter = require('events').EventEmitter
var inherits     = require('util').inherits
var sqlite3      = require('sqlite3')
var Transaction  = require('any-db').Transaction;

module.exports = SQLite3

SQLite3.verbose = sqlite3.verbose;

inherits(SQLite3, EventEmitter)
function SQLite3(db) {
	EventEmitter.call(this)
	this._db = db
	var self = this
	this._db.on('open',  function ()    { self.emit('open', self) })
	this._db.on('close', function ()    { self.emit('end') })
	this._db.on('error', function (err) { self.emit('error', err) })
}

SQLite3.createConnection = function (opts, callback) {
  requireDriver();

	var filename;

	if (opts.host) {
		filename = opts.host + (opts.database || '')
	} else {
		filename = opts.database
	}

	if (!filename || filename == '/:memory') filename = ':memory:'

  var mode = Object.keys(opts).map(function (k) {
    return (k == k.toUpperCase() && sqlite3[k]) | 0;
  }).reduce(function (mode, flag) {
    return mode | flag;
  }, 0)

	if (!mode) mode = (sqlite3.OPEN_READWRITE | sqlite3.OPEN_CREATE)

	var db = new sqlite3.Database(filename, mode)
    , adapter = new SQLite3(db)

	if (callback) {
		db.on('open', function () { callback(null, adapter) })
	}

	db.serialize()

	return adapter
}

SQLite3.createQuery = function (text, values, callback) {
  requireDriver();
	if (text instanceof Query) return text
	return new Query(text, values, callback)
}

SQLite3.prototype.query = function (text, values, callback) {
	var query = text
		, rowError = false
		;

  if (!(query instanceof Query)) {
    query = SQLite3.createQuery(text, values, callback);
  }

  if (query.text.match(/^\s*insert\s+/i)) {
    this._db.run(
      query.text,
      query.values,
      function onComplete(err) {
        if (err) return query.handleError(err)
        var result = { rows: [], rowCount: 0, lastInsertId: this.lastID }
        if (query._callback) query._callback(null, result)
        query.emit('end', result)
      }
    )
  }
  else {
    this._db.each(
      query.text,
      query.values,
      function onRow(err, row) {
        if (rowError) return
        rowError = err
        query.handleRow(row)
      },
      function onComplete(err, count) {
        if (err || rowError) return query.handleError(err || rowError)
        var result = {rows: query._rows, rowCount: count, lastInsertId: this.lastID}
        if (query._callback) query._callback(null, result)
        query.emit('end', result)
      }
    )
  }

	return query
}

SQLite3.prototype.begin = Transaction.createBeginMethod(SQLite3.createQuery)

SQLite3.prototype.end = function (callback) {
	if (callback) this.on('end', callback)
	this._db.close()
}

function requireDriver() {
  if (sqlite3) return;
  throw new Error("sqlite3 driver failed to load, please `npm install sqlite3`")
}

inherits(Query, EventEmitter)
function Query(text, values, callback) {
	EventEmitter.call(this)
	this._rows = []
	this._buffer = true
	this.text = text
	if (typeof values == 'function') {
		this._callback = values
		this.values = []
	} else {
		this.values = values
		this._callback = callback
	}
}

Query.prototype.handleRow = function (row) {
	if (this._callback) this._rows.push(row)
	this.emit('row', row)
}

Query.prototype.handleError = function (err) {
	if (this._callback) this._callback(err)
	else this.emit('error', err)
}
<|endoftext|>


<commit_before>const util = require('./util');
const { getPromiseDetails } = process.binding('util');

/**
 * The class for deep checking Types
 */
class Type {

	/**
	 * @param {*} value The value to generate a deep Type of
	 * @param {Type} [parent=null] The parent value used in recursion
	 */
	constructor(value, parent = null) {
		/**
		 * The value to generate a deep Type of
		 * @since 0.5.0
		 * @type {*}
		 */
		this.value = value;

		/**
		 * The shallow type of this
		 * @since 0.5.0
		 * @type {string}
		 */
		this.is = this.constructor.resolve(value);

		/**
		 * The parent of this type
		 * @since 0.5.0
		 * @type {?Type}
		 * @private
		 */
		this.parent = parent;

		/**
		 * The child keys of this Type
		 * @since 0.5.0
		 * @type {Map<string, Type>}
		 * @private
		 */
		this.childKeys = new Map();

		/**
		 * The child values of this Type
		 * @since 0.5.0
		 * @type {Map<string, Type>}
		 * @private
		 */
		this.childValues = new Map();
	}

	/**
	 * The type string for the children of this Type
	 * @since 0.5.0
	 * @type {string}
	 * @readonly
	 * @private
	 */
	get childTypes() {
		if (!this.childValues.size) return '';
		return `<${(this.childKeys.size ? `${this.constructor.list(this.childKeys)}, ` : '') + this.constructor.list(this.childValues)}>`;
	}

	/**
	 * The full type string generated.
	 * @since 0.5.0
	 * @returns {string}
	 */
	toString() {
		this.check();
		return this.is + this.childTypes;
	}

	/**
	 * The subtype to create based on this.value's sub value.
	 * @since 0.5.0
	 * @param {*} value The sub value
	 * @private
	 */
	addValue(value) {
		const child = new this.constructor(value, this);
		this.childValues.set(child.is, child);
	}

	/**
	 * The subtype to create based on this.value's entries.
	 * @since 0.5.0
	 * @param {Array<string, *>} entry the entry
	 * @private
	 */
	addEntry([key, value]) {
		const child = new this.constructor(key, this);
		this.childKeys.set(child.is, child);
		this.addValue(value);
	}

	/**
	 * Walks the linked list backwards, for checking circulars.
	 * @since 0.5.0
	 * @yields {?Type}
	 * @private
	 */
	*parents() {
		// eslint-disable-next-line consistent-this
		let current = this;
		// eslint-disable-next-line no-cond-assign
		while (current = current.parent) yield current;
	}

	/**
	 * Get the deep type name that defines the input.
	 * @since 0.5.0
	 * @private
	 */
	check() {
		if (Object.isFrozen(this)) return;
		const promise = util.isThenable(this.value) && getPromiseDetails(this.value);
		if (typeof this.value === 'object' && this.isCircular()) this.is = `[Circular:${this.is}]`;
		else if (promise && promise[0]) this.addValue(promise[1]);
		else if (this.value instanceof Map) for (const entry of this.value) this.addEntry(entry);
		else if (Array.isArray(this.value) || this.value instanceof Set) for (const value of this.value) this.addValue(value);
		else if (this.is === 'Object') this.is = 'any';
		Object.freeze(this);
	}

	/**
	 * Checks if the value of this Type is a circular reference to any parent.
	 * @since 0.5.0
	 * @returns {boolean}
	 * @private
	 */
	isCircular() {
		for (const parent of this.parents()) if (parent.value === this.value) return true;
		return false;
	}

	/**
	 * Resolves the type name that defines the input.
	 * @since 0.5.0
	 * @param {*} value The value to get the type name of
	 * @returns {string}
	 */
	static resolve(value) {
		const type = typeof value;
		switch (type) {
			case 'object': return value === null ? 'null' : value.constructor ? value.constructor.name : 'any';
			case 'function': return `${value.constructor.name}(${value.length}-arity)`;
			case 'undefined': return 'void';
			default: return type;
		}
	}

	/**
	 * Joins the list of child types.
	 * @since 0.5.0
	 * @param {Map<string, Type>} values The values to list
	 * @returns {string}
	 * @private
	 */
	static list(values) {
		return values.has('any') ? 'any' : [...values.values()].sort().join(' | ');
	}

}

module.exports = Type;
<commit_msg>fix: Replace process.binding usage with native v8 (#470)<commit_after>require('v8').setFlagsFromString('--allow-natives-syntax');
const getPromiseDetails = require('vm').runInThisContext(
	'p => p instanceof Promise ? { status: %PromiseStatus(p), result: %PromiseResult(p) } : null;');

/**
 * The class for deep checking Types
 */
class Type {

	/**
	 * @param {*} value The value to generate a deep Type of
	 * @param {Type} [parent=null] The parent value used in recursion
	 */
	constructor(value, parent = null) {
		/**
		 * The value to generate a deep Type of
		 * @since 0.5.0
		 * @type {*}
		 */
		this.value = value;

		/**
		 * The shallow type of this
		 * @since 0.5.0
		 * @type {string}
		 */
		this.is = this.constructor.resolve(value);

		/**
		 * The parent of this type
		 * @since 0.5.0
		 * @type {?Type}
		 * @private
		 */
		this.parent = parent;

		/**
		 * The child keys of this Type
		 * @since 0.5.0
		 * @type {Map<string, Type>}
		 * @private
		 */
		this.childKeys = new Map();

		/**
		 * The child values of this Type
		 * @since 0.5.0
		 * @type {Map<string, Type>}
		 * @private
		 */
		this.childValues = new Map();
	}

	/**
	 * The type string for the children of this Type
	 * @since 0.5.0
	 * @type {string}
	 * @readonly
	 * @private
	 */
	get childTypes() {
		if (!this.childValues.size) return '';
		return `<${(this.childKeys.size ? `${this.constructor.list(this.childKeys)}, ` : '') + this.constructor.list(this.childValues)}>`;
	}

	/**
	 * The full type string generated.
	 * @since 0.5.0
	 * @returns {string}
	 */
	toString() {
		this.check();
		return this.is + this.childTypes;
	}

	/**
	 * The subtype to create based on this.value's sub value.
	 * @since 0.5.0
	 * @param {*} value The sub value
	 * @private
	 */
	addValue(value) {
		const child = new this.constructor(value, this);
		this.childValues.set(child.is, child);
	}

	/**
	 * The subtype to create based on this.value's entries.
	 * @since 0.5.0
	 * @param {Array<string, *>} entry the entry
	 * @private
	 */
	addEntry([key, value]) {
		const child = new this.constructor(key, this);
		this.childKeys.set(child.is, child);
		this.addValue(value);
	}

	/**
	 * Walks the linked list backwards, for checking circulars.
	 * @since 0.5.0
	 * @yields {?Type}
	 * @private
	 */
	*parents() {
		// eslint-disable-next-line consistent-this
		let current = this;
		// eslint-disable-next-line no-cond-assign
		while (current = current.parent) yield current;
	}

	/**
	 * Get the deep type name that defines the input.
	 * @since 0.5.0
	 * @private
	 */
	check() {
		if (Object.isFrozen(this)) return;
		const promise = getPromiseDetails(this.value);
		if (typeof this.value === 'object' && this.isCircular()) this.is = `[Circular:${this.is}]`;
		else if (promise && promise.status) this.addValue(promise.result);
		else if (this.value instanceof Map) for (const entry of this.value) this.addEntry(entry);
		else if (Array.isArray(this.value) || this.value instanceof Set) for (const value of this.value) this.addValue(value);
		else if (this.is === 'Object') this.is = 'any';
		Object.freeze(this);
	}

	/**
	 * Checks if the value of this Type is a circular reference to any parent.
	 * @since 0.5.0
	 * @returns {boolean}
	 * @private
	 */
	isCircular() {
		for (const parent of this.parents()) if (parent.value === this.value) return true;
		return false;
	}

	/**
	 * Resolves the type name that defines the input.
	 * @since 0.5.0
	 * @param {*} value The value to get the type name of
	 * @returns {string}
	 */
	static resolve(value) {
		const type = typeof value;
		switch (type) {
			case 'object': return value === null ? 'null' : value.constructor ? value.constructor.name : 'any';
			case 'function': return `${value.constructor.name}(${value.length}-arity)`;
			case 'undefined': return 'void';
			default: return type;
		}
	}

	/**
	 * Joins the list of child types.
	 * @since 0.5.0
	 * @param {Map<string, Type>} values The values to list
	 * @returns {string}
	 * @private
	 */
	static list(values) {
		return values.has('any') ? 'any' : [...values.values()].sort().join(' | ');
	}

}

module.exports = Type;
<|endoftext|>


<commit_before>require('../../support');
var _ = require('ramda');

// Exercise 1
//==============
// Refactor to remove all arguments by partially applying the function

// var words = function (str) {
//   return split(' ', str);
// };

var words = _.split(' ');

// Exercise 1a
//==============
// Use map to make a new words fn that works on an array of strings.

var sentences = _.map(words);

// Exercise 2
//==============
// Refactor to remove all arguments by partially applying the functions

// var filterQs = function (xs) {
//   return filter(function (x) { return match(/q/i, x);  }, xs);
// };

var matchQs = match(/q/i);
var filterQs = filter(matchQs);

// Exercise 3
//==============
// Use the helper function _keepHighest to refactor max to not reference any arguments

// LEAVE BE:
var _keepHighest = function(x,y){ return x >= y ? x : y; };

// REFACTOR THIS ONE:
// var max = function (xs) {
//   return reduce(function (acc, x) {
//     return _keepHighest(acc, x);
//   }, 0, xs);
// };

var max = reduce(_keepHighest, 0);

// Bonus 1:
// ============
// wrap array's slice to be functional and curried.
// //[1,2,3].slice(0, 2)
var slice = undefined;

// Bonus 2:
// ============
// use slice to define a function "take" that takes n elements. Make it curried
var take = undefined;

module.exports = { words: words,
                   sentences: sentences,
                   filterQs: filterQs,
                   max: max,
                   slice: slice,
                   take: take
                 };
<commit_msg>Curry - bonus exercise 1<commit_after>require('../../support');
var _ = require('ramda');

// Exercise 1
//==============
// Refactor to remove all arguments by partially applying the function

// var words = function (str) {
//   return split(' ', str);
// };

var words = _.split(' ');

// Exercise 1a
//==============
// Use map to make a new words fn that works on an array of strings.

var sentences = _.map(words);

// Exercise 2
//==============
// Refactor to remove all arguments by partially applying the functions

// var filterQs = function (xs) {
//   return filter(function (x) { return match(/q/i, x);  }, xs);
// };

var matchQs = match(/q/i);
var filterQs = filter(matchQs);

// Exercise 3
//==============
// Use the helper function _keepHighest to refactor max to not reference any arguments

// LEAVE BE:
var _keepHighest = function(x,y){ return x >= y ? x : y; };

// REFACTOR THIS ONE:
// var max = function (xs) {
//   return reduce(function (acc, x) {
//     return _keepHighest(acc, x);
//   }, 0, xs);
// };

var max = reduce(_keepHighest, 0);

// Bonus 1:
// ============
// wrap array's slice to be functional and curried.
// //[1,2,3].slice(0, 2)
var slice = _.curry(function (x, y, xs) { return xs.slice(x, y); });

// Bonus 2:
// ============
// use slice to define a function "take" that takes n elements. Make it curried
var take = undefined;

module.exports = { words: words,
                   sentences: sentences,
                   filterQs: filterQs,
                   max: max,
                   slice: slice,
                   take: take
                 };
<|endoftext|>


<commit_before>var app = require('express');
const router = app.Router({ mergeParams: true });

var retrieval = require('../retrieval/retrieval');
var schedule  = require('./algorithms-courseformat/courseMatrixUsage')

router.get('/', function(req, res){
    if (!req.query.hasOwnProperty('courses')){
        res.status(400).json({message:"Make sure to include an courses GET parameter as JSON array"});
    }

    var courseSelection = JSON.parse(req.query.courses);
    var coursesLen = courseSelection.length;
    var courses = [];

    courseSelection.forEach(function(element) {
        retrieval.getSingleCourseByCode(element, function(course){
            if (course){
                courses.push(course);
            }
        });
        if (courses.length == coursesLen){
            var sched = schedule.genScheds(courses);
            res.status(200).json({data:sched});
        }
    }, this);
})

module.exports = router;<commit_msg>API Bug Fix; Scheduling logic still of interest.<commit_after>var app = require('express');
const router = app.Router({ mergeParams: true });

var retrieval = require('../retrieval/retrieval');
var schedule  = require('./algorithms-courseformat/courseMatrixUsage')

router.get('/', function(req, res){
    if (!req.query.hasOwnProperty('courses')){
        res.status(400).json({message:"Make sure to include an courses GET parameter as JSON array"});
    }

    var courseSelection = JSON.parse(req.query.courses);
    var coursesLen = courseSelection.length;
    var courses = [];

    courseSelection.forEach(function(element) {
        retrieval.getSingleCourseByCode(element, function(course){
            if (course){
                courses.push(course);
            }
            else {
                --coursesLen;
            }
            if (courses.length == coursesLen){
                var sched = schedule.genScheds(courses);
                res.status(200).json({data:sched});
            }
        });

    }, this);
})

module.exports = router;<|endoftext|>


<commit_before>const { callGeocoder, mergeGeocoderResults } = require('./geocoder');
const searchCivicAddressId = require('./contexts/searchCivicAddressId');
const searchPin = require('./contexts/searchPin');
const searchNeighborhood = require('./contexts/searchNeighborhood');
const searchOwner = require('./contexts/searchOwner');
const searchProperty = require('./contexts/searchProperty');
const searchStreet = require('./contexts/searchStreet');
const searchAddress = require('./contexts/searchAddress');
const searchPlace = require('./contexts/searchPlace');

// Context options: address, pin, neighborhood, property, civicAddressId, street, owner, google
function performSearch(searchString, searchContext, geoCodeResponse, context) {
  if (searchContext === 'civicAddressId') {
    return searchCivicAddressId(searchString, context);
  } else if (searchContext === 'pin') {
    return searchPin(searchString, context);
  } else if (searchContext === 'address') {
    return searchAddress(searchContext, searchString, geoCodeResponse, context);
  } else if (searchContext === 'property') {
    return searchProperty(searchString, geoCodeResponse, context);
  } else if (searchContext === 'street') {
    return searchStreet(searchContext, searchString, geoCodeResponse, context);
  } else if (searchContext === 'neighborhood') {
    return searchNeighborhood(searchString, context);
  } else if (searchContext === 'owner') {
    return searchOwner(searchString, context);
  } else if (searchContext === 'place') {
    return searchPlace(searchString, context);
  }
  throw new Error(`Unknown search context ${searchContext}`);
}

const resolvers = {
  Query: {
    search(obj, args, context) {
      const geoCodeResponse = [];

      if (args.searchContexts.indexOf('address') >= 0 ||
          args.searchContexts.indexOf('property') >= 0 ||
          args.searchContexts.indexOf('street') >= 0) {
        geoCodeResponse.push(callGeocoder(args.searchString, 'address'));
      }
      if (args.searchContexts.indexOf('street') >= 0) {
        geoCodeResponse.push(callGeocoder(args.searchString, 'street'));
      }
      if (geoCodeResponse.length === 0) geoCodeResponse.push(Promise.resolve(null));

      return Promise.all(geoCodeResponse).then(results => {
        const result = mergeGeocoderResults(results);
        return Promise.all(args.searchContexts.map((searchContext) => {
          const ret = performSearch(args.searchString, searchContext, result, context);
          return ret;
        }));
      })
      .catch((err) => {
        if (err) {
          console.log(`Got an error in search: ${err}`);
          throw new Error(err);
        }
      });
    },
  },

  NeighborhoodResult: {
    polygon(obj) {
      return obj.polygon;
    },
  },

  TypedSearchResult: {
    type(obj) {return obj.type;},
    results(obj, args, context) {
      return obj.results;
    },
  },

  SearchResult: {
    __resolveType(data, context, info) {
      if (data.type === 'civicAddressId') {
        return info.schema.getType('AddressResult');
      } else if (data.type === 'address') {
        return info.schema.getType('AddressResult');
      } else if (data.type === 'property') {
        return info.schema.getType('PropertyResult');
      } else if (data.type === 'pin') {
        return info.schema.getType('PropertyResult');
      } else if (data.type === 'street') {
        return info.schema.getType('StreetResult');
      } else if (data.type === 'neighborhood') {
        return info.schema.getType('NeighborhoodResult');
      } else if (data.type === 'owner') {
        return info.schema.getType('OwnerResult');
      } else if (data.type === 'place') {
        return info.schema.getType('PlaceResult');
      }
      return info.schema.getType('SillyResult');
    },
  },
};

module.exports = resolvers;
<commit_msg>Added some timing<commit_after>const { callGeocoder, mergeGeocoderResults } = require('./geocoder');
const searchCivicAddressId = require('./contexts/searchCivicAddressId');
const searchPin = require('./contexts/searchPin');
const searchNeighborhood = require('./contexts/searchNeighborhood');
const searchOwner = require('./contexts/searchOwner');
const searchProperty = require('./contexts/searchProperty');
const searchStreet = require('./contexts/searchStreet');
const searchAddress = require('./contexts/searchAddress');
const searchPlace = require('./contexts/searchPlace');

// Context options: address, pin, neighborhood, property, civicAddressId, street, owner, google
function performSearch(searchString, searchContext, geoCodeResponse, context) {
  if (searchContext === 'civicAddressId') {
    return searchCivicAddressId(searchString, context);
  } else if (searchContext === 'pin') {
    return searchPin(searchString, context);
  } else if (searchContext === 'address') {
    return searchAddress(searchContext, searchString, geoCodeResponse, context);
  } else if (searchContext === 'property') {
    return searchProperty(searchString, geoCodeResponse, context);
  } else if (searchContext === 'street') {
    return searchStreet(searchContext, searchString, geoCodeResponse, context);
  } else if (searchContext === 'neighborhood') {
    return searchNeighborhood(searchString, context);
  } else if (searchContext === 'owner') {
    return searchOwner(searchString, context);
  } else if (searchContext === 'place') {
    return searchPlace(searchString, context);
  }
  throw new Error(`Unknown search context ${searchContext}`);
}

const resolvers = {
  Query: {
    search(obj, args, context) {
      const geoCodeResponse = [];
      let startTime = new Date().getTime();
      if (args.searchContexts.indexOf('address') >= 0 ||
          args.searchContexts.indexOf('property') >= 0 ||
          args.searchContexts.indexOf('street') >= 0) {
        geoCodeResponse.push(callGeocoder(args.searchString, 'address'));
      }
      if (args.searchContexts.indexOf('street') >= 0) {
        geoCodeResponse.push(callGeocoder(args.searchString, 'street'));
      }
      if (geoCodeResponse.length === 0) geoCodeResponse.push(Promise.resolve(null));

      return Promise.all(geoCodeResponse).then(results => {
        let endTime = new Date().getTime();
        console.log(`Geocoder time: ${(endTime - startTime) / 1000.0} seconds`);
        startTime = endTime;
        const result = mergeGeocoderResults(results);
        return Promise.all(args.searchContexts.map((searchContext) => {
          const ret = performSearch(args.searchString, searchContext, result, context);
          endTime = new Date().getTime();
          console.log(`Search time (${searchContext}): ${(endTime - startTime) / 1000.0} seconds`);
          return ret;
        }));
      })
      .catch((err) => {
        if (err) {
          console.log(`Got an error in search: ${err}`);
          throw new Error(err);
        }
      });
    },
  },

  NeighborhoodResult: {
    polygon(obj) {
      return obj.polygon;
    },
  },

  TypedSearchResult: {
    type(obj) {return obj.type;},
    results(obj, args, context) {
      return obj.results;
    },
  },

  SearchResult: {
    __resolveType(data, context, info) {
      if (data.type === 'civicAddressId') {
        return info.schema.getType('AddressResult');
      } else if (data.type === 'address') {
        return info.schema.getType('AddressResult');
      } else if (data.type === 'property') {
        return info.schema.getType('PropertyResult');
      } else if (data.type === 'pin') {
        return info.schema.getType('PropertyResult');
      } else if (data.type === 'street') {
        return info.schema.getType('StreetResult');
      } else if (data.type === 'neighborhood') {
        return info.schema.getType('NeighborhoodResult');
      } else if (data.type === 'owner') {
        return info.schema.getType('OwnerResult');
      } else if (data.type === 'place') {
        return info.schema.getType('PlaceResult');
      }
      return info.schema.getType('SillyResult');
    },
  },
};

module.exports = resolvers;
<|endoftext|>


<commit_before>import {createAction} from 'redux-actions';
import {CHANNEL} from './../../backend/messageHandler';
import {TASKS} from './../../backend/tasks';
const ipcRenderer = require('electron').ipcRenderer;

export const NEW_SESSION = 'NEW_SESSION';
export const SWITCH_SESSION = 'SWITCH_SESSION';
export const FORGET_SESSION = 'FORGET_SESSION';

export const newSession = createAction(NEW_SESSION);
export const switchSession = createAction(SWITCH_SESSION);
export const forgetSession = createAction(FORGET_SESSION);

// update calls
export const UPDATE_CONNECTION = 'UPDATE_CONNECTION';
export const UPDATE_CONFIGURATION = 'UPDATE_CONFIGURATION';
export const UPDATE_IPC_STATE = 'UPDATE_IPC_STATE';

export const updateConnection = createAction(UPDATE_CONNECTION);
export const updateConfiguration = createAction(UPDATE_CONFIGURATION);
export const updateIpcState = createAction(UPDATE_IPC_STATE);

// ipc specific ->

export function query (statement) {
    return (_, getState) => {
        const state = getState();
        const sessionSelected = state.sessions.get('sessionSelected');
        const database = state.sessions[sessionSelected].configuration.database;
        ipcSend(TASKS.QUERY, sessionSelected, database, statement);
    };
}

export function connect () {
    return (_, getState) => {
        const state = getState();
        const sessionSelected = state.sessions.get('sessionSelected');
        const configuration = state.sessions.getIn(
            ['list', sessionSelected, 'configuration']
        ).toJS();
        ipcSend(
            TASKS.CONNECT_AND_SHOW_DATABASES,
            sessionSelected,
            configuration.database,
            configuration
        );
    };
}

export function deleteSession (sessionId) {
    return (_, getState) => {
        ipcSend(TASKS.DELETE_SESSION, sessionId, null, sessionId);
    };
}

export function selectDatabase () {
    return (_, getState) => {
        const state = getState();
        const sessionSelected = state.sessions.get('sessionSelected');
        const configuration = state.sessions.getIn(
            ['list', sessionSelected, 'configuration']
        ).toJS();
        ipcSend(
            TASKS.SELECT_DATABASE_AND_SHOW_TABLES,
            sessionSelected,
            configuration.database,
            configuration.database
        );
    };
}

export function previewTables (tableNames) {
    return (_, getState) => {
        const state = getState();
        const sessionSelected = state.sessions.get('sessionSelected');
        const database = state.sessions.getIn(
            ['list', sessionSelected, 'configuration']
        ).toJS().database;
        ipcSend(TASKS.PREVIEW, sessionSelected, database, tableNames);
    };
}

export function disconnect () {
    return (_, getState) => {
        const state = getState();
        const sessionSelected = state.sessions.get('sessionSelected');
        const database = state.sessions.getIn(
            ['list', sessionSelected, 'configuration']
        ).toJS().database;
        ipcSend(TASKS.DISCONNECT, sessionSelected, database);
    };
}

export function setupHttpsServer () {
    return (__, getState) => {
        const state = getState();
        const sessionSelected = state.sessions.get('sessionSelected');
        ipcSend(TASKS.SETUP_HTTPS_SERVER, sessionSelected);
    };
}

export function newOnPremSession (domain) {
    return (__, getState) => {
        const state = getState();
        const sessionSelected = state.sessions.get('sessionSelected');
        ipcSend(TASKS.NEW_ON_PREM_SESSION, sessionSelected, null, domain);
    };
}

function ipcSend(task, sessionSelected, database, message = {}) {
    ipcRenderer.send(CHANNEL, {task, sessionSelected, database, message});
}

// <- ipc specific
<commit_msg>:wrench: minor comment<commit_after>import {createAction} from 'redux-actions';
import {CHANNEL} from './../../backend/messageHandler';
import {TASKS} from './../../backend/tasks';
const ipcRenderer = require('electron').ipcRenderer;

export const NEW_SESSION = 'NEW_SESSION';
export const SWITCH_SESSION = 'SWITCH_SESSION';
export const FORGET_SESSION = 'FORGET_SESSION';

export const newSession = createAction(NEW_SESSION);
export const switchSession = createAction(SWITCH_SESSION);
export const forgetSession = createAction(FORGET_SESSION);

// update calls
export const UPDATE_CONNECTION = 'UPDATE_CONNECTION';
export const UPDATE_CONFIGURATION = 'UPDATE_CONFIGURATION';
export const UPDATE_IPC_STATE = 'UPDATE_IPC_STATE';

export const updateConnection = createAction(UPDATE_CONNECTION);
export const updateConfiguration = createAction(UPDATE_CONFIGURATION);
export const updateIpcState = createAction(UPDATE_IPC_STATE);

// ipc specific ->

export function query (statement) {
    return (_, getState) => {
        const state = getState();
        const sessionSelected = state.sessions.get('sessionSelected');
        const database = state.sessions[sessionSelected].configuration.database;
        ipcSend(TASKS.QUERY, sessionSelected, database, statement);
    };
}

export function connect () {
    return (_, getState) => {
        const state = getState();
        const sessionSelected = state.sessions.get('sessionSelected');
        const configuration = state.sessions.getIn(
            ['list', sessionSelected, 'configuration']
        ).toJS();
        ipcSend(
            TASKS.CONNECT_AND_SHOW_DATABASES,
            sessionSelected,
            configuration.database,
            configuration
        );
    };
}

export function deleteSession (sessionId) {
    return (_, getState) => {
        ipcSend(TASKS.DELETE_SESSION, sessionId, null, sessionId);
    };
}

export function selectDatabase () {
    return (_, getState) => {
        const state = getState();
        const sessionSelected = state.sessions.get('sessionSelected');
        const configuration = state.sessions.getIn(
            ['list', sessionSelected, 'configuration']
        ).toJS();
        ipcSend(
            TASKS.SELECT_DATABASE_AND_SHOW_TABLES,
            sessionSelected,
            configuration.database,
            configuration.database
        );
    };
}

export function previewTables (tableNames) {
    return (_, getState) => {
        const state = getState();
        const sessionSelected = state.sessions.get('sessionSelected');
        const database = state.sessions.getIn(
            ['list', sessionSelected, 'configuration', 'database']);
        ipcSend(TASKS.PREVIEW, sessionSelected, database, tableNames);
    };
}

export function disconnect () {
    return (_, getState) => {
        const state = getState();
        const sessionSelected = state.sessions.get('sessionSelected');
        const database = state.sessions.getIn(
            ['list', sessionSelected, 'configuration', 'database']);
        ipcSend(TASKS.DISCONNECT, sessionSelected, database);
    };
}

export function setupHttpsServer () {
    return (__, getState) => {
        const state = getState();
        const sessionSelected = state.sessions.get('sessionSelected');
        ipcSend(TASKS.SETUP_HTTPS_SERVER, sessionSelected);
    };
}

export function newOnPremSession (domain) {
    return (__, getState) => {
        const state = getState();
        const sessionSelected = state.sessions.get('sessionSelected');
        ipcSend(TASKS.NEW_ON_PREM_SESSION, sessionSelected, null, domain);
    };
}

function ipcSend(task, sessionSelected, database, message = {}) {
    ipcRenderer.send(CHANNEL, {task, sessionSelected, database, message});
}

// <- ipc specific
<|endoftext|>