<commit_before>/**
 * controller.js
 * @flow weak
 */

import $ from "jquery";
import _ from "lodash";
import app from "app";
import Utils from "libs/utils";
import Backbone from "backbone";
import Stats from "stats.js";
import { InputKeyboardNoLoop } from "libs/input";
import Toast from "libs/toast";
import Model from "oxalis/model";
import PlaneController from "oxalis/controller/viewmodes/plane_controller";
import SkeletonTracingController from "oxalis/controller/annotations/skeletontracing_controller";
import VolumeTracingController from "oxalis/controller/annotations/volumetracing_controller";
import SkeletonTracingArbitraryController from "oxalis/controller/combinations/skeletontracing_arbitrary_controller";
import SkeletonTracingPlaneController from "oxalis/controller/combinations/skeletontracing_plane_controller";
import VolumeTracingPlaneController from "oxalis/controller/combinations/volumetracing_plane_controller";
import ArbitraryController from "oxalis/controller/viewmodes/arbitrary_controller";
import MinimalArbitraryController from "oxalis/controller/combinations/minimal_skeletontracing_arbitrary_controller";
import SceneController from "oxalis/controller/scene_controller";
import UrlManager from "oxalis/controller/url_manager";
import View from "oxalis/view";
import SkeletonTracingView from "oxalis/view/skeletontracing/skeletontracing_view";
import VolumeTracingView from "oxalis/view/volumetracing/volumetracing_view";
import constants from "oxalis/constants";

import type { ToastType } from "libs/toast";

class Controller {

  model: Model;
  urlManager: UrlManager;
  sceneController: SceneController;
  view: View;
  annotationController: SkeletonTracingController | VolumeTracingController;
  planeController: PlaneController;
  arbitraryController: ArbitraryController;
  zoomStepWarningToast: ToastType;
  keyboardNoLoop: InputKeyboardNoLoop;

  // Copied from backbone events (TODO: handle this better)
  listenTo: Function;

  // Main controller, responsible for setting modes and everything
  // that has to be controlled in any mode.
  //
  // We have a matrix of modes like this:
  //
  //   Annotation Mode \ View mode    Plane       Arbitrary
  //              Skeleton Tracing      X             X
  //                Volume Tracing      X             /
  //
  // In order to maximize code reuse, there is - besides the main
  // controller - a controller for each row, each column and each
  // cross in this matrix.

  constructor(options) {
    this.model = options.model;

    _.extend(this, Backbone.Events);

    this.urlManager = new UrlManager(this.model);
    this.model.set("state", this.urlManager.initialState);

    this.model.fetch()
        .then(() => this.modelFetchDone())
        .catch((error) => {
          // Don't throw errors for errors already handled by the model.
          if (error !== this.model.HANDLED_ERROR) {
            throw error;
          }
        },
        );
  }

  modelFetchDone() {
    if (!this.model.tracing.restrictions.allowAccess) {
      Toast.Error("You are not allowed to access this tracing");
      return;
    }

    app.router.on("beforeunload", () => {
      if (this.model.get("controlMode") === constants.CONTROL_MODE_TRACE) {
        const { stateLogger } = this.model.annotationModel;
        if (!stateLogger.stateSaved() && stateLogger.allowUpdate) {
          stateLogger.pushNow();
          return "You haven't saved your progress, please give us 2 seconds to do so and and then leave this site.";
        }
      }
      return null;
    },
    );

    this.urlManager.startUrlUpdater();

    this.sceneController = new SceneController(this.model);

    if (this.model.skeletonTracing != null) {
      this.view = new SkeletonTracingView(this.model);
      this.annotationController = new SkeletonTracingController(
        this.model, this.view, this.sceneController);
      this.planeController = new SkeletonTracingPlaneController(
        this.model, this.view, this.sceneController, this.annotationController);

      const ArbitraryControllerClass = this.model.tracing.content.settings.advancedOptionsAllowed ? SkeletonTracingArbitraryController : MinimalArbitraryController;
      this.arbitraryController = new ArbitraryControllerClass(
        this.model, this.view, this.sceneController, this.annotationController);
    } else if (this.model.volumeTracing != null) {
      this.view = new VolumeTracingView(this.model);
      this.annotationController = new VolumeTracingController(
        this.model, this.view, this.sceneController);
      this.planeController = new VolumeTracingPlaneController(
        this.model, this.view, this.sceneController, this.annotationController);
    } else {
      // View mode

      this.view = new View(this.model);
      this.planeController = new PlaneController(
        this.model, this.view, this.sceneController);
    }

    // FPS stats
    const stats = new Stats();
    $("body").append(stats.domElement);
    if (this.arbitraryController) { this.listenTo(this.arbitraryController.arbitraryView, "render", () => stats.update()); }
    this.listenTo(this.planeController.planeView, "render", () => stats.update());

    this.initKeyboard();
    this.initTimeLimit();

    for (const binaryName of Object.keys(this.model.binary)) {
      this.listenTo(this.model.binary[binaryName].cube, "bucketLoaded", () => app.vent.trigger("rerender"));
    }

    this.listenTo(this.model, "change:mode", this.loadMode);
    this.loadMode(this.model.get("mode"));

    // Zoom step warning
    this.zoomStepWarningToast = null;
    this.listenTo(this.model.flycam, "zoomStepChanged", this.onZoomStepChange);
    this.onZoomStepChange();

    app.vent.trigger("webknossos:ready");
  }

  initKeyboard() {
    // avoid scrolling while pressing space
    $(document).keydown((event) => {
      if ((event.which === 32 || event.which === 18 || event.which >= 37 && event.which <= 40) && !$(":focus").length) { event.preventDefault(); }
    });

    const keyboardControls = {};

    if (this.model.get("controlMode") === constants.CONTROL_MODE_TRACE) {
      _.extend(keyboardControls, {
        // Set Mode, outcomment for release
        "shift + 1": () => this.model.setMode(constants.MODE_PLANE_TRACING),
        "shift + 2": () => this.model.setMode(constants.MODE_ARBITRARY),
        "shift + 3": () => this.model.setMode(constants.MODE_ARBITRARY_PLANE),

        t: () => this.view.toggleTheme(),

        m: () => {
          // rotate allowed modes
          const index = (this.model.allowedModes.indexOf(this.model.get("mode")) + 1) % this.model.allowedModes.length;
          this.model.setMode(this.model.allowedModes[index]);
        },

        "super + s": (event) => {
          event.preventDefault();
          event.stopPropagation();
          this.model.save();
        },

        "ctrl + s": (event) => {
          event.preventDefault();
          event.stopPropagation();
          this.model.save();
        },

      });
    }

    this.keyboardNoLoop = new InputKeyboardNoLoop(keyboardControls);
  }

  loadMode(newMode, force = false) {
    if ((newMode === constants.MODE_ARBITRARY || newMode === constants.MODE_ARBITRARY_PLANE) && (this.model.allowedModes.includes(newMode) || force)) {
      Utils.__guard__(this.planeController, x => x.stop());
      this.arbitraryController.start(newMode);
    } else if ((newMode === constants.MODE_PLANE_TRACING || newMode === constants.MODE_VOLUME) && (this.model.allowedModes.includes(newMode) || force)) {
      Utils.__guard__(this.arbitraryController, x1 => x1.stop());
      this.planeController.start(newMode);
    }
  }

  initTimeLimit() {
    // only enable hard time limit for anonymous users so far
    let model;
    if (!this.model.tracing.task || !this.model.tracing.user.isAnonymous) {
      return;
    }

    // TODO move that somehwere else
    const finishTracing = () => {
      // save the progress
      model = this.model;

      const tracingType = model.skeletonTracing || model.volumeTracing;
      tracingType.stateLogger.pushNow().then(() => {
        const url = `/annotations/${model.tracingType}/${model.tracingId}/finishAndRedirect`;
        app.router.loadURL(url);
      });
    };

    // parse hard time limit and convert from min to ms
    const { expectedTime } = this.model.tracing.task.type;
    let timeLimit = (expectedTime.maxHard * 60 * 1000) || 0;

    // setTimeout uses signed 32-bit integers, an overflow would cause immediate timeout execution
    if (timeLimit >= Math.pow(2, 32) / 2) {
      Toast.error("Time limit was reduced as it cannot be bigger than 35791 minutes.");
      timeLimit = (Math.pow(2, 32) / 2) - 1;
    }
    console.log(`TimeLimit is ${timeLimit / 60 / 1000} min`);

    if (timeLimit) {
      setTimeout(() => {
        window.alert("Time limit is reached, thanks for tracing!");
        finishTracing();
      }
      , timeLimit);
    }
  }

  onZoomStepChange() {
    const shouldWarn = !this.model.canDisplaySegmentationData();
    if (shouldWarn && (this.zoomStepWarningToast == null)) {
      const toastType = (this.model.volumeTracing != null) ? "danger" : "info";
      this.zoomStepWarningToast = Toast.message(toastType,
        "Segmentation data and volume tracing is only fully supported at a smaller zoom level.", true);
    } else if (!shouldWarn && (this.zoomStepWarningToast != null)) {
      this.zoomStepWarningToast.remove();
      this.zoomStepWarningToast = null;
    }
  }
}

export default Controller;
<commit_msg>automatically execute user script for tasks #1168<commit_after>/**
 * controller.js
 * @flow weak
 */

import $ from "jquery";
import _ from "lodash";
import app from "app";
import Utils from "libs/utils";
import Backbone from "backbone";
import Stats from "stats.js";
import { InputKeyboardNoLoop } from "libs/input";
import Toast from "libs/toast";
import Model from "oxalis/model";
import PlaneController from "oxalis/controller/viewmodes/plane_controller";
import SkeletonTracingController from "oxalis/controller/annotations/skeletontracing_controller";
import VolumeTracingController from "oxalis/controller/annotations/volumetracing_controller";
import SkeletonTracingArbitraryController from "oxalis/controller/combinations/skeletontracing_arbitrary_controller";
import SkeletonTracingPlaneController from "oxalis/controller/combinations/skeletontracing_plane_controller";
import VolumeTracingPlaneController from "oxalis/controller/combinations/volumetracing_plane_controller";
import ArbitraryController from "oxalis/controller/viewmodes/arbitrary_controller";
import MinimalArbitraryController from "oxalis/controller/combinations/minimal_skeletontracing_arbitrary_controller";
import SceneController from "oxalis/controller/scene_controller";
import UrlManager from "oxalis/controller/url_manager";
import View from "oxalis/view";
import SkeletonTracingView from "oxalis/view/skeletontracing/skeletontracing_view";
import VolumeTracingView from "oxalis/view/volumetracing/volumetracing_view";
import constants from "oxalis/constants";
import Request from "libs/request";

import type { ToastType } from "libs/toast";

class Controller {

  model: Model;
  urlManager: UrlManager;
  sceneController: SceneController;
  view: View;
  annotationController: SkeletonTracingController | VolumeTracingController;
  planeController: PlaneController;
  arbitraryController: ArbitraryController;
  zoomStepWarningToast: ToastType;
  keyboardNoLoop: InputKeyboardNoLoop;

  // Copied from backbone events (TODO: handle this better)
  listenTo: Function;

  // Main controller, responsible for setting modes and everything
  // that has to be controlled in any mode.
  //
  // We have a matrix of modes like this:
  //
  //   Annotation Mode \ View mode    Plane       Arbitrary
  //              Skeleton Tracing      X             X
  //                Volume Tracing      X             /
  //
  // In order to maximize code reuse, there is - besides the main
  // controller - a controller for each row, each column and each
  // cross in this matrix.

  constructor(options) {
    this.model = options.model;

    _.extend(this, Backbone.Events);

    this.urlManager = new UrlManager(this.model);
    this.model.set("state", this.urlManager.initialState);

    this.model.fetch()
        .then(() => this.modelFetchDone())
        .catch((error) => {
          // Don't throw errors for errors already handled by the model.
          if (error !== this.model.HANDLED_ERROR) {
            throw error;
          }
        },
        );
  }

  modelFetchDone() {
    if (!this.model.tracing.restrictions.allowAccess) {
      Toast.Error("You are not allowed to access this tracing");
      return;
    }

    app.router.on("beforeunload", () => {
      if (this.model.get("controlMode") === constants.CONTROL_MODE_TRACE) {
        const { stateLogger } = this.model.annotationModel;
        if (!stateLogger.stateSaved() && stateLogger.allowUpdate) {
          stateLogger.pushNow();
          return "You haven't saved your progress, please give us 2 seconds to do so and and then leave this site.";
        }
      }
      return null;
    },
    );

    this.urlManager.startUrlUpdater();

    this.sceneController = new SceneController(this.model);

    if (this.model.skeletonTracing != null) {
      this.view = new SkeletonTracingView(this.model);
      this.annotationController = new SkeletonTracingController(
        this.model, this.view, this.sceneController);
      this.planeController = new SkeletonTracingPlaneController(
        this.model, this.view, this.sceneController, this.annotationController);

      const ArbitraryControllerClass = this.model.tracing.content.settings.advancedOptionsAllowed ? SkeletonTracingArbitraryController : MinimalArbitraryController;
      this.arbitraryController = new ArbitraryControllerClass(
        this.model, this.view, this.sceneController, this.annotationController);
    } else if (this.model.volumeTracing != null) {
      this.view = new VolumeTracingView(this.model);
      this.annotationController = new VolumeTracingController(
        this.model, this.view, this.sceneController);
      this.planeController = new VolumeTracingPlaneController(
        this.model, this.view, this.sceneController, this.annotationController);
    } else {
      // View mode

      this.view = new View(this.model);
      this.planeController = new PlaneController(
        this.model, this.view, this.sceneController);
    }

    // FPS stats
    const stats = new Stats();
    $("body").append(stats.domElement);
    if (this.arbitraryController) { this.listenTo(this.arbitraryController.arbitraryView, "render", () => stats.update()); }
    this.listenTo(this.planeController.planeView, "render", () => stats.update());

    this.initKeyboard();
    this.initTimeLimit();
    this.initTaskScript();

    for (const binaryName of Object.keys(this.model.binary)) {
      this.listenTo(this.model.binary[binaryName].cube, "bucketLoaded", () => app.vent.trigger("rerender"));
    }

    this.listenTo(this.model, "change:mode", this.loadMode);
    this.loadMode(this.model.get("mode"));

    // Zoom step warning
    this.zoomStepWarningToast = null;
    this.listenTo(this.model.flycam, "zoomStepChanged", this.onZoomStepChange);
    this.onZoomStepChange();

    app.vent.trigger("webknossos:ready");
  }

  initTaskScript() {
    // Loads a Gist from GitHub with a user script if there is a
    // script assigned to the task
    if (this.model.tracing.task) {
      const script = this.model.tracing.task.script;
      const gistId = _.last(script.gist.split("/"));

      Request.receiveJSON(`https://api.github.com/gists/${gistId}`).then((gist) => {
        const firstFile = gist.files[Object.keys(gist.files)[0]];

        if (firstFile || firstFile.content) {
          try {
            // eslint-disable-next-line no-eval
            eval(firstFile.content);
          } catch (error) {
            console.error(error);
            Toast.error(`Error executing the task script "${script.name}". See console for more information.`);
          }
        } else {
          Toast.error(`Unable to retrieve script ${script.name}`);
        }
      });
    }
  }

  initKeyboard() {
    // avoid scrolling while pressing space
    $(document).keydown((event) => {
      if ((event.which === 32 || event.which === 18 || event.which >= 37 && event.which <= 40) && !$(":focus").length) { event.preventDefault(); }
    });

    const keyboardControls = {};

    if (this.model.get("controlMode") === constants.CONTROL_MODE_TRACE) {
      _.extend(keyboardControls, {
        // Set Mode, outcomment for release
        "shift + 1": () => this.model.setMode(constants.MODE_PLANE_TRACING),
        "shift + 2": () => this.model.setMode(constants.MODE_ARBITRARY),
        "shift + 3": () => this.model.setMode(constants.MODE_ARBITRARY_PLANE),

        t: () => this.view.toggleTheme(),

        m: () => {
          // rotate allowed modes
          const index = (this.model.allowedModes.indexOf(this.model.get("mode")) + 1) % this.model.allowedModes.length;
          this.model.setMode(this.model.allowedModes[index]);
        },

        "super + s": (event) => {
          event.preventDefault();
          event.stopPropagation();
          this.model.save();
        },

        "ctrl + s": (event) => {
          event.preventDefault();
          event.stopPropagation();
          this.model.save();
        },

      });
    }

    this.keyboardNoLoop = new InputKeyboardNoLoop(keyboardControls);
  }

  loadMode(newMode, force = false) {
    if ((newMode === constants.MODE_ARBITRARY || newMode === constants.MODE_ARBITRARY_PLANE) && (this.model.allowedModes.includes(newMode) || force)) {
      Utils.__guard__(this.planeController, x => x.stop());
      this.arbitraryController.start(newMode);
    } else if ((newMode === constants.MODE_PLANE_TRACING || newMode === constants.MODE_VOLUME) && (this.model.allowedModes.includes(newMode) || force)) {
      Utils.__guard__(this.arbitraryController, x1 => x1.stop());
      this.planeController.start(newMode);
    }
  }

  initTimeLimit() {
    // only enable hard time limit for anonymous users so far
    let model;
    if (!this.model.tracing.task || !this.model.tracing.user.isAnonymous) {
      return;
    }

    // TODO move that somehwere else
    const finishTracing = () => {
      // save the progress
      model = this.model;

      const tracingType = model.skeletonTracing || model.volumeTracing;
      tracingType.stateLogger.pushNow().then(() => {
        const url = `/annotations/${model.tracingType}/${model.tracingId}/finishAndRedirect`;
        app.router.loadURL(url);
      });
    };

    // parse hard time limit and convert from min to ms
    const { expectedTime } = this.model.tracing.task.type;
    let timeLimit = (expectedTime.maxHard * 60 * 1000) || 0;

    // setTimeout uses signed 32-bit integers, an overflow would cause immediate timeout execution
    if (timeLimit >= Math.pow(2, 32) / 2) {
      Toast.error("Time limit was reduced as it cannot be bigger than 35791 minutes.");
      timeLimit = (Math.pow(2, 32) / 2) - 1;
    }
    console.log(`TimeLimit is ${timeLimit / 60 / 1000} min`);

    if (timeLimit) {
      setTimeout(() => {
        window.alert("Time limit is reached, thanks for tracing!");
        finishTracing();
      }
      , timeLimit);
    }
  }

  onZoomStepChange() {
    const shouldWarn = !this.model.canDisplaySegmentationData();
    if (shouldWarn && (this.zoomStepWarningToast == null)) {
      const toastType = (this.model.volumeTracing != null) ? "danger" : "info";
      this.zoomStepWarningToast = Toast.message(toastType,
        "Segmentation data and volume tracing is only fully supported at a smaller zoom level.", true);
    } else if (!shouldWarn && (this.zoomStepWarningToast != null)) {
      this.zoomStepWarningToast.remove();
      this.zoomStepWarningToast = null;
    }
  }
}

export default Controller;
<|endoftext|>


<commit_before>/**
 * @file greetMessage command
 * @author Sankarsan Kampa (a.k.a k3rn31p4nic)
 * @license GPL-3.0
 */

exports.exec = async (Bastion, message, args) => {
  if (!args.text && !args.embed) {
    let guildModel = await Bastion.database.models.guild.findOne({
      attributes: [ 'greet', 'greetMessage' ],
      where: {
        guildID: message.guild.id
      }
    });

    if (guildModel.dataValues.greetMessage && Object.keys(guildModel.dataValues.greetMessage).length) {
      let text = guildModel.dataValues.greetMessage.text ? guildModel.dataValues.greetMessage.text : null;
      delete guildModel.dataValues.greetMessage.text;

      let embed = Object.keys(guildModel.dataValues.greetMessage).length ? guildModel.dataValues.greetMessage : null;
      if (embed) {
        embed.footer = {};
        embed.footer.text = guildModel.dataValues.greet ? 'Greeting Message Preview' : 'Greetings are currently disabled. You can enable it using the `greet` command.';
      }

      if (text && embed) {
        await message.channel.send(text, { embed: embed });
      }
      else if (text) {
        await message.channel.send({
          embed: {
            color: Bastion.colors.BLUE,
            description: text,
            footer: {
              text: guildModel.dataValues.greet ? 'Greeting Message Preview' : 'Greetings are currently disabled. You can enable it using the `greet` command.'
            }
          }
        });
      }
      else if (embed) {
        await message.channel.send({ embed: embed });
      }
    }
    else {
      await message.channel.send({
        embed: {
          color: Bastion.colors.BLUE,
          title: 'Greeting Message',
          description: `Not set. See the help message for this command to see how to set a greeting message to welcome new users: \`help ${this.help.name}\``
        }
      });
    }
  }
  else {
    let responseObject = {};

    if (args.text) {
      responseObject.text = args.text.join(' ');
    }
    if (args.embed) {
      args.embed = args.embed.join(' ');
      Object.assign(responseObject, JSON.parse(args.embed));

      delete responseObject.footer;
    }

    await Bastion.database.models.guild.update({
      greetMessage: responseObject
    },
    {
      where: {
        guildID: message.guild.id
      },
      fields: [ 'greetMessage' ]
    });

    await message.channel.send({
      embed: {
        color: Bastion.colors.GREEN,
        title: 'Greeting Message',
        description: `Successfully set the greeting message. Use the \`${this.help.name}\` command without any arguments to see a preview of the greeting message.`
      }
    }).catch(e => {
      Bastion.log.error(e);
    });
  }
};

exports.config = {
  aliases: [ 'gmsg' ],
  enabled: true,
  argsDefinitions: [
    { name: 'text', type: String, alias: 't', multiple: true, defaultOption: true },
    { name: 'embed', type: String, alias: 'e', multiple: true }
  ]
};

exports.help = {
  name: 'greetMessage',
  description: 'Edits the greeting message that shows when a member joins the server.',
  botPermission: '',
  userTextPermission: 'MANAGE_GUILD',
  userVoicePermission: '',
  usage: 'greetMessage [MESSAGE] [--embed EMBED_OBJECT]',
  example: [ 'greetMessage', 'greetMessage Hello $user! Welcome to $server.', 'greetMessage Hello $user! --embed { "title": "$user", "description": "Welcome to $server." }' ]
};
<commit_msg>commands(server_configuration): update examples of greetMessage<commit_after>/**
 * @file greetMessage command
 * @author Sankarsan Kampa (a.k.a k3rn31p4nic)
 * @license GPL-3.0
 */

exports.exec = async (Bastion, message, args) => {
  if (!args.text && !args.embed) {
    let guildModel = await Bastion.database.models.guild.findOne({
      attributes: [ 'greet', 'greetMessage' ],
      where: {
        guildID: message.guild.id
      }
    });

    if (guildModel.dataValues.greetMessage && Object.keys(guildModel.dataValues.greetMessage).length) {
      let text = guildModel.dataValues.greetMessage.text ? guildModel.dataValues.greetMessage.text : null;
      delete guildModel.dataValues.greetMessage.text;

      let embed = Object.keys(guildModel.dataValues.greetMessage).length ? guildModel.dataValues.greetMessage : null;
      if (embed) {
        embed.footer = {};
        embed.footer.text = guildModel.dataValues.greet ? 'Greeting Message Preview' : 'Greetings are currently disabled. You can enable it using the `greet` command.';
      }

      if (text && embed) {
        await message.channel.send(text, { embed: embed });
      }
      else if (text) {
        await message.channel.send({
          embed: {
            color: Bastion.colors.BLUE,
            description: text,
            footer: {
              text: guildModel.dataValues.greet ? 'Greeting Message Preview' : 'Greetings are currently disabled. You can enable it using the `greet` command.'
            }
          }
        });
      }
      else if (embed) {
        await message.channel.send({ embed: embed });
      }
    }
    else {
      await message.channel.send({
        embed: {
          color: Bastion.colors.BLUE,
          title: 'Greeting Message',
          description: `Not set. See the help message for this command to see how to set a greeting message to welcome new users: \`help ${this.help.name}\``
        }
      });
    }
  }
  else {
    let responseObject = {};

    if (args.text) {
      responseObject.text = args.text.join(' ');
    }
    if (args.embed) {
      args.embed = args.embed.join(' ');
      Object.assign(responseObject, JSON.parse(args.embed));

      delete responseObject.footer;
    }

    await Bastion.database.models.guild.update({
      greetMessage: responseObject
    },
    {
      where: {
        guildID: message.guild.id
      },
      fields: [ 'greetMessage' ]
    });

    await message.channel.send({
      embed: {
        color: Bastion.colors.GREEN,
        title: 'Greeting Message',
        description: `Successfully set the greeting message. Use the \`${this.help.name}\` command without any arguments to see a preview of the greeting message.`
      }
    }).catch(e => {
      Bastion.log.error(e);
    });
  }
};

exports.config = {
  aliases: [ 'gmsg' ],
  enabled: true,
  argsDefinitions: [
    { name: 'text', type: String, alias: 't', multiple: true, defaultOption: true },
    { name: 'embed', type: String, alias: 'e', multiple: true }
  ]
};

exports.help = {
  name: 'greetMessage',
  description: 'Edits the greeting message that shows when a member joins the server.',
  botPermission: '',
  userTextPermission: 'MANAGE_GUILD',
  userVoicePermission: '',
  usage: 'greetMessage [MESSAGE] [--embed EMBED_OBJECT]',
  example: [ 'greetMessage', 'greetMessage Hello {author}! Welcome to {server}.', 'greetMessage Hello {author}! --embed { "title": "{author}", "description": "Welcome to {server}." }' ]
};
<|endoftext|>


<commit_before>var numero = Math.random();

if (numero <= 0.5){
	console.log('\n' + numero + ' MENOR que 0,5 \n');
}
else {
	console.log('\n' + numero + ' MAYOR que 0,5 \n');
}
<commit_msg>random version 2<commit_after>var numero = Math.random();

var str=' Mayor que 0,5';

if (numero <= 0.5){
	str = 'Menor que 0,5';
}

console.log('\n' + numero +str + '\n');
<|endoftext|>


<commit_before>/*
 Copyright (c) 2012 GFT Appverse, S.L., Sociedad Unipersonal.
 This Source Code Form is subject to the terms of the Appverse Public License
 Version 2.0 (“APL v2.0”). If a copy of the APL was not distributed with this
 file, You can obtain one at http://www.appverse.mobi/licenses/apl_v2.0.pdf. [^]
 Redistribution and use in source and binary forms, with or without modification,
 are permitted provided that the conditions of the AppVerse Public License v2.0
 are met.
 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 DISCLAIMED. EXCEPT IN CASE OF WILLFUL MISCONDUCT OR GROSS NEGLIGENCE, IN NO EVENT
 SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT(INCLUDING NEGLIGENCE OR OTHERWISE)
 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 POSSIBILITY OF SUCH DAMAGE.
 */

'use strict';
var slug = require("underscore.string");
var os = require('os');
var path = require('path');
var wiring = require('html-wiring');
var project = require('./config/project-config.json');
var pkg = require("../../package.json");
var appverseHtml5Gen = require('../generator-base');

module.exports = appverseHtml5Gen.extend({
    initializing: function () {
        this.conflicter.force = true;
        this.skipprompts = false;
        this.props = {};
        this.props.moduleOptions = [];
        this.props.buildOptions = [];
        require('events').EventEmitter.defaultMaxListeners = 20;

        if (!this.options['skip-welcome-message']) {
            this.welcome(pkg);
            this.checkVersion();
        }
        if (!this.options.modules) {
            this.modules = path.join(__dirname, '../module/config/modules.json');
        } else {
            this.modules = this.options.modules;
        }

        if (!this.options.builds) {
            this.builds = path.join(__dirname, '../build/config/build.json');
        } else {
            this.builds = this.options.builds;
        }
        // This makes `appname` an argument.
        this.argument('application', {
            type: String,
            required: false
        });
        // Get the application name as argument to skip promtps and init all the variables
        // false by default or --all
        if (typeof this.application !== 'undefined') {
            this.skipprompts = true;
            this.appName = this.application;
        }

        // This makes `project` an option. --project=project.json
        // Get a JSON path or URL as value. The JSON defines the project and must validate against schema/appverse-project-schema.json
        if (this.options.project) {
            this.project = this.options.project;
            this.readJSONFileOrUrl(this.project, function (error, data) {
                if (!error) {
                    this.jsonproject = data;
                    this.validateJson(this.jsonproject, this.templatePath(), function (error, data) {
                        if (!error) {
                            this.appName = slug.slugify(this.jsonproject.project);
                            //ENABLED MODULES
                            for (var key in this.jsonproject.modules) {
                                if (this.jsonproject.modules[key].enabled) {
                                    if (this.jsonproject.modules.hasOwnProperty(key)) {
                                        this.props.moduleOptions.push(key);
                                    }
                                }
                            }
                            //ENABLED BUILDS
                            for (var buildkey in this.jsonproject.builds) {
                                if (this.jsonproject.builds[buildkey].enabled) {
                                    if (this.jsonproject.builds.hasOwnProperty(buildkey)) {
                                        this.props.buildOptions.push(buildkey);
                                    }
                                }
                            }
                            this.env.options.appPath = this.options.appPath || 'app';
                            this.config.set('appPath', this.env.options.appPath);
                            this.skipprompts = true;
                        } else {
                            this.warning(error);
                            process.exit();
                        }
                    }.bind(this));
                } else {
                    this.warning(error);
                    process.exit();
                }
            }.bind(this));
        }
    },
    prompting: function () {
        if (!this.skipprompts) {
            var done = this.async();
            var prompts = [{
                    name: 'appName',
                    message: 'What is your app\'s name ?  ' +
                        '\n Application name cannot contain special characters or a blank space. ' +
                        '\n Name will be slug if needed.  ',
                    default: slug.slugify(this.appname)
                }, {
                    type: 'checkbox',
                    name: 'moduleOptions',
                    message: "Select core modules. \n You can add the modules later executing the subgenerators",
                    choices: this.promptsConfig(this.modules)
                }, {
                    type: 'checkbox',
                    name: 'buildOptions',
                    message: "Select build types. \n You can add the build types later executing the subgenerators",
                    choices: this.promptsConfig(this.builds)
                }, {
                    type: "confirm",
                    name: "docker",
                    message: "Do you want to add Docker runtime? \n I will add a Dockerfile and Docker Compose files to run your application with a NGINX container and HAProxy.",
                    default: true
                }
                ];

            this.prompt(prompts, function (props) {
                if (prompts.length > 0) {
                    this.appName = slug.slugify(props.appName);
                    this.props = props;
                    this.env.options.appPath = this.options.appPath || 'app';
                    this.config.set('appPath', this.env.options.appPath);
                }
                done();
            }.bind(this));
        }
    },
    writing: function () {
      //FILES
      this.moveFiles(this.templatePath(), project.files);
      //TEMPLATES
      this.moveTemplates(this.templatePath(),project.templates);
      //STYLESHEETS
      var entryPoint = '\n    <!-- include: "type": "css", "files": "styles/**/*.css" -->'
                     + '\n    <!-- /include -->\n';
      //STATIC SCRIPTS
      var indexFile = this.fs.read(this.destinationPath('app/index.html'));
      indexFile = wiring.appendScripts(indexFile, 'scripts/scripts.js', project.scripts);
      //DINAMIC SCRIPTS
      [].forEach.call(project.appScripts, function (elem) {
        var line = '\n    <!-- include: "type": "js", "files": "' + elem + '" -->\n'
                   + '    <!-- /include -->\n';
        indexFile = wiring.domUpdate(indexFile, 'body', line, 'a');
      });
      this.write(this.destinationPath('app/index.html'), indexFile);
    },
    install: function () {
        if (this.props.moduleOptions) {
            if (this.props.moduleOptions.length > 0) {
                //MODULES
                this.props.moduleOptions.forEach(function (option) {
                    this.composeWith('appverse-html5:module', {
                        args: option,
                        options: {
                            'modules': this.modules,
                            'skip-welcome-message': true,
                            'skip-install': true,
                            'skip-prompts': this.skipprompts,
                            'jsonproject': this.jsonproject
                        }
                    });
                }.bind(this));
            }
        }
        if (this.props.buildOptions) {
            if (this.props.buildOptions.length > 0) {
                //BUILDS
                this.props.buildOptions.forEach(function (option) {
                    this.composeWith('appverse-html5:build', {
                       args: option,
                       options: {
                           'builds': this.builds,
                           'skip-welcome-message': true,
                           'skip-prompts': this.skipprompts,
                           'jsonproject': this.jsonproject
                         }
                     });
                 }.bind(this));
             }
         }
         if (this.props.docker) {
             this.composeWith('appverse-html5:runtime', {
               options: {
                 'skip-welcome-message': true,
                 'skip-install': true
               }
              });
         }
        this.installDependencies({
            skipInstall: this.options['skip-install'],
            callback: function () {
                // Emit a new event - dependencies installed
                this.emit('dependenciesInstalled');
            }.bind(this)
        });
        //Now you can bind to the dependencies installed event
        this.on('dependenciesInstalled', function () {
            this.spawnCommand('grunt', ['list']);
        });
    },
    end: function () {
        this.log(os.EOL + "Finish!" + os.EOL);
        if (this.options['skip-install']) {
            this.log(os.EOL + "Execute 'npm install & bower install' to resolve project dependencies.");
            this.log("Execute 'grunt list' to report the available grunt tasks into the Readme.md file." + os.EOL);
        } else {
            this.log(os.EOL + "Execute '$ grunt server:open' to see the results. That will starts the nodejs server and will open your browser with the home page");
            this.log(" or just execute '$ grunt server' to start the server." + os.EOL);
            this.log("Check your Readme.md for available grunt tasks." + os.EOL);
        }
    }
});
<commit_msg>Load CSS<commit_after>/*
 Copyright (c) 2012 GFT Appverse, S.L., Sociedad Unipersonal.
 This Source Code Form is subject to the terms of the Appverse Public License
 Version 2.0 (“APL v2.0”). If a copy of the APL was not distributed with this
 file, You can obtain one at http://www.appverse.mobi/licenses/apl_v2.0.pdf. [^]
 Redistribution and use in source and binary forms, with or without modification,
 are permitted provided that the conditions of the AppVerse Public License v2.0
 are met.
 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 DISCLAIMED. EXCEPT IN CASE OF WILLFUL MISCONDUCT OR GROSS NEGLIGENCE, IN NO EVENT
 SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT(INCLUDING NEGLIGENCE OR OTHERWISE)
 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 POSSIBILITY OF SUCH DAMAGE.
 */

'use strict';
var slug = require("underscore.string");
var os = require('os');
var path = require('path');
var wiring = require('html-wiring');
var project = require('./config/project-config.json');
var pkg = require("../../package.json");
var appverseHtml5Gen = require('../generator-base');

module.exports = appverseHtml5Gen.extend({
    initializing: function () {
        this.conflicter.force = true;
        this.skipprompts = false;
        this.props = {};
        this.props.moduleOptions = [];
        this.props.buildOptions = [];
        require('events').EventEmitter.defaultMaxListeners = 20;

        if (!this.options['skip-welcome-message']) {
            this.welcome(pkg);
            this.checkVersion();
        }
        if (!this.options.modules) {
            this.modules = path.join(__dirname, '../module/config/modules.json');
        } else {
            this.modules = this.options.modules;
        }

        if (!this.options.builds) {
            this.builds = path.join(__dirname, '../build/config/build.json');
        } else {
            this.builds = this.options.builds;
        }
        // This makes `appname` an argument.
        this.argument('application', {
            type: String,
            required: false
        });
        // Get the application name as argument to skip promtps and init all the variables
        // false by default or --all
        if (typeof this.application !== 'undefined') {
            this.skipprompts = true;
            this.appName = this.application;
        }

        // This makes `project` an option. --project=project.json
        // Get a JSON path or URL as value. The JSON defines the project and must validate against schema/appverse-project-schema.json
        if (this.options.project) {
            this.project = this.options.project;
            this.readJSONFileOrUrl(this.project, function (error, data) {
                if (!error) {
                    this.jsonproject = data;
                    this.validateJson(this.jsonproject, this.templatePath(), function (error, data) {
                        if (!error) {
                            this.appName = slug.slugify(this.jsonproject.project);
                            //ENABLED MODULES
                            for (var key in this.jsonproject.modules) {
                                if (this.jsonproject.modules[key].enabled) {
                                    if (this.jsonproject.modules.hasOwnProperty(key)) {
                                        this.props.moduleOptions.push(key);
                                    }
                                }
                            }
                            //ENABLED BUILDS
                            for (var buildkey in this.jsonproject.builds) {
                                if (this.jsonproject.builds[buildkey].enabled) {
                                    if (this.jsonproject.builds.hasOwnProperty(buildkey)) {
                                        this.props.buildOptions.push(buildkey);
                                    }
                                }
                            }
                            this.env.options.appPath = this.options.appPath || 'app';
                            this.config.set('appPath', this.env.options.appPath);
                            this.skipprompts = true;
                        } else {
                            this.warning(error);
                            process.exit();
                        }
                    }.bind(this));
                } else {
                    this.warning(error);
                    process.exit();
                }
            }.bind(this));
        }
    },
    prompting: function () {
        if (!this.skipprompts) {
            var done = this.async();
            var prompts = [{
                    name: 'appName',
                    message: 'What is your app\'s name ?  ' +
                        '\n Application name cannot contain special characters or a blank space. ' +
                        '\n Name will be slug if needed.  ',
                    default: slug.slugify(this.appname)
                }, {
                    type: 'checkbox',
                    name: 'moduleOptions',
                    message: "Select core modules. \n You can add the modules later executing the subgenerators",
                    choices: this.promptsConfig(this.modules)
                }, {
                    type: 'checkbox',
                    name: 'buildOptions',
                    message: "Select build types. \n You can add the build types later executing the subgenerators",
                    choices: this.promptsConfig(this.builds)
                }, {
                    type: "confirm",
                    name: "docker",
                    message: "Do you want to add Docker runtime? \n I will add a Dockerfile and Docker Compose files to run your application with a NGINX container and HAProxy.",
                    default: true
                }
                ];

            this.prompt(prompts, function (props) {
                if (prompts.length > 0) {
                    this.appName = slug.slugify(props.appName);
                    this.props = props;
                    this.env.options.appPath = this.options.appPath || 'app';
                    this.config.set('appPath', this.env.options.appPath);
                }
                done();
            }.bind(this));
        }
    },
    writing: function () {
      //FILES
      this.moveFiles(this.templatePath(), project.files);
      //TEMPLATES
      this.moveTemplates(this.templatePath(),project.templates);
      //STYLESHEETS
      var entryPoint = '\n    <!-- include: "type": "css", "files": "styles/**/*.css" -->'
                     + '\n    <!-- /include -->\n';
      indexFile = wiring.domUpdate(indexFile, 'head', entryPoint, 'a');
      //STATIC SCRIPTS
      var indexFile = this.fs.read(this.destinationPath('app/index.html'));
      indexFile = wiring.appendScripts(indexFile, 'scripts/scripts.js', project.scripts);
      //DINAMIC SCRIPTS
      [].forEach.call(project.appScripts, function (elem) {
        var line = '\n    <!-- include: "type": "js", "files": "' + elem + '" -->\n'
                   + '    <!-- /include -->\n';
        indexFile = wiring.domUpdate(indexFile, 'body', line, 'a');
      });
      this.write(this.destinationPath('app/index.html'), indexFile);
    },
    install: function () {
        if (this.props.moduleOptions) {
            if (this.props.moduleOptions.length > 0) {
                //MODULES
                this.props.moduleOptions.forEach(function (option) {
                    this.composeWith('appverse-html5:module', {
                        args: option,
                        options: {
                            'modules': this.modules,
                            'skip-welcome-message': true,
                            'skip-install': true,
                            'skip-prompts': this.skipprompts,
                            'jsonproject': this.jsonproject
                        }
                    });
                }.bind(this));
            }
        }
        if (this.props.buildOptions) {
            if (this.props.buildOptions.length > 0) {
                //BUILDS
                this.props.buildOptions.forEach(function (option) {
                    this.composeWith('appverse-html5:build', {
                       args: option,
                       options: {
                           'builds': this.builds,
                           'skip-welcome-message': true,
                           'skip-prompts': this.skipprompts,
                           'jsonproject': this.jsonproject
                         }
                     });
                 }.bind(this));
             }
         }
         if (this.props.docker) {
             this.composeWith('appverse-html5:runtime', {
               options: {
                 'skip-welcome-message': true,
                 'skip-install': true
               }
              });
         }
        this.installDependencies({
            skipInstall: this.options['skip-install'],
            callback: function () {
                // Emit a new event - dependencies installed
                this.emit('dependenciesInstalled');
            }.bind(this)
        });
        //Now you can bind to the dependencies installed event
        this.on('dependenciesInstalled', function () {
            this.spawnCommand('grunt', ['list']);
        });
    },
    end: function () {
        this.log(os.EOL + "Finish!" + os.EOL);
        if (this.options['skip-install']) {
            this.log(os.EOL + "Execute 'npm install & bower install' to resolve project dependencies.");
            this.log("Execute 'grunt list' to report the available grunt tasks into the Readme.md file." + os.EOL);
        } else {
            this.log(os.EOL + "Execute '$ grunt server:open' to see the results. That will starts the nodejs server and will open your browser with the home page");
            this.log(" or just execute '$ grunt server' to start the server." + os.EOL);
            this.log("Check your Readme.md for available grunt tasks." + os.EOL);
        }
    }
});
<|endoftext|>


<commit_before>(function() {
  angular.module('civic.services')
    .factory('EvidenceResource', EvidenceResource)
    .factory('Evidence', EvidenceService);

  // @ngInject
  function EvidenceResource($resource, $cacheFactory) {
    var cache = $cacheFactory.get('$http');

    var cacheInterceptor = function(response) {
      console.log(['EvidenceResource: removing', response.config.url, 'from $http cache.'].join(" "));
      cache.remove(response.config.url);
      return response.$promise;
    };

    return $resource('/api/evidence_items/:evidenceId',
      {
        evidenceId: '@evidenceId'
      },
      {
        // Base Evidence Resources
        query: {
          method: 'GET',
          isArray: true,
          cache: cache
        },
        get: { // get a single evidence
          method: 'GET',
          isArray: false,
          cache: cache
        },
        update: {
          method: 'PATCH',
          interceptor: {
            response: cacheInterceptor
          }
        },
        delete: {
          method: 'DELETE',
          interceptor: {
            response: cacheInterceptor
          }
        },
        add: {
          method: 'POST',
          cache: false
        },
        apply: {
          method: 'PATCH'
        },
        // Base Evidence Refresh
        queryFresh: { // get list of evidence
          method: 'GET',
          isArray: true,
          cache: false
        },
        getFresh: { // get evidence, force cache
          method: 'GET',
          isArray: false,
          cache: false
        },

        // Evidence Comments Resources
        queryComments: {
          method: 'GET',
          url: '/api/evidence_items/:evidenceId/comments',
          isArray: true,
          cache: cache
        },
        getComment: {
          method: 'GET',
          url: '/api/evidence_items/:evidenceId/comments/:commentId',
          params: {
            evidenceId: '@evidenceId',
            commentId: '@commentId'
          },
          isArray: false,
          cache: cache
        },

        submitComment: {
          method: 'POST',
          url: '/api/evidence_items/:evidenceId/comments',
          params: {
            evidenceId: '@evidenceId'
          },
          cache: cache
        },
        updateComment: {
          method: 'PATCH',
          url: '/api/evidence_items/:evidenceId/comments/:commentId',
          params: {
            evidenceId: '@evidenceId',
            commentId: '@commentId'
          },
          interceptor: {
            response: cacheInterceptor
          }
        },
        deleteComment: {
          method: 'DELETE',
          url: '/api/evidence_items/:evidenceId/comments/:commentId',
          params: {
            evidenceId: '@evidenceId',
            commentId: '@commentId'
          },
          interceptor: {
            response: cacheInterceptor
          }
        },

        // Evidence Comments Refresh
        queryCommentsFresh: {
          method: 'GET',
          url: 'api/evidence_items/:evidenceId/comments',
          isArray: true,
          cache: false
        },
        getCommentFresh: {
          method: 'GET',
          url: '/api/evidence_items/:evidenceId/comments/:commentId',
          params: {
            evidenceId: '@evidenceId',
            commentId: '@commentId'
          },
          isArray: false,
          cache: false
        }
      }
    )
  }

  // @ngInject
  function EvidenceService(EvidenceResource, $q, $exceptionHandler, $cacheFactory) {
    var cache = $cacheFactory.get('$http');
    // Base Evidence and Evidence Collection
    var item = {};
    var collection = [];
    var comment = {};
    var comments = [];

    // Evidence Collections
    var evidence = [];

    return {
      initBase: initBase,
      initComments: initComments,
      data: {
        item: item,
        collection: collection,
        comment: comment,
        comments: comments
      },

      // Evidence Base
      add: add,
      query: query,
      get: get,
      update: update,
      delete: deleteItem,
      apply: apply,

      // Evidence Base Refresh
      queryFresh: queryFresh,
      getFresh: getFresh,

      // Evidence Comments
      queryComments: queryComments,
      getComment: getComment,
      submitComment: submitComment,
      updateComment: updateComment,
      deleteComment: deleteComment,

      // Evidence Comments Refresh
      queryCommentsFresh: queryCommentsFresh,
      getCommentFresh: getCommentFresh
    };

    function initBase(evidenceId) {
      return $q.all([
        get(evidenceId)
      ])
    }

    function initComments(evidenceId) {
      return $q.all([
        queryComments(evidenceId)
      ])
    }
    // Evidence Base
    function add() {
      return EvidenceResource.add().$promise
        .then(function(response) {
          // angular.copy(response, collection);
          return response.$promise;
        });
    }
    function query() {
      return EvidenceResource.query().$promise
        .then(function(response) {
          angular.copy(response, collection);
          return response.$promise;
        });
    }
    function get(evidenceId) {
      return EvidenceResource.get({evidenceId: evidenceId}).$promise
        .then(function(response) {
          angular.copy(response, item);
          return response.$promise;
        });
    }
    function update(reqObj) {
      return EvidenceResource.update(reqObj).$promise
        .then(function(response) {
          angular.copy(response, item);
          return response.$promise;
        });
    }
    function deleteItem(evidenceId) {
      return EvidenceResource.delete({evidenceId: evidenceId}).$promise
        .then(function(response) {
          item = null;
          return response.$promise;
        });
    }
    function apply(reqObj) {
      return EvidenceResource.apply(reqObj).$promise.then(
        function(response) { // success
          // remove evidence's cache record
          cache.remove('/api/evidence_items/' + response.id);
          get(reqObj.evidenceId);
          return $q.when(response);
        },
        function(error) { // fail
          return $q.reject(error);
        })
    }

    // Evidence Collections
    function queryEvidence(evidenceId) {
      return EvidenceResource.queryEvidence({evidenceId: evidenceId}).$promise
        .then(function(response) {
          angular.copy(response, evidence);
          return response.$promise;
        });
    }

    // Evidence Base Refresh
    function queryFresh(evidenceId) {
      return EvidenceResource.queryFresh({evidenceId: evidenceId}).$promise
        .then(function(response) {
          angular.copy(response, collection);
          return response.$promise;
        });
    }
    function getFresh(evidenceId) {
      return EvidenceResource.getFresh({evidenceId: evidenceId}).$promise
        .then(function(response) {
          angular.copy(response, item);
          return response.$promise;
        });
    }

    // Evidence Collections Refresh
    function queryEvidenceFresh(evidenceId) {
      return EvidenceResource.queryEvidenceFresh({evidenceId: evidenceId}).$promise
        .then(function(response) {
          angular.copy(response, evidence);
          return response.$promise;
        });
    }

    // Evidence Comments
    function queryComments(evidenceId) {
      return EvidenceResource.queryComments({evidenceId: evidenceId}).$promise
        .then(function(response) {
          angular.copy(response, comments);
          return response.$promise;
        });
    }
    function getComment(evidenceId, commentId) {
      return EvidenceResource.getComment({evidenceId: evidenceId, commentId: commentId}).$promise
        .then(function(response) {
          angular.copy(response, comment);
          return response.$promise;
        });
    }
    function submitComment(reqObj) {
      try {
        if(!_.has(reqObj, 'evidenceId')) {
          if(_.has(item, 'id')) { // check to see if we have a evidence with an id
            _.merge(reqObj, { evidenceId: item.id });
          } else {
            throw new Error("No evidenceId supplied or found.");
          }
        }
      } catch(e) {
        $exceptionHandler(e.message, "EvidenceService:submitComment");
      }

      return EvidenceResource.submitComment(reqObj).$promise
        .then(function(response) {
          queryCommentsFresh(reqObj.evidenceId);
          return response.$promise;
        });
    }
    function updateComment(reqObj) {
      return EvidenceResource.updateComment(reqObj).$promise
        .then(function(response) {
          angular.copy(response, comment);
          getCommentFresh(reqObj);
          return response.$promise;
        });
    }
    function deleteComment(evidenceId, commentId) {
      return EvidenceResource.deleteComment({evidenceId: evidenceId, commentId: commentId}).$promise
        .then(function(response) {
          comment = null;
          return response.$promise;
        });
    }

    // Evidence Comments Refresh
    function queryCommentsFresh(evidenceId) {
      return EvidenceResource.queryCommentsFresh({evidenceId: evidenceId}).$promise
        .then(function(response) {
          angular.copy(response, comments);
          return response.$promise;
        });
    }
    function getCommentFresh(evidenceId, commentId) {
      return EvidenceResource.getCommentFresh({evidenceId: evidenceId, commentId: commentId}).$promise
        .then(function(response) {
          angular.copy(response   , comment);
          return response.$promise;
        });
    }
  }
})();
<commit_msg>add evidence now works<commit_after>(function() {
  angular.module('civic.services')
    .factory('EvidenceResource', EvidenceResource)
    .factory('Evidence', EvidenceService);

  // @ngInject
  function EvidenceResource($resource, $cacheFactory) {
    var cache = $cacheFactory.get('$http');

    var cacheInterceptor = function(response) {
      console.log(['EvidenceResource: removing', response.config.url, 'from $http cache.'].join(" "));
      cache.remove(response.config.url);
      return response.$promise;
    };

    return $resource('/api/evidence_items/:evidenceId',
      {
        evidenceId: '@evidenceId'
      },
      {
        // Base Evidence Resources
        query: {
          method: 'GET',
          isArray: true,
          cache: cache
        },
        get: { // get a single evidence
          method: 'GET',
          isArray: false,
          cache: cache
        },
        update: {
          method: 'PATCH',
          interceptor: {
            response: cacheInterceptor
          }
        },
        delete: {
          method: 'DELETE',
          interceptor: {
            response: cacheInterceptor
          }
        },
        add: {
          method: 'POST',
          cache: false
        },
        apply: {
          method: 'PATCH'
        },
        // Base Evidence Refresh
        queryFresh: { // get list of evidence
          method: 'GET',
          isArray: true,
          cache: false
        },
        getFresh: { // get evidence, force cache
          method: 'GET',
          isArray: false,
          cache: false
        },

        // Evidence Comments Resources
        queryComments: {
          method: 'GET',
          url: '/api/evidence_items/:evidenceId/comments',
          isArray: true,
          cache: cache
        },
        getComment: {
          method: 'GET',
          url: '/api/evidence_items/:evidenceId/comments/:commentId',
          params: {
            evidenceId: '@evidenceId',
            commentId: '@commentId'
          },
          isArray: false,
          cache: cache
        },

        submitComment: {
          method: 'POST',
          url: '/api/evidence_items/:evidenceId/comments',
          params: {
            evidenceId: '@evidenceId'
          },
          cache: cache
        },
        updateComment: {
          method: 'PATCH',
          url: '/api/evidence_items/:evidenceId/comments/:commentId',
          params: {
            evidenceId: '@evidenceId',
            commentId: '@commentId'
          },
          interceptor: {
            response: cacheInterceptor
          }
        },
        deleteComment: {
          method: 'DELETE',
          url: '/api/evidence_items/:evidenceId/comments/:commentId',
          params: {
            evidenceId: '@evidenceId',
            commentId: '@commentId'
          },
          interceptor: {
            response: cacheInterceptor
          }
        },

        // Evidence Comments Refresh
        queryCommentsFresh: {
          method: 'GET',
          url: 'api/evidence_items/:evidenceId/comments',
          isArray: true,
          cache: false
        },
        getCommentFresh: {
          method: 'GET',
          url: '/api/evidence_items/:evidenceId/comments/:commentId',
          params: {
            evidenceId: '@evidenceId',
            commentId: '@commentId'
          },
          isArray: false,
          cache: false
        }
      }
    )
  }

  // @ngInject
  function EvidenceService(EvidenceResource, $q, $exceptionHandler, $cacheFactory) {
    var cache = $cacheFactory.get('$http');
    // Base Evidence and Evidence Collection
    var item = {};
    var collection = [];
    var comment = {};
    var comments = [];

    // Evidence Collections
    var evidence = [];

    return {
      initBase: initBase,
      initComments: initComments,
      data: {
        item: item,
        collection: collection,
        comment: comment,
        comments: comments
      },

      // Evidence Base
      add: add,
      query: query,
      get: get,
      update: update,
      delete: deleteItem,
      apply: apply,

      // Evidence Base Refresh
      queryFresh: queryFresh,
      getFresh: getFresh,

      // Evidence Comments
      queryComments: queryComments,
      getComment: getComment,
      submitComment: submitComment,
      updateComment: updateComment,
      deleteComment: deleteComment,

      // Evidence Comments Refresh
      queryCommentsFresh: queryCommentsFresh,
      getCommentFresh: getCommentFresh
    };

    function initBase(evidenceId) {
      return $q.all([
        get(evidenceId)
      ])
    }

    function initComments(evidenceId) {
      return $q.all([
        queryComments(evidenceId)
      ])
    }
    // Evidence Base
    function add(reqObj) {
      return EvidenceResource.add(reqObj).$promise
        .then(function(response) {
          // angular.copy(response, collection);
          return response.$promise;
        });
    }
    function query() {
      return EvidenceResource.query().$promise
        .then(function(response) {
          angular.copy(response, collection);
          return response.$promise;
        });
    }
    function get(evidenceId) {
      return EvidenceResource.get({evidenceId: evidenceId}).$promise
        .then(function(response) {
          angular.copy(response, item);
          return response.$promise;
        });
    }
    function update(reqObj) {
      return EvidenceResource.update(reqObj).$promise
        .then(function(response) {
          angular.copy(response, item);
          return response.$promise;
        });
    }
    function deleteItem(evidenceId) {
      return EvidenceResource.delete({evidenceId: evidenceId}).$promise
        .then(function(response) {
          item = null;
          return response.$promise;
        });
    }
    function apply(reqObj) {
      return EvidenceResource.apply(reqObj).$promise.then(
        function(response) { // success
          // remove evidence's cache record
          cache.remove('/api/evidence_items/' + response.id);
          get(reqObj.evidenceId);
          return $q.when(response);
        },
        function(error) { // fail
          return $q.reject(error);
        })
    }

    // Evidence Collections
    function queryEvidence(evidenceId) {
      return EvidenceResource.queryEvidence({evidenceId: evidenceId}).$promise
        .then(function(response) {
          angular.copy(response, evidence);
          return response.$promise;
        });
    }

    // Evidence Base Refresh
    function queryFresh(evidenceId) {
      return EvidenceResource.queryFresh({evidenceId: evidenceId}).$promise
        .then(function(response) {
          angular.copy(response, collection);
          return response.$promise;
        });
    }
    function getFresh(evidenceId) {
      return EvidenceResource.getFresh({evidenceId: evidenceId}).$promise
        .then(function(response) {
          angular.copy(response, item);
          return response.$promise;
        });
    }

    // Evidence Collections Refresh
    function queryEvidenceFresh(evidenceId) {
      return EvidenceResource.queryEvidenceFresh({evidenceId: evidenceId}).$promise
        .then(function(response) {
          angular.copy(response, evidence);
          return response.$promise;
        });
    }

    // Evidence Comments
    function queryComments(evidenceId) {
      return EvidenceResource.queryComments({evidenceId: evidenceId}).$promise
        .then(function(response) {
          angular.copy(response, comments);
          return response.$promise;
        });
    }
    function getComment(evidenceId, commentId) {
      return EvidenceResource.getComment({evidenceId: evidenceId, commentId: commentId}).$promise
        .then(function(response) {
          angular.copy(response, comment);
          return response.$promise;
        });
    }
    function submitComment(reqObj) {
      try {
        if(!_.has(reqObj, 'evidenceId')) {
          if(_.has(item, 'id')) { // check to see if we have a evidence with an id
            _.merge(reqObj, { evidenceId: item.id });
          } else {
            throw new Error("No evidenceId supplied or found.");
          }
        }
      } catch(e) {
        $exceptionHandler(e.message, "EvidenceService:submitComment");
      }

      return EvidenceResource.submitComment(reqObj).$promise
        .then(function(response) {
          queryCommentsFresh(reqObj.evidenceId);
          return response.$promise;
        });
    }
    function updateComment(reqObj) {
      return EvidenceResource.updateComment(reqObj).$promise
        .then(function(response) {
          angular.copy(response, comment);
          getCommentFresh(reqObj);
          return response.$promise;
        });
    }
    function deleteComment(evidenceId, commentId) {
      return EvidenceResource.deleteComment({evidenceId: evidenceId, commentId: commentId}).$promise
        .then(function(response) {
          comment = null;
          return response.$promise;
        });
    }

    // Evidence Comments Refresh
    function queryCommentsFresh(evidenceId) {
      return EvidenceResource.queryCommentsFresh({evidenceId: evidenceId}).$promise
        .then(function(response) {
          angular.copy(response, comments);
          return response.$promise;
        });
    }
    function getCommentFresh(evidenceId, commentId) {
      return EvidenceResource.getCommentFresh({evidenceId: evidenceId, commentId: commentId}).$promise
        .then(function(response) {
          angular.copy(response   , comment);
          return response.$promise;
        });
    }
  }
})();
<|endoftext|>


<commit_before>// DataTable component is beta, over-writing buggy logic on it before they get fixed on YUI

var Lang = A.Lang,
	isNumber = Lang.isNumber,
	isString = Lang.isString,

	CHILD_NODES = 'childNodes',
	COLUMNSET = 'columnset',
	DATA = 'data',
	HEADERS = 'headers',
	ID = 'id',

	_HASH = '#',
	_SPACE = ' ';

A.DataTable.Base = A.Base.create('datatable', A.DataTable.Base, [], {
	initializer: function() {
		var instance = this;

		instance.after('render', instance._afterRender);
		instance.after('recordsetChange', instance._afterRecordsetChangeExt);
	},

	getCellNode: function(record, column) {
		var row = A.one(_HASH+record.get(ID));

		return row.get(CHILD_NODES).item(column.keyIndex);
	},

	getColumnByCell: function(cell) {
		var instance = this;
		var dataHeaderId = cell.getAttribute(HEADERS).split(_SPACE).pop() || cell.get(ID);

		return instance.get(COLUMNSET).getColumn(dataHeaderId);
	},

	getColNode: function(cell) {
		var instance = this;
		var index = instance.get(COLUMNSET).getColumnIndex(instance.getColumnByCell(cell));

		return instance._colgroupNode.get(CHILD_NODES).item(index);
	},

	_afterRender: function() {
		var instance = this;

		instance._bindPluginsEvents();
		instance._fixPluginsUI();
	},

	_afterRecordsetChangeExt: function(event) {
		var instance = this;

		instance._fixPluginsUI();
	},

	_bindPluginsEvents: function() {
		var instance = this;
		var sort = instance.sort;

		if (sort) {
			sort.after('lastSortedByChange', A.bind(instance._fixPluginsUI, instance));
		}
	},

	_fixPluginsUI: function() {
		var instance = this;
		var sort = instance.sort;
		var scroll = instance.scroll;

		if (sort && scroll) {
			scroll.syncUI();
		}
	}
}, {});

A.Columnset = A.Base.create('columnset', A.Columnset, [], {
	getColumn: function(i) {
		var instance = this;

		if (isString(i)) {
			return this.idHash[i];
		}
		else if (isNumber(i)) {
			return instance.keys[i];
		}

		return null;
	},

	getColumnIndex: function(column) {
		return column.keyIndex;
	},

	getLength: function() {
		var instance = this;

		return instance.keys.length;
	},

	_setDefinitions: function(val) {
		return val;
	}
}, {});

A.Recordset = A.Base.create('recordset', A.Recordset, [], {
	getRecordByRow: function(row) {
		var instance = this;

		return instance.getRecord(row.get(ID));
	},

	getRecordIndex: function(record) {
		var instance = this;

		return A.Array.indexOf(instance._items, record);
	},

	updateRecordDataByKey: function(record, key, value) {
		var instance = this;
		var data = record.get(DATA);

		if (data) {
			data[key] = value;
			record.set(DATA, data);
		}

		instance.update(record, instance.getRecordIndex(record));
	}
}, {});<commit_msg>AUI-413 Fix DataTable sync widths when column is sortable<commit_after>// DataTable component is beta, over-writing buggy logic on it before they get fixed on YUI

var Lang = A.Lang,
	isNumber = Lang.isNumber,
	isString = Lang.isString,

	CHILD_NODES = 'childNodes',
	COLUMNSET = 'columnset',
	DATA = 'data',
	HEADERS = 'headers',
	ID = 'id',

	_HASH = '#',
	_SPACE = ' ';

A.DataTable.Base = A.Base.create('datatable', A.DataTable.Base, [], {
	initializer: function() {
		var instance = this;

		instance.after('render', instance._afterRender);
		instance.after('recordsetChange', instance._afterRecordsetChangeExt);
	},

	getCellNode: function(record, column) {
		var row = A.one(_HASH+record.get(ID));

		return row.get(CHILD_NODES).item(column.keyIndex);
	},

	getColumnByCell: function(cell) {
		var instance = this;
		var dataHeaderId = cell.getAttribute(HEADERS).split(_SPACE).pop() || cell.get(ID);

		return instance.get(COLUMNSET).getColumn(dataHeaderId);
	},

	getColNode: function(cell) {
		var instance = this;
		var index = instance.get(COLUMNSET).getColumnIndex(instance.getColumnByCell(cell));

		return instance._colgroupNode.get(CHILD_NODES).item(index);
	},

	_afterRender: function() {
		var instance = this;

		instance._bindPluginsEvents();
		instance._fixPluginsUI();
	},

	_afterRecordsetChangeExt: function(event) {
		var instance = this;

		instance._fixPluginsUI();
	},

	_bindPluginsEvents: function() {
		var instance = this;
		var sort = instance.sort;

		if (sort) {
			sort.after('lastSortedByChange', A.bind(instance._fixPluginsUI, instance));
		}
	},

	_fixPluginsUI: function() {
		var instance = this;
		var sort = instance.sort;
		var scroll = instance.scroll;

		if (sort && scroll) {
			scroll.syncUI();

			// Workaround: Invoke _syncWidths twice from DataTableScroll, otherwise it's misscalculating the paddings for the sortable columns.
			// TODO: Fix this on DataTable DataTableScroll
			scroll._syncWidths();
		}
	}
}, {});

A.Columnset = A.Base.create('columnset', A.Columnset, [], {
	getColumn: function(i) {
		var instance = this;

		if (isString(i)) {
			return this.idHash[i];
		}
		else if (isNumber(i)) {
			return instance.keys[i];
		}

		return null;
	},

	getColumnIndex: function(column) {
		return column.keyIndex;
	},

	getLength: function() {
		var instance = this;

		return instance.keys.length;
	},

	_setDefinitions: function(val) {
		return val;
	}
}, {});

A.Recordset = A.Base.create('recordset', A.Recordset, [], {
	getRecordByRow: function(row) {
		var instance = this;

		return instance.getRecord(row.get(ID));
	},

	getRecordIndex: function(record) {
		var instance = this;

		return A.Array.indexOf(instance._items, record);
	},

	updateRecordDataByKey: function(record, key, value) {
		var instance = this;
		var data = record.get(DATA);

		if (data) {
			data[key] = value;
			record.set(DATA, data);
		}

		instance.update(record, instance.getRecordIndex(record));
	}
}, {});<|endoftext|>


<commit_before>var child_process = require('child_process')
var fs = require('fs');
var max_sleep = 300
var step = 10
//Added a comment that achieves no real goal.
//Non-blocking loop
//Adjustable step
//Status line
//Add a rough time indicator
//First cut at libfaketime support

var commit_messages = [
  "Fixing an important issue with the universe.",
  "Someone poisoned the waterhole!",
  "You feeling lucky punk?",
  "Five bullets or six?",
  "Fixed memory parsing error #1337",
  "Cleaned out the intertubes",
  "AAAAAAAAAAARGH!",
  "Fixed a typo",
  "<commit_msg>Fixing an error introduced in the last commit<commit_after>var child_process = require('child_process')
var fs = require('fs');
var max_sleep = 300
var step = 10
//Added a comment that achieves no real goal.
//Non-blocking loop
//Adjustable step
//Status line
//Add a rough time indicator
//First cut at libfaketime support

var commit_messages = [
  "Fixing an important issue with the universe.",
  "Someone poisoned the waterhole!",
  "You feeling lucky punk?",
  "Five bullets or six?",
  "Fixed memory parsing error #1337",
  "Cleaned out the intertubes",
  "AAAAAAAAAAARGH!",
  "Fixed a typo",
  "U<|endoftext|>


<commit_before>var getRoutes = require('../harness.js').getRoutes;
var app = require('../harness.js').app;

xdescribe('routes test suite', function() {
    it('should be able to get routes', function() {
        getRoutes(app, function(routes) {
            expect(routes).toBeDefined();
            expect(routes).toEqual([{
                path: '/api/test',
                methods: {
                    get: true
                }
            }]);
        });
    });
});
<commit_msg>remove x<commit_after>var getRoutes = require('../harness.js').getRoutes;
var app = require('../harness.js').app;

describe('routes test suite', function() {
    it('should be able to get routes', function() {
        getRoutes(app, function(routes) {
            expect(routes).toBeDefined();
            expect(routes).toEqual([{
                path: '/api/test',
                methods: {
                    get: true
                }
            }]);
        });
    });
});
<|endoftext|>


<commit_before>'use strict'
const GMR = require('../gmr.js')
const angular = require('angular')
const moment = require('moment')
const remote = require('electron').remote
const dialog = remote.dialog
const HomeFolder = remote.app.getPath('home')
const Menu = remote.Menu

// http://electron.atom.io/docs/v0.30.0/api/menu/
const template = [
  {
    label: 'Application',
    submenu: [
      { label: 'About Application', selector: 'orderFrontStandardAboutPanel:' },
      { type: 'separator' },
      { label: 'Quit', accelerator: 'Command+Q', selector: 'terminate:'}
    ]
  },
  {
    label: 'Edit',
    submenu: [
      { label: 'Undo', accelerator: 'CmdOrCtrl+Z', selector: 'undo:' },
      { label: 'Redo', accelerator: 'Shift+CmdOrCtrl+Z', selector: 'redo:' },
      { type: 'separator' },
      { label: 'Cut', accelerator: 'CmdOrCtrl+X', selector: 'cut:' },
      { label: 'Copy', accelerator: 'CmdOrCtrl+C', selector: 'copy:' },
      { label: 'Paste', accelerator: 'CmdOrCtrl+V', selector: 'paste:' },
      { label: 'Select All', accelerator: 'CmdOrCtrl+A', selector: 'selectAll:' }
    ]
  },
  {
    label: 'View',
    submenu: [
      {
        label: 'Reload',
        accelerator: 'Command+R',
        click: function() { remote.getCurrentWindow().reload(); }
      },
      { type: 'separator' },
      {
        label: 'Toggle DevTools',
        accelerator: 'Alt+Command+I',
        click: function() { remote.getCurrentWindow().toggleDevTools(); }
      }
    ]
  }
]

Menu.setApplicationMenu(Menu.buildFromTemplate(template))

/* Here begins Angular */
let app = angular.module('eGMR', [])
let gmr = new GMR()

app.controller('GlobalController', function ($scope, $timeout) {
  // $scope.players = []
  // $scope.games = []
  $scope.selectedGame = {}
  $scope.playerId = -1
  $scope.isSettingsSelected = false

  $scope.settings = gmr.getSettings()

  $scope.loadFromGMR = function () {
    gmr.fetchInfo((err, infos) => {
      return $scope.$apply(() => {
        if (err) return showError(err)
        $scope.players = infos.players
        $scope.games = infos.games
        $scope.settings = gmr.getSettings()
        $scope.selectedGame = $scope.games[0]
        $scope.playerId = gmr.getPlayerId()
        $scope.$broadcast('selectedGameWasUpdated')
      })
    })
  }

  if (!$scope.settings.saveFile || !$scope.settings.authKey) {
    $scope.isSettingsSelected = true
  } else {
    $scope.loadFromGMR()
  }

  $scope.setSelectedGame = function (game) {
    $scope.selectedGame = game

    $scope.isSettingsSelected = false
    $scope.$broadcast('settingsTabWasExited')

    return $scope.$broadcast('selectedGameWasUpdated')
  }

  $scope.showSettings = function () {
    $scope.isSettingsSelected = true
  }

  function showError (err) {
    $scope.error = err
    return $timeout(() => {$scope.error=''}, 10000)
  }

  $scope.$on('error', (err) => {
    return showError(err)
  })

  $scope.filterPlayers = function filterPlayers (game) {
    return function (player) {
      return player.UserId !== '0' && player.UserId !== game.CurrentTurn.UserId
    }
  }

})

app.controller('GameInfoController', function ($scope, $timeout) {
  $scope.timeRemaining = '∞'

  $scope.$on('selectedGameWasUpdated', () => {
    let timeRemaining = moment($scope.selectedGame.CurrentTurn.Expires).fromNow(true)
    if (!timeRemaining) {
      timeRemaining = '∞'
    }
    return $scope.timeRemaining = timeRemaining
  })

  $scope.downloadSave = function () {
    console.log(`Downloading...${$scope.selectedGame.GameId}`)
    $scope.isLoading = true
    return gmr.getGameSave($scope.selectedGame.GameId, (err) => {
      if (err) return $scope.$emit('error', err)
      return $scope.$apply(() => {
        $scope.downloaded = true
        $scope.isLoading = false
        return $timeout(() => {$scope.downloaded = false}, 5000)
      })
    })
  }

  $scope.uploadSave = function () {
    $scope.isLoading = true
    return gmr.uploadGameSave($scope.selectedGame.CurrentTurn.TurnId, (err) => {
      if (err) return $scope.$emit('error', err)
      return $scope.$apply(() => {
        $scope.uploaded = true
        $scope.isLoading = false
        return $timeout(() => {$scope.uploaded = false}, 5000)
      })
    })
  }

  $scope.launchCivilization = function () {
    const runCommand = 'open' //TODO get command for other platforms

    const spawn = require('child_process').spawn;
    const child = spawn(runCommand, ['steam://run/8930'], {
      detached: true,
      stdio: [ 'ignore', 'ignore', 'ignore' ]
    })
    child.unref();
  }

})

app.controller('GameListController', function ($scope) {})

app.controller('SettingsController', function ($scope) {
  $scope.settings = gmr.getSettings()

  $scope.$on('settingsTabWasExited', () => {
    return $scope.cancelSettings()
  })

  $scope.changeSaveFile = function () {
    let defaultPath = HomeFolder
    if ($scope.settings.saveFile) {
      defaultPath = $scope.settings.saveFile
    }
    let newSave = dialog.showOpenDialog({defaultPath: defaultPath,  properties: ['openDirectory']})
    if (newSave) {
      $scope.settings.saveFile = newSave[0] + '/(GMR) Play this one!.Civ5Save'
    }
  }

  $scope.saveSettings = function () {
    gmr.setSettings($scope.settings)
    return $scope.loadFromGMR()
  }

  $scope.cancelSettings = function () {
    $scope.settings = gmr.getSettings()
  }
})
<commit_msg>Adds multiplatform support for launching Civ5 (#4)<commit_after>'use strict'
const GMR = require('../gmr.js')
const angular = require('angular')
const moment = require('moment')
const os = require('os')
const remote = require('electron').remote
const dialog = remote.dialog
const HomeFolder = remote.app.getPath('home')
const Menu = remote.Menu

// http://electron.atom.io/docs/v0.30.0/api/menu/
const template = [
  {
    label: 'Application',
    submenu: [
      { label: 'About Application', selector: 'orderFrontStandardAboutPanel:' },
      { type: 'separator' },
      { label: 'Quit', accelerator: 'Command+Q', selector: 'terminate:'}
    ]
  },
  {
    label: 'Edit',
    submenu: [
      { label: 'Undo', accelerator: 'CmdOrCtrl+Z', selector: 'undo:' },
      { label: 'Redo', accelerator: 'Shift+CmdOrCtrl+Z', selector: 'redo:' },
      { type: 'separator' },
      { label: 'Cut', accelerator: 'CmdOrCtrl+X', selector: 'cut:' },
      { label: 'Copy', accelerator: 'CmdOrCtrl+C', selector: 'copy:' },
      { label: 'Paste', accelerator: 'CmdOrCtrl+V', selector: 'paste:' },
      { label: 'Select All', accelerator: 'CmdOrCtrl+A', selector: 'selectAll:' }
    ]
  },
  {
    label: 'View',
    submenu: [
      {
        label: 'Reload',
        accelerator: 'Command+R',
        click: function() { remote.getCurrentWindow().reload(); }
      },
      { type: 'separator' },
      {
        label: 'Toggle DevTools',
        accelerator: 'Alt+Command+I',
        click: function() { remote.getCurrentWindow().toggleDevTools(); }
      }
    ]
  }
]

Menu.setApplicationMenu(Menu.buildFromTemplate(template))

/* Here begins Angular */
let app = angular.module('eGMR', [])
let gmr = new GMR()

app.controller('GlobalController', function ($scope, $timeout) {
  // $scope.players = []
  // $scope.games = []
  $scope.selectedGame = {}
  $scope.playerId = -1
  $scope.isSettingsSelected = false

  $scope.settings = gmr.getSettings()

  $scope.loadFromGMR = function () {
    gmr.fetchInfo((err, infos) => {
      return $scope.$apply(() => {
        if (err) return showError(err)
        $scope.players = infos.players
        $scope.games = infos.games
        $scope.settings = gmr.getSettings()
        $scope.selectedGame = $scope.games[0]
        $scope.playerId = gmr.getPlayerId()
        $scope.$broadcast('selectedGameWasUpdated')
      })
    })
  }

  if (!$scope.settings.saveFile || !$scope.settings.authKey) {
    $scope.isSettingsSelected = true
  } else {
    $scope.loadFromGMR()
  }

  $scope.setSelectedGame = function (game) {
    $scope.selectedGame = game

    $scope.isSettingsSelected = false
    $scope.$broadcast('settingsTabWasExited')

    return $scope.$broadcast('selectedGameWasUpdated')
  }

  $scope.showSettings = function () {
    $scope.isSettingsSelected = true
  }

  function showError (err) {
    $scope.error = err
    return $timeout(() => {$scope.error=''}, 10000)
  }

  $scope.$on('error', (err) => {
    return showError(err)
  })

  $scope.filterPlayers = function filterPlayers (game) {
    return function (player) {
      return player.UserId !== '0' && player.UserId !== game.CurrentTurn.UserId
    }
  }

})

app.controller('GameInfoController', function ($scope, $timeout) {
  $scope.timeRemaining = '∞'

  $scope.$on('selectedGameWasUpdated', () => {
    let timeRemaining = moment($scope.selectedGame.CurrentTurn.Expires).fromNow(true)
    if (!timeRemaining) {
      timeRemaining = '∞'
    }
    return $scope.timeRemaining = timeRemaining
  })

  $scope.downloadSave = function () {
    console.log(`Downloading...${$scope.selectedGame.GameId}`)
    $scope.isLoading = true
    return gmr.getGameSave($scope.selectedGame.GameId, (err) => {
      if (err) return $scope.$emit('error', err)
      return $scope.$apply(() => {
        $scope.downloaded = true
        $scope.isLoading = false
        return $timeout(() => {$scope.downloaded = false}, 5000)
      })
    })
  }

  $scope.uploadSave = function () {
    $scope.isLoading = true
    return gmr.uploadGameSave($scope.selectedGame.CurrentTurn.TurnId, (err) => {
      if (err) return $scope.$emit('error', err)
      return $scope.$apply(() => {
        $scope.uploaded = true
        $scope.isLoading = false
        return $timeout(() => {$scope.uploaded = false}, 5000)
      })
    })
  }

  $scope.launchCivilization = function () {
    const commands = {
      darwin:'open',
      windows:'cmd /c start', //TODO test
      linux:'xdg-open', //TODO check if xdg-open is installed (xdg-utils)
      openbsd:'xdg-open', //TODO test
      freebsd:'xdg-open', //TODO test
    }
    const runCommand = commands[os.platform()]

    const spawn = require('child_process').spawn;
    const child = spawn(runCommand, ['steam://run/8930'], {
      detached: true,
      stdio: [ 'ignore', 'ignore', 'ignore' ]
    })
    child.unref();
  }

})

app.controller('GameListController', function ($scope) {})

app.controller('SettingsController', function ($scope) {
  $scope.settings = gmr.getSettings()

  $scope.$on('settingsTabWasExited', () => {
    return $scope.cancelSettings()
  })

  $scope.changeSaveFile = function () {
    let defaultPath = HomeFolder
    if ($scope.settings.saveFile) {
      defaultPath = $scope.settings.saveFile
    }
    let newSave = dialog.showOpenDialog({defaultPath: defaultPath,  properties: ['openDirectory']})
    if (newSave) {
      $scope.settings.saveFile = newSave[0] + '/(GMR) Play this one!.Civ5Save'
    }
  }

  $scope.saveSettings = function () {
    gmr.setSettings($scope.settings)
    return $scope.loadFromGMR()
  }

  $scope.cancelSettings = function () {
    $scope.settings = gmr.getSettings()
  }
})
<|endoftext|>


<commit_before>import Cannon from 'cannon';
import PointLight from '../lights/PointLight';
import { randomInt, clamp } from 'utils';

import Emitter from 'helpers/Emitter';

import {
  EXP_LUX_TOGGLE,
  EXP_LUX_END_GAME,
  EXP_FLASH_MSG,
  EXP_GET_LUX_VALUE,
  EXP_LUX_VALUE_SENDED,
  EXP_LUX_VALUE_UPDATE,
  EXP_PLAYER_TOGGLE_IS_IN_DANGER
} from 'config/messages';

/**
 * Player class
 * @param {Configuration} Configuration Configuration
 * @param {World} World instance
 */
class Player extends THREE.Object3D {

  /**
   * constructor function
   * @param {World}  World         World instance
   * @param {Object} playerConfig  Player Configuration
   * @param {Object} cameraConfig  Camera Configuration
   */
  constructor( World, playerConfig, cameraConfig ) {

    super();

    this.world = World;

    this.luxEnabled = false;

    this.playerConfig = playerConfig.pointLights;
    this.cameraConfig = cameraConfig;
    this.lights = [];

    this.luxVal = 0.9;
    this.previousluxVal = 0.2;
    this.decreaseLuxVal = 1 / 10000;

    this.nbLights = this.playerConfig.number;

    this.isInDanger = false;
    this.dangerThreshold = 0.5;

    this.createSphere();
    this.initLights();

    this.bind();

    this.addListeners();

    this.debug();
  }

  bind() {

    [ 'toggleLux', 'getLuxVal', 'updateLuxVal', 'updateLuxVal', 'incrementLux', 'checkDangerState' ]
        .forEach( ( fn ) => this[ fn ] = this[ fn ].bind( this ) );
  }

  debug() {

    const onKeyUp = ( ev )=> {

      if( ev.keyCode === 76 ) { // l

        this.luxVal += 0.05;

      } else if ( ev.keyCode === 75 ) { // k

        this.luxVal -= 0.05;
      }
    };

    document.addEventListener( 'keyup', onKeyUp, false );

  }

  addListeners() {

    Emitter.on( EXP_LUX_TOGGLE, this.toggleLux );
    Emitter.on( EXP_GET_LUX_VALUE, this.getLuxVal );
    Emitter.on( EXP_LUX_VALUE_UPDATE, this.incrementLux );
  }

  toggleLux( toggleVal ) {

    this.luxEnabled = toggleVal;
  }

  /**
   * createSphere function
   */
  createSphere() {

    // Create a sphere
    const sphereShape = new Cannon.Sphere( 10 );
    this.sphereBody = new Cannon.Body({ mass: 300 });
    this.sphereBody.addShape( sphereShape );
    this.sphereBody.linearDamping = 0.9;
    this.sphereBody.position.copy( this.cameraConfig.position );
    this.world.add( this.sphereBody );

    // const geometry = new THREE.SphereGeometry( 10, 10, 10 );
    // const material = new THREE.MeshBasicMaterial({ color: 0xffff00, side: THREE.DoubleSide, wireframe: true });
    // this.sphere = new THREE.Mesh( geometry, material );
    // this.add( this.sphere );
  }

  /**
   * initLights function
   */
  initLights() {

    for ( let i = 0; i < this.nbLights; i++ ) {

      const plight = new PointLight({
        hex: parseInt( this.playerConfig.colors[ randomInt( 0, this.playerConfig.colors.length - 1 ) ], 16 ),
        intensity: this.playerConfig.intensity,
        distance: this.playerConfig.distance,
        decay: this.playerConfig.decay
      });

      plight.addSphere();

      this.lights.push( plight );

      this.add( plight );
    }
  }

  /**
   * move function
   * Move the player where the camera is
   * @param {object} newPos Position vector of the camera
   */
  move( newPos ) {

    this.position.copy( newPos );
  }

  /**
   * rotate function
   * Rotate the player where the camera is
   * @param {object} newRotation Rotation vector of the camera
   */
  rotate( newRotation ) {

    // this.sphereBody.quaternion.setFromEuler( newRotation );
  }

  incrementLux( increment ) {

    this.luxVal = clamp( 0, 1, this.luxVal + increment );
  }

  getLuxVal() {

    Emitter.emit( EXP_LUX_VALUE_SENDED , this.luxVal );
  }

  checkDangerState() {

    if( this.luxVal < this.dangerThreshold && !this.isInDanger ) {

      this.isInDanger = true;

      Emitter.emit( EXP_PLAYER_TOGGLE_IS_IN_DANGER, true );
      Emitter.emit( EXP_FLASH_MSG, 'danger', "Uh oh, your light gauge is going down ! Catch the lux to keep swimming." );

    } else if ( this.luxVal > this.dangerThreshold && this.isInDanger ) {
      this.isInDanger = false;
      Emitter.emit( EXP_PLAYER_TOGGLE_IS_IN_DANGER, false );
    }

    console.log(this.previousluxVal, this.luxVal)
  }

  updateLuxVal() {

    if( this.luxVal > 0 && this.luxEnabled ) {
      this.previousluxVal = this.luxVal;
      this.luxVal -= this.decreaseLuxVal;
    } else if( this.luxEnabled ) {

      this.luxEnabled = false;
      Emitter.emit( EXP_LUX_END_GAME );
      Emitter.emit( EXP_FLASH_MSG, 'danger', 'You have no light, you loose. Try again !' );
    }
  }

  /**
   * update function
   * @param {number} time  Elapsed time from three global clock
   * @param {number} delta Delta time from three global clock
   */
  update( time, delta ) {

    this.updateLuxVal();

    this.checkDangerState();

    for ( let i = 0; i < this.nbLights; i++ ) {
      this.updateLight( this.lights[ i ], time, delta );
    }
  }

  /**
   * updateLight function
   * @param {Light} light Light to update
   * @param {time} time   Elapsed time from three global clock
   */
  updateLight( light, time ) {

    const gOption = light.gravitationOptions;
    light.position.x = Math.sin( gOption.x.velocity * time + gOption.x.offset ) * gOption.x.distance;
    light.position.y = Math.sin( gOption.y.velocity * time + gOption.y.offset ) * gOption.y.distance;
    light.position.z = Math.cos( gOption.z.velocity * time + gOption.z.offset ) * gOption.z.distance;

    light.intensity = this.luxVal * this.playerConfig.intensity;
  }
}

export default Player;
<commit_msg>Experience - Remove unused console log.<commit_after>import Cannon from 'cannon';
import PointLight from '../lights/PointLight';
import { randomInt, clamp } from 'utils';

import Emitter from 'helpers/Emitter';

import {
  EXP_LUX_TOGGLE,
  EXP_LUX_END_GAME,
  EXP_FLASH_MSG,
  EXP_GET_LUX_VALUE,
  EXP_LUX_VALUE_SENDED,
  EXP_LUX_VALUE_UPDATE,
  EXP_PLAYER_TOGGLE_IS_IN_DANGER
} from 'config/messages';

/**
 * Player class
 * @param {Configuration} Configuration Configuration
 * @param {World} World instance
 */
class Player extends THREE.Object3D {

  /**
   * constructor function
   * @param {World}  World         World instance
   * @param {Object} playerConfig  Player Configuration
   * @param {Object} cameraConfig  Camera Configuration
   */
  constructor( World, playerConfig, cameraConfig ) {

    super();

    this.world = World;

    this.luxEnabled = false;

    this.playerConfig = playerConfig.pointLights;
    this.cameraConfig = cameraConfig;
    this.lights = [];

    this.luxVal = 0.9;
    this.previousluxVal = 0.2;
    this.decreaseLuxVal = 1 / 10000;

    this.nbLights = this.playerConfig.number;

    this.isInDanger = false;
    this.dangerThreshold = 0.5;

    this.createSphere();
    this.initLights();

    this.bind();

    this.addListeners();

    this.debug();
  }

  bind() {

    [ 'toggleLux', 'getLuxVal', 'updateLuxVal', 'updateLuxVal', 'incrementLux', 'checkDangerState' ]
        .forEach( ( fn ) => this[ fn ] = this[ fn ].bind( this ) );
  }

  debug() {

    const onKeyUp = ( ev )=> {

      if( ev.keyCode === 76 ) { // l

        this.luxVal += 0.05;

      } else if ( ev.keyCode === 75 ) { // k

        this.luxVal -= 0.05;
      }
    };

    document.addEventListener( 'keyup', onKeyUp, false );

  }

  addListeners() {

    Emitter.on( EXP_LUX_TOGGLE, this.toggleLux );
    Emitter.on( EXP_GET_LUX_VALUE, this.getLuxVal );
    Emitter.on( EXP_LUX_VALUE_UPDATE, this.incrementLux );
  }

  toggleLux( toggleVal ) {

    this.luxEnabled = toggleVal;
  }

  /**
   * createSphere function
   */
  createSphere() {

    // Create a sphere
    const sphereShape = new Cannon.Sphere( 10 );
    this.sphereBody = new Cannon.Body({ mass: 300 });
    this.sphereBody.addShape( sphereShape );
    this.sphereBody.linearDamping = 0.9;
    this.sphereBody.position.copy( this.cameraConfig.position );
    this.world.add( this.sphereBody );

    // const geometry = new THREE.SphereGeometry( 10, 10, 10 );
    // const material = new THREE.MeshBasicMaterial({ color: 0xffff00, side: THREE.DoubleSide, wireframe: true });
    // this.sphere = new THREE.Mesh( geometry, material );
    // this.add( this.sphere );
  }

  /**
   * initLights function
   */
  initLights() {

    for ( let i = 0; i < this.nbLights; i++ ) {

      const plight = new PointLight({
        hex: parseInt( this.playerConfig.colors[ randomInt( 0, this.playerConfig.colors.length - 1 ) ], 16 ),
        intensity: this.playerConfig.intensity,
        distance: this.playerConfig.distance,
        decay: this.playerConfig.decay
      });

      plight.addSphere();

      this.lights.push( plight );

      this.add( plight );
    }
  }

  /**
   * move function
   * Move the player where the camera is
   * @param {object} newPos Position vector of the camera
   */
  move( newPos ) {

    this.position.copy( newPos );
  }

  /**
   * rotate function
   * Rotate the player where the camera is
   * @param {object} newRotation Rotation vector of the camera
   */
  rotate( newRotation ) {

    // this.sphereBody.quaternion.setFromEuler( newRotation );
  }

  incrementLux( increment ) {

    this.luxVal = clamp( 0, 1, this.luxVal + increment );
  }

  getLuxVal() {

    Emitter.emit( EXP_LUX_VALUE_SENDED , this.luxVal );
  }

  checkDangerState() {

    if( this.luxVal < this.dangerThreshold && !this.isInDanger ) {

      this.isInDanger = true;

      Emitter.emit( EXP_PLAYER_TOGGLE_IS_IN_DANGER, true );
      Emitter.emit( EXP_FLASH_MSG, 'danger', "Uh oh, your light gauge is going down ! Catch the lux to keep swimming." );

    } else if ( this.luxVal > this.dangerThreshold && this.isInDanger ) {
      this.isInDanger = false;
      Emitter.emit( EXP_PLAYER_TOGGLE_IS_IN_DANGER, false );
    }
  }

  updateLuxVal() {

    if( this.luxVal > 0 && this.luxEnabled ) {
      this.previousluxVal = this.luxVal;
      this.luxVal -= this.decreaseLuxVal;
    } else if( this.luxEnabled ) {

      this.luxEnabled = false;
      Emitter.emit( EXP_LUX_END_GAME );
      Emitter.emit( EXP_FLASH_MSG, 'danger', 'You have no light, you loose. Try again !' );
    }
  }

  /**
   * update function
   * @param {number} time  Elapsed time from three global clock
   * @param {number} delta Delta time from three global clock
   */
  update( time, delta ) {

    this.updateLuxVal();

    this.checkDangerState();

    for ( let i = 0; i < this.nbLights; i++ ) {
      this.updateLight( this.lights[ i ], time, delta );
    }
  }

  /**
   * updateLight function
   * @param {Light} light Light to update
   * @param {time} time   Elapsed time from three global clock
   */
  updateLight( light, time ) {

    const gOption = light.gravitationOptions;
    light.position.x = Math.sin( gOption.x.velocity * time + gOption.x.offset ) * gOption.x.distance;
    light.position.y = Math.sin( gOption.y.velocity * time + gOption.y.offset ) * gOption.y.distance;
    light.position.z = Math.cos( gOption.z.velocity * time + gOption.z.offset ) * gOption.z.distance;

    light.intensity = this.luxVal * this.playerConfig.intensity;
  }
}

export default Player;
<|endoftext|>