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

'use strict';

var util = require('util');

var profile = require('../../../util/profile');
var utils = require('../../../util/utils');

var groupUtils = require('./groupUtils');

var $ = utils.getLocaleString;

exports.init = function (cli) {
  var log = cli.output;

  var group = cli.category('group');
  var deployment = group.category('deployment')
      .description($('Commands to manage your deployment in a resource group'));

  deployment.command('create [resource-group] [mode] [name]')
    .description($('Creates a deployment.'))
    .option('-g --resource-group <resource-group>', $('the name of the resource group'))
    .option('-n --name <name>', $('the name of the deployment'))
    .option('-y --gallery-template <gallery-template>', $('the name of the template in the gallery'))
    .option('-f --file-template <file-template>', $('the path to the template file, local or remote'))
    //TODO: comment out till CSM supports contentHash
    //.option('--template-hash <template-hash>', $('the content hash of the template'))
    //.option('--template-hash-algorithm <template-hash-algorithm>', $('the algorithm used to hash the template content'))
    .option('--template-version <template-version>', $('the content version of the template'))
    .option('-s --storage-account <storage-account>', $('the storage account where to upload the template file to'))
    .option('-m --mode <mode>', $('the mode of the template deployment. Valid values are Replace, New and Incremental'))
    .option('-p --parameters <parameters>', $('the string in JSON format which represents the parameters'))
    .option('-e --parameters-file <parametersFile>', $('the file with parameters'))
    //TODO: comment out till CSM supports contentHash
    //.option('--parameters-hash <parameters-hash>', $('the content hash of the parameters'))
    //.option('--parameters-hash-algorithm <parameters-hash-algorithm>', $('the algorithm used to hash the parameters content'))
    .option('--parameters-version <parameters-version>', $('the expect content version of the parameters'))
    .option('--subscription <subscription>', $('the subscription identifier'))
    .option('--env [env]', $('Azure environment to run against'))
    .execute(function (resourceGroup, mode, name, options, _) {
      if (!resourceGroup) {
        return cli.missingArgument('resourceGroup');
      }
      var deployment = groupUtils.createDeployment(cli, resourceGroup, mode, name, options, _);

      displayDeployment(deployment, resourceGroup, true, cli.output);
    });

  deployment.command('list [resource-group] [state]')
    .usage('[options] <resource-group> [state]')
    .description($('Get deployments'))
    .option('-g --resource-group <resourceGroup>', $('Name of the resource group.'))
    .option('--state <state>', $('Optional. Filter the deployments by provisioning state, valid ' +
      'values are Accepted, Running, Failed and Succeeded.'))
    .option('--subscription <subscription>', $('Optional. Subscription containing deployments to list'))
    .execute(function (resourceGroup, state, options, _) {
      if (!resourceGroup) {
        return cli.missingArgument('resourceGroup');
      }
      var subscription = profile.current.getSubscription(options.subscription);
      var client = subscription.createResourceClient('createResourceManagementClient');
      var progress = cli.interaction.progress($('Listing deployments'));
      var allDeployments;
      try {
        allDeployments = retrieveDeployments(client, resourceGroup, state, _);
      } finally {
        progress.end();
      }

      cli.interaction.formatOutput(allDeployments, function (outputData) {
        if (outputData) {
          for (var i = 0; i < outputData.length; i++) {
            var deployment = outputData[i];
            displayDeployment(deployment, resourceGroup, false, log);
            if (i !== outputData.length - 1) {
              //Insert an empty line between each deployment.
              log.data($(''));
            }
          }
        }
      });
    });

  deployment.command('show [resource-group] [name]')
    .usage('[options] <resource-group> [deployment-name]')
    .description($('Show a deployment'))
    .option('-g --resource-group <resourceGroup>', $('Name of the resource group.'))
    .option('-n --name <name>', $('Optional. Name of the deployment. ' +
            'If not specified, show the most recent deployment.'))
    .option('--subscription <subscription>', $('Optional. Subscription containing the deployment to display'))
    .execute(function (resourceGroup, name, options, _) {
      if (!resourceGroup) {
        return cli.missingArgument('resourceGroup');
      }
      var subscription = profile.current.getSubscription(options.subscription);
      var client = subscription.createResourceClient('createResourceManagementClient');
      var progress = cli.interaction.progress($('Getting deployments'));
      var deployment;
      try {
        if (name) {
          deployment = client.deployments.get(resourceGroup, name, _).deployment;
        }
        else {
          //look for the most recent one
          var allDeployments = retrieveDeployments(client, resourceGroup, '', _);
          if (allDeployments && allDeployments.length > 0) {
            allDeployments.sort(function (a, b) {
              return Date.parse(a.properties.timestamp) < Date.parse(b.properties.timestamp);
            });
            deployment = allDeployments[0];
          }
        }
      } finally {
        progress.end();
      }

      if (deployment) {
        displayDeployment(deployment, resourceGroup, true, log);
      }
    });

  deployment.command('stop [resource-group] [name]')
    .usage('[options] <resource-group> [deployment-name]')
    .description($('Stop a specified deployment or a current running one.'))
    .option('-g --resource-group <resourceGroup>', $('Name of the resource group.'))
    .option('-q --quiet', $('Quiet mode. Do not ask confirmation for stop deployment'))
    .option('-n --name <name>', $('Optional. Name of the deployment. ' +
        'If not specified, stop the current running deployment.'))
    .option('--subscription <subscription>', $('the subscription identifier'))
    .execute(function (resourceGroup, name, options, _) {
      if (!resourceGroup) {
        return cli.missingArgument('resourceGroup');
      }
      var subscription = profile.current.getSubscription(options.subscription);
      var client = subscription.createResourceClient('createResourceManagementClient');
      var deploymentToStop = name;

      if (!name) {
        cli.interaction.withProgress($('Looking for Running or Accepted deployment'),
          function (log, _) {
            //We leverage service side filtering for simplicity and less payload on the wire . If user data
            //proves the extra round trip causes non-trivial latency, we can choose to do it at the client side.
            var allRunningDeployments = retrieveDeployments(client, resourceGroup, 'Running', _);
            var allAcceptedDeployments = retrieveDeployments(client, resourceGroup, 'Accepted', _);
            var allCancellableDeployments = allRunningDeployments;
            if (!allCancellableDeployments){
              allCancellableDeployments = allAcceptedDeployments;
            } else {
              allCancellableDeployments = allCancellableDeployments.concat(allAcceptedDeployments);
            }

            if (allCancellableDeployments && allCancellableDeployments.length > 0) {
              if (allCancellableDeployments.length > 1) {
                throw new Error($('There are more than 1 deployment in either Running or Accepted state, please name one.'));
              }
              deploymentToStop = allCancellableDeployments[0].deploymentName;
              log.info(util.format($('Found a deployment: %s'), deploymentToStop));
            }
            else {
              log.info($('There is no deployment to stop.'));
            }
          }, _);
      }

      if (deploymentToStop) {
        if (!options.quiet &&
            !cli.interaction.confirm(util.format($('Stop deployment %s? [y/n]: '), deploymentToStop), _)) {
          return;
        }

        var progress = cli.interaction.progress($('Stopping deployment'));

        try {
          client.deployments.cancel(resourceGroup, deploymentToStop, _);
        } finally {
          progress.end();
        }
      }
    });
};

function retrieveDeployments(client, resourceGroup, state, _) {
  //Wrap with single quots(needed for constructing RESTful query string)
  var stateFilter = state;
  if (stateFilter && !(utils.stringStartsWith(stateFilter, '\''))) {
    stateFilter = '\'' + stateFilter + '\'';
  }

  var response = client.deployments.list(resourceGroup, { provisioningState: stateFilter }, _);
  var allDeployments = response.deployments;
  var nextLink = response.nextLink;

  while (nextLink) {
    response = client.deployments.listNext(nextLink, _);
    allDeployments = allDeployments.concat(response.deployments);
    nextLink = response.nextLink;
  }

  return allDeployments;
}

function displayDeployment(deployment, resourceGroup, showDetail, log) {
  log.data($('DeploymentName     :'), deployment.name || deployment.deploymentName);
  log.data($('ResourceGroupName  :'), resourceGroup);
  log.data($('ProvisioningState  :'), deployment.properties.provisioningState);
  log.data($('Timestamp          :'), deployment.properties.timestamp);
  log.data($('Mode               :'), deployment.properties.mode);
  if (showDetail) {
    log.data($('TemplateLink       :'), deployment.properties.templateLink.uri);
    log.data($('ContentVersion     :'), deployment.properties.templateLink.contentVersion);
    //TODO: comment out till CSM supports contentHash
    //log.data($('ContentHash        :'), deployment.properties.templateLink.contentHash ?
    //  deployment.properties.templateLink.contentHash.value : '');
    log.table(deployment.properties.parameters, function (row, item) {
      row.cell($('Name'), item);
      row.cell($('Type'), deployment.properties.parameters[item].type);
      row.cell($('Value'), deployment.properties.parameters[item].value);
    });
  }
}<commit_msg>address review feedback<commit_after>/**
* Copyright (c) Microsoft.  All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

'use strict';

var util = require('util');

var profile = require('../../../util/profile');
var utils = require('../../../util/utils');

var groupUtils = require('./groupUtils');

var $ = utils.getLocaleString;

exports.init = function (cli) {
  var log = cli.output;

  var group = cli.category('group');
  var deployment = group.category('deployment')
      .description($('Commands to manage your deployment in a resource group'));

  deployment.command('create [resource-group] [mode] [name]')
    .description($('Creates a deployment.'))
    .option('-g --resource-group <resource-group>', $('the name of the resource group'))
    .option('-n --name <name>', $('the name of the deployment'))
    .option('-y --gallery-template <gallery-template>', $('the name of the template in the gallery'))
    .option('-f --file-template <file-template>', $('the path to the template file, local or remote'))
    //TODO: comment out till CSM supports contentHash
    //.option('--template-hash <template-hash>', $('the content hash of the template'))
    //.option('--template-hash-algorithm <template-hash-algorithm>', $('the algorithm used to hash the template content'))
    .option('--template-version <template-version>', $('the content version of the template'))
    .option('-s --storage-account <storage-account>', $('the storage account where to upload the template file to'))
    .option('-m --mode <mode>', $('the mode of the template deployment. Valid values are Replace, New and Incremental'))
    .option('-p --parameters <parameters>', $('the string in JSON format which represents the parameters'))
    .option('-e --parameters-file <parametersFile>', $('the file with parameters'))
    //TODO: comment out till CSM supports contentHash
    //.option('--parameters-hash <parameters-hash>', $('the content hash of the parameters'))
    //.option('--parameters-hash-algorithm <parameters-hash-algorithm>', $('the algorithm used to hash the parameters content'))
    .option('--parameters-version <parameters-version>', $('the expect content version of the parameters'))
    .option('--subscription <subscription>', $('the subscription identifier'))
    .option('--env [env]', $('Azure environment to run against'))
    .execute(function (resourceGroup, mode, name, options, _) {
      if (!resourceGroup) {
        return cli.missingArgument('resourceGroup');
      }
      var deployment = groupUtils.createDeployment(cli, resourceGroup, mode, name, options, _);

      displayDeployment(deployment, resourceGroup, true, cli.output);
    });

  deployment.command('list [resource-group] [state]')
    .usage('[options] <resource-group> [state]')
    .description($('Get deployments'))
    .option('-g --resource-group <resourceGroup>', $('Name of the resource group.'))
    .option('--state <state>', $('Optional. Filter the deployments by provisioning state, valid ' +
      'values are Accepted, Running, Failed and Succeeded.'))
    .option('--subscription <subscription>', $('Optional. Subscription containing deployments to list'))
    .execute(function (resourceGroup, state, options, _) {
      if (!resourceGroup) {
        return cli.missingArgument('resourceGroup');
      }
      var subscription = profile.current.getSubscription(options.subscription);
      var client = subscription.createResourceClient('createResourceManagementClient');
      var progress = cli.interaction.progress($('Listing deployments'));
      var allDeployments;
      try {
        allDeployments = retrieveDeployments(client, resourceGroup, state, _);
      } finally {
        progress.end();
      }

      cli.interaction.formatOutput(allDeployments, function (outputData) {
        if (outputData) {
          for (var i = 0; i < outputData.length; i++) {
            var deployment = outputData[i];
            displayDeployment(deployment, resourceGroup, false, log);
            if (i !== outputData.length - 1) {
              //Insert an empty line between each deployment.
              log.data($(''));
            }
          }
        }
      });
    });

  deployment.command('show [resource-group] [name]')
    .usage('[options] <resource-group> [deployment-name]')
    .description($('Show a deployment'))
    .option('-g --resource-group <resourceGroup>', $('Name of the resource group.'))
    .option('-n --name <name>', $('Optional. Name of the deployment. ' +
            'If not specified, show the most recent deployment.'))
    .option('--subscription <subscription>', $('Optional. Subscription containing the deployment to display'))
    .execute(function (resourceGroup, name, options, _) {
      if (!resourceGroup) {
        return cli.missingArgument('resourceGroup');
      }
      var subscription = profile.current.getSubscription(options.subscription);
      var client = subscription.createResourceClient('createResourceManagementClient');
      var progress = cli.interaction.progress($('Getting deployments'));
      var deployment;
      try {
        if (name) {
          deployment = client.deployments.get(resourceGroup, name, _).deployment;
        }
        else {
          //look for the most recent one
          var allDeployments = retrieveDeployments(client, resourceGroup, '', _);
          if (allDeployments && allDeployments.length > 0) {
            allDeployments.sort(function (a, b) {
              return Date.parse(a.properties.timestamp) < Date.parse(b.properties.timestamp);
            });
            deployment = allDeployments[0];
          }
        }
      } finally {
        progress.end();
      }

      if (deployment) {
        displayDeployment(deployment, resourceGroup, true, log);
      }
    });

  deployment.command('stop [resource-group] [name]')
    .usage('[options] <resource-group> [deployment-name]')
    .description($('Stop a specified deployment or a current running one.'))
    .option('-g --resource-group <resourceGroup>', $('Name of the resource group.'))
    .option('-q --quiet', $('Quiet mode. Do not ask confirmation for stop deployment'))
    .option('-n --name <name>', $('Optional. Name of the deployment. ' +
        'If not specified, stop the current running deployment.'))
    .option('--subscription <subscription>', $('the subscription identifier'))
    .execute(function (resourceGroup, name, options, _) {
      if (!resourceGroup) {
        return cli.missingArgument('resourceGroup');
      }
      var subscription = profile.current.getSubscription(options.subscription);
      var client = subscription.createResourceClient('createResourceManagementClient');
      var deploymentToStop = name;

      if (!name) {
        cli.interaction.withProgress($('Looking for "Running" or "Accepted" deployment'),
          function (log, _) {
            //We leverage service side filtering for simplicity and less payload on the wire. If user data
            //proves the extra round trip causes non-trivial latency, we can choose to do it at the client side.
            var allRunningDeployments = retrieveDeployments(client, resourceGroup, 'Running', _);
            var allAcceptedDeployments = retrieveDeployments(client, resourceGroup, 'Accepted', _);
            var allCancellableDeployments = allRunningDeployments;
            if (!allCancellableDeployments){
              allCancellableDeployments = allAcceptedDeployments;
            } else {
              allCancellableDeployments = allCancellableDeployments.concat(allAcceptedDeployments);
            }

            if (allCancellableDeployments && allCancellableDeployments.length > 0) {
              if (allCancellableDeployments.length > 1) {
                throw new Error($('There are more than 1 deployment in either "Running" or "Accepted" state, please name one.'));
              }
              deploymentToStop = allCancellableDeployments[0].deploymentName;
              log.info(util.format($('Found a deployment: %s'), deploymentToStop));
            }
            else {
              log.info($('There is no deployment to stop.'));
            }
          }, _);
      }

      if (deploymentToStop) {
        if (!options.quiet &&
            !cli.interaction.confirm(util.format($('Stop deployment %s? [y/n]: '), deploymentToStop), _)) {
          return;
        }

        var progress = cli.interaction.progress($('Stopping deployment'));

        try {
          client.deployments.cancel(resourceGroup, deploymentToStop, _);
        } finally {
          progress.end();
        }
      }
    });
};

function retrieveDeployments(client, resourceGroup, state, _) {
  //Wrap with single quots(needed for constructing RESTful query string)
  var stateFilter = state;
  if (stateFilter && !(utils.stringStartsWith(stateFilter, '\''))) {
    stateFilter = '\'' + stateFilter + '\'';
  }

  var response = client.deployments.list(resourceGroup, { provisioningState: stateFilter }, _);
  var allDeployments = response.deployments;
  var nextLink = response.nextLink;

  while (nextLink) {
    response = client.deployments.listNext(nextLink, _);
    allDeployments = allDeployments.concat(response.deployments);
    nextLink = response.nextLink;
  }

  return allDeployments;
}

function displayDeployment(deployment, resourceGroup, showDetail, log) {
  log.data($('DeploymentName     :'), deployment.name || deployment.deploymentName);
  log.data($('ResourceGroupName  :'), resourceGroup);
  log.data($('ProvisioningState  :'), deployment.properties.provisioningState);
  log.data($('Timestamp          :'), deployment.properties.timestamp);
  log.data($('Mode               :'), deployment.properties.mode);
  if (showDetail) {
    log.data($('TemplateLink       :'), deployment.properties.templateLink.uri);
    log.data($('ContentVersion     :'), deployment.properties.templateLink.contentVersion);
    //TODO: comment out till CSM supports contentHash
    //log.data($('ContentHash        :'), deployment.properties.templateLink.contentHash ?
    //  deployment.properties.templateLink.contentHash.value : '');
    log.table(deployment.properties.parameters, function (row, item) {
      row.cell($('Name'), item);
      row.cell($('Type'), deployment.properties.parameters[item].type);
      row.cell($('Value'), deployment.properties.parameters[item].value);
    });
  }
}<|endoftext|>


<commit_before>window.InstrumentListView = Backbone.View.extend({

    initialize: function () {

    },

    render: function () {
        var instruments = this.model.models;
        var len = instruments.length;
        console.log("Instrument list: " + len + " instruments");
        var items = parseInt(settings.get('itemsperpage'));
        var startPos = (this.options.page - 1) * items;
        var endPos = Math.min(startPos + items, len);

        $(this.el).html('

');

        for (var i = startPos; i < endPos; i++) {
            $('.thumbnails', this.el).append(new InstrumentListItemView({model: instruments[i]}).render().el);
        }

        $(this.el).append(new Paginator({model: this.model, page: this.options.page, items: items}).render().el);

        return this;
    }
});

window.InstrumentListItemView = Backbone.View.extend({

    tagName: "li",

    initialize: function () {
        this.model.bind("change", this.render, this);
        this.model.bind("destroy", this.close, this);
    },

    render: function () {
        $(this.el).html(this.template(this.model.toJSON()));
        return this;
    },

    events: {
        "click .select" : "selectInstrument",
        "click .edit": "editInstrument"
    },

    editInstrument: function(event) {
        var url = event.target.href.substr(event.target.baseURI.length);
        app.navigate(url, {trigger: true});
        event.stopPropagation();
    },

    selectInstrument: function(event) {
        console.log('Instrument selected: ' + this.model.id);
        var theID = this.model.id;
        // Now store the instrument ID in our settings:
        this.options.settings.set({currentInstrument:theID});
        // Update our settings to use the correct port:
        this.options.settings.set({ serialPort: this.model.get('port')});
        this.options.settings.save(null, {success: function() {
            app.navigate('/', true);
        }});
        return false;
    },

});<commit_msg>Bugfix: forgot one reference in instrumentlist.js<commit_after>window.InstrumentListView = Backbone.View.extend({

    initialize: function () {

    },

    render: function () {
        var instruments = this.model.models;
        var len = instruments.length;
        console.log("Instrument list: " + len + " instruments");
        var items = parseInt(settings.get('itemsperpage'));
        var startPos = (this.options.page - 1) * items;
        var endPos = Math.min(startPos + items, len);

        $(this.el).html('

');

        for (var i = startPos; i < endPos; i++) {
            $('.thumbnails', this.el).append(new InstrumentListItemView({model: instruments[i]}).render().el);
        }

        $(this.el).append(new Paginator({model: this.model, page: this.options.page, items: items}).render().el);

        return this;
    }
});

window.InstrumentListItemView = Backbone.View.extend({

    tagName: "li",

    initialize: function () {
        this.model.bind("change", this.render, this);
        this.model.bind("destroy", this.close, this);
    },

    render: function () {
        $(this.el).html(this.template(this.model.toJSON()));
        return this;
    },

    events: {
        "click .select" : "selectInstrument",
        "click .edit": "editInstrument"
    },

    editInstrument: function(event) {
        var url = event.target.href.substr(event.target.baseURI.length);
        app.navigate(url, {trigger: true});
        event.stopPropagation();
    },

    selectInstrument: function(event) {
        console.log('Instrument selected: ' + this.model.id);
        var theID = this.model.id;
        // Now store the instrument ID in our settings:
        settings.set({currentInstrument:theID});
        // Update our settings to use the correct port:
        settings.set({ serialPort: this.model.get('port')});
        settings.save(null, {success: function() {
            app.navigate('/', true);
        }});
        return false;
    },

});<|endoftext|>


<commit_before>import * as t from "../lib";
import glob from "glob";
import path from "path";
import fs from "fs";
import { inspect } from "util";

// eslint-disable-next-line no-restricted-globals
const packages = path.resolve(__dirname, "..", "..");

function readJson(file) {
  return new Promise((resolve, reject) => {
    fs.readFile(file, "utf8", (err, data) => {
      if (err) reject(err);
      else resolve(JSON.parse(data));
    });
  });
}

function traverse(thing, visitor) {
  if (Array.isArray(thing)) {
    thing.forEach(elem => traverse(elem, visitor));
  } else if (thing instanceof Object && typeof thing.type === "string") {
    visitor(thing);
    for (const key in thing) {
      const value = thing[key];
      if (value instanceof Object) traverse(value, visitor);
    }
  }
}

const files = glob.sync(
  path.join("babel-parser", "test", "**", "output.json"),
  {
    cwd: packages,
    ignore: [
      path.join("**", "estree*", "**"),
      path.join("**", "is-expression-babel-parser", "**"),
    ],
  },
);

const ignoredFields = {
  ArrowFunctionExpression: { id: true, predicate: true },
  ClassMethod: { id: true, predicate: true },
  ClassPrivateMethod: { id: true, predicate: true },
  ClassPrivateProperty: { declare: true, optional: true },
  FunctionDeclaration: { predicate: true },
  FunctionExpression: { predicate: true },
  ImportDeclaration: { attributes: true },
  ObjectProperty: { method: true },
  ObjectMethod: { method: true, id: true, predicate: true },
  StaticBlock: { static: true },
  TSDeclareMethod: { id: true },
};

function isEmpty(obj) {
  for (const key in obj) return false;
  return true;
}

describe("NODE_FIELDS contains all fields in", function () {
  files.forEach(file =>
    it(`${file}`, async function () {
      const ast = await readJson(path.resolve(packages, file));
      if (ast.type === "File" && ast.errors && ast.errors.length) return;
      t[`assert${ast.type}`](ast);
      const missingFields = {};
      traverse(ast, node => {
        const { type } = node;
        switch (type) {
          case "File":
          case "CommentBlock":
          case "CommentLine":
            return;
        }
        if (ignoredFields[type] === true) return;
        const fields = t.NODE_FIELDS[type];
        if (!fields) {
          if (!missingFields[type]) {
            missingFields[type] = {
              MISSING_TYPE: true,
            };
          }
          return;
        }
        for (const field in node) {
          switch (field) {
            case "type":
            case "start":
            case "end":
            case "loc":
            case "range":
            case "leadingComments":
            case "innerComments":
            case "trailingComments":
            case "comments":
            case "extra":
              continue;
          }
          if (!fields[field]) {
            if (ignoredFields[type] && ignoredFields[type][field]) continue;
            if (!missingFields[type]) missingFields[type] = {};
            if (!missingFields[type][field]) {
              missingFields[type][field] = true;
            }
          }
        }
      });
      if (!isEmpty(missingFields)) {
        throw new Error(
          `the following NODE_FIELDS were missing: ${inspect(missingFields)}`,
        );
      }
    }),
  );
});
<commit_msg>Use `import.meta.url` instead of `__dirname` (#13721)<commit_after>import * as t from "../lib";
import glob from "glob";
import path from "path";
import fs from "fs";
import { inspect } from "util";
import { fileURLToPath } from "url";

const dirname = path.dirname(fileURLToPath(import.meta.url));
const packages = path.resolve(dirname, "..", "..");

function readJson(file) {
  return new Promise((resolve, reject) => {
    fs.readFile(file, "utf8", (err, data) => {
      if (err) reject(err);
      else resolve(JSON.parse(data));
    });
  });
}

function traverse(thing, visitor) {
  if (Array.isArray(thing)) {
    thing.forEach(elem => traverse(elem, visitor));
  } else if (thing instanceof Object && typeof thing.type === "string") {
    visitor(thing);
    for (const key in thing) {
      const value = thing[key];
      if (value instanceof Object) traverse(value, visitor);
    }
  }
}

const files = glob.sync(
  path.join("babel-parser", "test", "**", "output.json"),
  {
    cwd: packages,
    ignore: [
      path.join("**", "estree*", "**"),
      path.join("**", "is-expression-babel-parser", "**"),
    ],
  },
);

const ignoredFields = {
  ArrowFunctionExpression: { id: true, predicate: true },
  ClassMethod: { id: true, predicate: true },
  ClassPrivateMethod: { id: true, predicate: true },
  ClassPrivateProperty: { declare: true, optional: true },
  FunctionDeclaration: { predicate: true },
  FunctionExpression: { predicate: true },
  ImportDeclaration: { attributes: true },
  ObjectProperty: { method: true },
  ObjectMethod: { method: true, id: true, predicate: true },
  StaticBlock: { static: true },
  TSDeclareMethod: { id: true },
};

function isEmpty(obj) {
  for (const key in obj) return false;
  return true;
}

describe("NODE_FIELDS contains all fields in", function () {
  files.forEach(file =>
    it(`${file}`, async function () {
      const ast = await readJson(path.resolve(packages, file));
      if (ast.type === "File" && ast.errors && ast.errors.length) return;
      t[`assert${ast.type}`](ast);
      const missingFields = {};
      traverse(ast, node => {
        const { type } = node;
        switch (type) {
          case "File":
          case "CommentBlock":
          case "CommentLine":
            return;
        }
        if (ignoredFields[type] === true) return;
        const fields = t.NODE_FIELDS[type];
        if (!fields) {
          if (!missingFields[type]) {
            missingFields[type] = {
              MISSING_TYPE: true,
            };
          }
          return;
        }
        for (const field in node) {
          switch (field) {
            case "type":
            case "start":
            case "end":
            case "loc":
            case "range":
            case "leadingComments":
            case "innerComments":
            case "trailingComments":
            case "comments":
            case "extra":
              continue;
          }
          if (!fields[field]) {
            if (ignoredFields[type] && ignoredFields[type][field]) continue;
            if (!missingFields[type]) missingFields[type] = {};
            if (!missingFields[type][field]) {
              missingFields[type][field] = true;
            }
          }
        }
      });
      if (!isEmpty(missingFields)) {
        throw new Error(
          `the following NODE_FIELDS were missing: ${inspect(missingFields)}`,
        );
      }
    }),
  );
});
<|endoftext|>


<commit_before>import Ember from 'ember';
import ComputedValidationsMixin from 'ember-computed-validations/mixins/computed-validations';
import { module, test } from 'qunit';

module('Unit | Mixin | computed validations');

// Replace this with your real tests.
test('it works', function(assert) {
  var ComputedValidationsObject = Ember.Object.extend(ComputedValidationsMixin);
  var subject = ComputedValidationsObject.create();
  assert.ok(subject);
});
<commit_msg>Add tests<commit_after>import Ember from 'ember';
import ComputedValidationsMixin from 'ember-computed-validations/mixins/computed-validations';
import { module, test } from 'qunit';

module('Unit | Mixin | computed validations');

// Replace this with your real tests.
test('it works', function(assert) {
  var ComputedValidationsObject = Ember.Object.extend(ComputedValidationsMixin);
  var subject = ComputedValidationsObject.create();
  assert.ok(subject);
});

test('it can validate with a computed property', function(assert) {
  var ComputedValidationsObject = Ember.Object.extend(ComputedValidationsMixin, {
    firstName: null,
    firstNameNotEmpty: Ember.computed.notEmpty('firstName'),
    computedValidations: {
      firstName: {
        firstNameNotEmpty: 'First name is a required field.'
      }
    }
  });
  var subject = ComputedValidationsObject.create();
  assert.equal(subject.get('computedIsValid'), false);
  assert.equal(subject.get('computedIsInvalid'), true);
  assert.deepEqual(subject.get('computedErrors.firstName'), ['First name is a required field.']);

  subject.set('firstName', 'Bob');

  assert.equal(subject.get('computedIsValid'), true);
  assert.equal(subject.get('computedIsInvalid'), false);
  assert.deepEqual(subject.get('computedErrors.firstName'), []);
});

test('it can validate without a computed property', function(assert) {
  var ComputedValidationsObject = Ember.Object.extend(ComputedValidationsMixin, {
    firstName: null,
    computedValidations: {
      firstName: {
        firstName: 'First name is a required field.'
      }
    }
  });
  var subject = ComputedValidationsObject.create();
  assert.equal(subject.get('computedIsValid'), false);
  assert.equal(subject.get('computedIsInvalid'), true);
  assert.deepEqual(subject.get('computedErrors.firstName'), ['First name is a required field.']);

  subject.set('firstName', 'Bob');

  assert.equal(subject.get('computedIsValid'), true);
  assert.equal(subject.get('computedIsInvalid'), false);
  assert.deepEqual(subject.get('computedErrors.firstName'), []);
});

test('it can validate a nested property', function(assert) {
  var ComputedValidationsObject = Ember.Object.extend(ComputedValidationsMixin, {
    user: null,
    computedValidations: {
      firstName: {
        'user.firstName': 'First name is a required field.'
      }
    }
  });
  var subject = ComputedValidationsObject.create();
  assert.equal(subject.get('computedIsValid'), false);
  assert.equal(subject.get('computedIsInvalid'), true);
  assert.deepEqual(subject.get('computedErrors.firstName'), ['First name is a required field.']);

  subject.set('user', {firstName:'Bob'});

  assert.equal(subject.get('computedIsValid'), true);
  assert.equal(subject.get('computedIsInvalid'), false);
  assert.deepEqual(subject.get('computedErrors.firstName'), []);
});

test('it can validate a property with multiple validations', function(assert) {
  var ComputedValidationsObject = Ember.Object.extend(ComputedValidationsMixin, {
    user: null,
    passwordsMatch: Ember.computed('user.password1', 'user.password2', function() {
      return this.get('user.password1') === this.get('user.password2');
    }),
    computedValidations: {
      password: {
        'user.password1': 'Please enter a password.',
        passwordsMatch: 'The password fields must match.'
      }
    }
  });
  var subject = ComputedValidationsObject.create();
  assert.equal(subject.get('computedIsValid'), false);
  assert.equal(subject.get('computedIsInvalid'), true);
  assert.deepEqual(subject.get('computedErrors.password'), ['Please enter a password.']);

  subject.set('user', {password1: 'p@ssw0rd!'});

  assert.equal(subject.get('computedIsValid'), false);
  assert.equal(subject.get('computedIsInvalid'), true);
  assert.deepEqual(subject.get('computedErrors.password'), ['The password fields must match.']);

  subject.set('user.password2', 'p@ssw0rd!');

  assert.equal(subject.get('computedIsValid'), true);
  assert.equal(subject.get('computedIsInvalid'), false);
  assert.deepEqual(subject.get('computedErrors.password'), []);

  subject.set('user.password1', null);

  assert.equal(subject.get('computedIsValid'), false);
  assert.equal(subject.get('computedIsInvalid'), true);
  assert.deepEqual(subject.get('computedErrors.password'), ['Please enter a password.', 'The password fields must match.']);
});
<|endoftext|>


<commit_before>Slack = {};

OAuth.registerService('slack', 2, null, function(query) {
  var tokens = getTokens(query);
  var identity = getIdentity(tokens.access_token);

  // console.log('tokens', tokens);
  // console.log('identity', identity);

  return {
    serviceData: {
      id: identity.user_id,
      accessToken: tokens.access_token,
      botAccessToken: tokens.bot_access_token
    },
    options: {
      profile: {
        name: identity.user,
        url: identity.url,
        team: identity.team,
        user_id: identity.user_id,
        team_id: identity.team_id
      },
      slack: {
        tokens: tokens,
        identity: identity,
      }
    }
  };
});

var getTokens = function (query) {
  var config = ServiceConfiguration.configurations.findOne({service: 'slack'});
  if (!config)
    throw new ServiceConfiguration.ConfigError();

  var response;
  try {
    response = HTTP.post(
      "https://slack.com/api/oauth.access", {
        headers: {
          Accept: 'application/json'
        },
        params: {
          code: query.code,
          client_id: config.clientId,
          client_secret: OAuth.openSecret(config.secret),
  //        redirect_uri: Meteor.absoluteUrl("_oauth/slack?close")
          redirect_uri: OAuth._redirectUri('slack', config),
          state: query.state
        }
      });
  } catch (err) {
    throw _.extend(new Error("Failed to complete OAuth handshake with Slack. " + err.message),
                   {response: err.response});
  }

  if (!response.data.ok) { // if the http response was a json object with an error attribute
    throw new Error("Failed to complete OAuth handshake with Slack. " + response.data.error);
  } else {
    return response.data;
  }
};

var getIdentity = function (accessToken) {
  try {
    var response = HTTP.get(
      "https://slack.com/api/auth.test",
      {params: {token: accessToken}});

    if (response.data && response.data.ok)
      return response.data;

    response = HTTP.get(
      "https://slack.com/api/users.identity",
      {params: {token: accessToken}});

    if (response.data && response.data.ok)
      // Simulate the response that auth.test would have returned
      return _.extend(response.data.user, {
        user: response.data.user.name,
        user_id: response.data.user.id,
        team_id: response.data.team.id,
        team: response.data.team.name,
        url: response.data.url
      });
    else
      throw new Error("Could not retrieve user identity");
  } catch (err) {
    throw _.extend(new Error("Failed to fetch identity from Slack. " + err.message),
                   {response: err.response});
  }
};

Slack.retrieveCredential = function(credentialToken, credentialSecret) {
  return OAuth.retrieveCredential(credentialToken, credentialSecret);
};
<commit_msg>:sparkles: fixes bot token bug according to new slack api spec<commit_after>Slack = {};

OAuth.registerService('slack', 2, null, function(query) {
  var tokens = getTokens(query);
  var identity = getIdentity(tokens.access_token);

  // console.log('tokens', tokens);
  // console.log('identity', identity);

  return {
    serviceData: {
      id: identity.user_id,
      accessToken: tokens.access_token,
      botAccessToken: tokens.bot.bot_access_token,
      botUserId: tokens.bot.bot_user_id
    },
    options: {
      profile: {
        name: identity.user,
        url: identity.url,
        team: identity.team,
        user_id: identity.user_id,
        team_id: identity.team_id
      },
      slack: {
        tokens: tokens,
        identity: identity,
      }
    }
  };
});

var getTokens = function (query) {
  var config = ServiceConfiguration.configurations.findOne({service: 'slack'});
  if (!config)
    throw new ServiceConfiguration.ConfigError();

  var response;
  try {
    response = HTTP.post(
      "https://slack.com/api/oauth.access", {
        headers: {
          Accept: 'application/json'
        },
        params: {
          code: query.code,
          client_id: config.clientId,
          client_secret: OAuth.openSecret(config.secret),
  //        redirect_uri: Meteor.absoluteUrl("_oauth/slack?close")
          redirect_uri: OAuth._redirectUri('slack', config),
          state: query.state
        }
      });
  } catch (err) {
    throw _.extend(new Error("Failed to complete OAuth handshake with Slack. " + err.message),
                   {response: err.response});
  }

  if (!response.data.ok) { // if the http response was a json object with an error attribute
    throw new Error("Failed to complete OAuth handshake with Slack. " + response.data.error);
  } else {
    return response.data;
  }
};

var getIdentity = function (accessToken) {
  try {
    var response = HTTP.get(
      "https://slack.com/api/auth.test",
      {params: {token: accessToken}});

    if (response.data && response.data.ok)
      return response.data;

    response = HTTP.get(
      "https://slack.com/api/users.identity",
      {params: {token: accessToken}});

    if (response.data && response.data.ok)
      // Simulate the response that auth.test would have returned
      return _.extend(response.data.user, {
        user: response.data.user.name,
        user_id: response.data.user.id,
        team_id: response.data.team.id,
        team: response.data.team.name,
        url: response.data.url
      });
    else
      throw new Error("Could not retrieve user identity");
  } catch (err) {
    throw _.extend(new Error("Failed to fetch identity from Slack. " + err.message),
                   {response: err.response});
  }
};

Slack.retrieveCredential = function(credentialToken, credentialSecret) {
  return OAuth.retrieveCredential(credentialToken, credentialSecret);
};
<|endoftext|>


<commit_before>let tiger;
let tigerImg;
let obstacleImg1;
let obstacleImg2;
let backgroundImg;
let obstacles = [];
let startGame = false
let landingImg;
let obstacleCounter = 0
let score = 0
function preload() {
  const options = {
    probabilityThreshold: 0.95
  };
  tigerImg = loadImage('tiger.png');
  obstacleImg1 = loadImage('obstacle1.gif');
  obstacleImg2 = loadImage('obstacle2.png');
  backgroundImg = loadImage('road.gif');
  landingImg =  loadImage("home.jpeg");
}

function mousePressed() {
  obstacles.push(new SpeedBreaker());
}

function setup() {
  createCanvas(windowWidth, windowHeight);
  tiger = new Tiger();
}

function gotCommand(error, results) {
  if (error) {
    console.error(error);
  }
  if (results[0].label == 'up') {
    tiger.jump();
  }
}

function keyPressed() {
  if(startGame === false)
    startGame = true;
  else{
    if (key == ' ') {
        tiger.jump();
      }
  }
}

function draw() {
  score =score + 1;
  document.getElementById("score").innerHTML= "SCORE: " + score;
  if(startGame){
    if (random(1) < 0.005) {
      obstacles.push(new SpeedBreaker());
    }

    background(backgroundImg);
    for (let t of obstacles) {
      t.move();
      t.show();
      if (tiger.hits(t)) {
        console.log('game over');
        noLoop();
        alert("Khel Katam! Tiger Mar Gaya!");
        location.reload();
      }
    }

    tiger.show();
    tiger.move();
  }
  else{
    background(landingImg);
  }
}
<commit_msg>Added score feature<commit_after>let tiger;
let tigerImg;
let obstacleImg1;
let obstacleImg2;
let backgroundImg;
let obstacles = [];
let startGame = false
let landingImg;
let obstacleCounter = 0
let score = 0
function preload() {
  const options = {
    probabilityThreshold: 0.95
  };
  tigerImg = loadImage('tiger.png');
  obstacleImg1 = loadImage('obstacle1.gif');
  obstacleImg2 = loadImage('obstacle2.png');
  backgroundImg = loadImage('road.gif');
  landingImg =  loadImage("home.jpeg");
}

function mousePressed() {
  obstacles.push(new SpeedBreaker());
}

function setup() {
  createCanvas(windowWidth, windowHeight);
  tiger = new Tiger();
}

function gotCommand(error, results) {
  if (error) {
    console.error(error);
  }
  if (results[0].label == 'up') {
    tiger.jump();
  }
}

function keyPressed() {
  if(startGame === false)
    startGame = true;
  else{
    if (key == ' ') {
        tiger.jump();
      }
  }
}

function draw() {

  if(startGame){
    if (random(1) < 0.005) {
      updateScore();
      obstacles.push(new SpeedBreaker());
    }

    background(backgroundImg);
    for (let t of obstacles) {
      t.move();
      t.show();
      if (tiger.hits(t)) {
        console.log('game over');
        noLoop();
        alert("Khel Katam! Tiger Mar Gaya!");
        location.reload();
      }
    }

    tiger.show();
    tiger.move();
  }
  else{
    background(landingImg);
  }
}

function updateScore(){
  score =score + 1;
  document.getElementById("score").innerHTML= "SCORE: " + score;
}<|endoftext|>


<commit_before>var CoreView = require('backbone/core-view');
var checkAndBuildOpts = require('../../../../../../helpers/required-opts');
var ScrollView = require('../../../../../scroll/scroll-view');
var AssetsCollection = require('../../../../../../data/assets-collection');
var UserAssetsListView = require('./user-assets-list-view');

var REQUIRED_OPTS = [
  'configModel',
  'userModel',
  'title',
  'selectedAsset'
];

module.exports = CoreView.extend({
  events: {
    'change .js-uploadInput': '_onFileSelected'
  },

  initialize: function (opts) {
    checkAndBuildOpts(opts, REQUIRED_OPTS, this);

    this._assetCollection = new AssetsCollection(
      null, {
        configModel: this._configModel,
        userModel: this._userModel
      }
    );

    this._fetchAllAssets();
  },

  render: function () {
    this.clearSubViews();
    return this;
  },

  _fetchAllAssets: function () {
    this._assetCollection.fetch({
      success: this._renderAssets.bind(this),
      error: this._onFetchAssetsError.bind(this)
    });
  },

  _renderAssets: function () {
    var view = new ScrollView({
      createContentView: function () {
        var view = new UserAssetsListView({
          title: this._title,
          model: this.model,
          assets: this._assetCollection,
          selectedAsset: this._selectedAsset
        });

        view.bind('init-upload', function () {
          this.trigger('init-upload');
        }, this);

        return view;
      }.bind(this)
    });

    this.addView(view);
    this.$el.append(view.render().el);
  },

  _onFetchAssetsError: function () {
    console.log('Error');
  }
});
<commit_msg>Triggers error<commit_after>var CoreView = require('backbone/core-view');
var checkAndBuildOpts = require('../../../../../../helpers/required-opts');
var ScrollView = require('../../../../../scroll/scroll-view');
var AssetsCollection = require('../../../../../../data/assets-collection');
var UserAssetsListView = require('./user-assets-list-view');

var REQUIRED_OPTS = [
  'configModel',
  'userModel',
  'title',
  'selectedAsset'
];

module.exports = CoreView.extend({
  events: {
    'change .js-uploadInput': '_onFileSelected'
  },

  initialize: function (opts) {
    checkAndBuildOpts(opts, REQUIRED_OPTS, this);

    this._assetCollection = new AssetsCollection(
      null, {
        configModel: this._configModel,
        userModel: this._userModel
      }
    );

    this._fetchAllAssets();
  },

  render: function () {
    this.clearSubViews();
    return this;
  },

  _fetchAllAssets: function () {
    this._assetCollection.fetch({
      success: this._renderAssets.bind(this),
      error: this._onFetchAssetsError.bind(this)
    });
  },

  _renderAssets: function () {
    var view = new ScrollView({
      createContentView: function () {
        var view = new UserAssetsListView({
          title: this._title,
          model: this.model,
          assetsCollection: this._assetCollection,
          selectedAsset: this._selectedAsset
        });

        view.bind('init-upload', function () {
          this.trigger('init-upload');
        }, this);

        return view;
      }.bind(this)
    });

    this.addView(view);
    this.$el.append(view.render().el);
  },

  _onFetchAssetsError: function (model, response) {
    this.trigger('error', response);
  }
});
<|endoftext|>


<commit_before>import React from 'react';
import {shallow} from 'enzyme';
import sinon from 'sinon';
import assert from 'assert';

import MouseMoveActionLayer from '../MouseMoveActionLayer';

describe('MouseMoveActionLayer', () => {
  const CANVAS_WIDTH = 40;
  const CANVAS_HEIGHT = 30;
  const CANVAS_START_POSITION = {x: 200, y: 200};
  const canvas = document.createElement('canvas');
  const ctx = canvas.getContext('2d');
  const imageData = ctx.createImageData(CANVAS_WIDTH, CANVAS_HEIGHT);
  const LINE_WIDTH = 6;
  const LINE_CAP = 'round';
  const setting = {
    ctx: {
      lineWidth: LINE_WIDTH,
      lineCap: LINE_CAP,
    },
  };
  const DISPLAY_WIDTH = 40;
  const DISPLAY_HEIGHT = 30;
  const DISPLAY_MAGNIFICATION_PERCENT = 100;
  const display = {
    width: DISPLAY_WIDTH,
    height: DISPLAY_HEIGHT,
    magnificationPercent: DISPLAY_MAGNIFICATION_PERCENT,
  };
  let wrapper;
  let calledFunc;
  let executeActionReceivedArg;
  let inst;
  beforeEach(() => {
    calledFunc = null;
    executeActionReceivedArg = null;
    wrapper = shallow(
      <MouseMoveActionLayer
        callbackDidMount={() => {
          calledFunc = 'callbackDidMount';
        }}
        callbackDidUpdate={() => {
          calledFunc = 'callbackDidUpdate';
        }}
        executeAction={receivedArg => {
          calledFunc = 'executeAction';
          executeActionReceivedArg = receivedArg;
        }}
        imageData={imageData}
        setting={setting}
        display={display}
      />,
      {disableLifecycleMethods: true}
    );
    inst = wrapper.instance();
    inst.canvas = document.createElement('canvas');
    inst.ctx = document.createElement('canvas').getContext('2d');
    inst.canvasStartPosition = CANVAS_START_POSITION;
  });
  it('imageDataで渡されたサイズのCanvasが描画される', () => {
    inst.canvas = document.createElement('canvas');
    inst.componentDidMount();
    assert(inst.canvas.width === CANVAS_WIDTH);
    assert(inst.canvas.height === CANVAS_HEIGHT);
  });
  it('マウスイベントによって state.isAction が適切に切り替わる', () => {
    assert(wrapper.state('isAction') === false);
    wrapper.find('canvas').simulate('mouseDown', {pageX: 0, pageY: 0});
    assert(wrapper.state('isAction') === true);
    wrapper.find('canvas').simulate('mouseUp');
    assert(wrapper.state('isAction') === false);
  });
  it('componentDidMount すると props.callbackDidMount が実行される', () => {
    assert(calledFunc === null);
    inst.componentDidMount();
    assert(calledFunc === 'callbackDidMount');
  });
  it('componentDidMount すると ctx に props.setting で渡された内容が反映される', () => {
    assert(inst.ctx.lineWidth === 1);
    assert(inst.ctx.lineCap === 'butt');
    inst.componentDidMount();
    assert(inst.ctx.lineWidth === LINE_WIDTH);
    assert(inst.ctx.lineCap === LINE_CAP);
  });
  it('componentDidUpdate すると props.callbackDidUpdate と this.loadContextSetting が実行される', () => {
    const spy = sinon.spy(inst, 'loadContextSetting');
    assert(calledFunc === null);
    assert(spy.callCount === 0);
    inst.componentDidUpdate();
    assert(calledFunc === 'callbackDidUpdate');
    assert(spy.callCount === 1);
    spy.restore();
  });
  it('getCurrentPoint で、押下したポイントを取得できる', () => {
    const result = inst.getCurrentPoint(100, 105);
    assert(result.x === 100 - CANVAS_START_POSITION.x);
    assert(result.y === 105 - CANVAS_START_POSITION.y);
  });
  it('mouseDown の後に mouseMove すると props.executeAction が実行される', () => {
    assert(calledFunc === null);
    wrapper.find('canvas').simulate('mouseDown', {pageX: 0, pageY: 0});
    wrapper.find('canvas').simulate('mouseMove', {pageX: 0, pageY: 0});
    assert(calledFunc === 'executeAction');
  });
  it('executeAction に、正しくポイントが渡される', () => {
    assert(executeActionReceivedArg === null);
    wrapper.find('canvas').simulate('mouseDown', {pageX: 100, pageY: 60});
    wrapper.find('canvas').simulate('mouseMove', {pageX: 110, pageY: 70});
    const {x, y} = CANVAS_START_POSITION;
    assert(executeActionReceivedArg.startPoint.x === 100 - x);
    assert(executeActionReceivedArg.startPoint.y === 60 - y);
    assert(executeActionReceivedArg.currentPoint.x === 110 - x);
    assert(executeActionReceivedArg.currentPoint.y === 70 - y);
  });
  it('switchCurrentPointToStartPoint で受け取った値が state.startPoint になる', () => {
    assert(wrapper.state('startPoint').x === 0);
    assert(wrapper.state('startPoint').y === 0);
    inst.switchCurrentPointToStartPoint({x: 33, y: 44});
    assert(wrapper.state('startPoint').x === 33);
    assert(wrapper.state('startPoint').y === 44);
  });
  it('mouseDown の後に mouseMove すると switchCurrentPointToStartPoint が呼び出される', () => {
    const spy = sinon.spy(inst, 'switchCurrentPointToStartPoint');
    assert(spy.callCount === 0);
    wrapper.find('canvas').simulate('mouseDown', {pageX: 0, pageY: 0});
    assert(spy.callCount === 0);
    wrapper.find('canvas').simulate('mouseMove', {pageX: 0, pageY: 0});
    assert(spy.callCount === 1);
    spy.restore();
  });
});
<commit_msg>MouseMoveActionLayer のテストを追加。<commit_after>import React from 'react';
import {shallow} from 'enzyme';
import sinon from 'sinon';
import assert from 'assert';

import MouseMoveActionLayer from '../MouseMoveActionLayer';

describe('MouseMoveActionLayer', () => {
  const CANVAS_WIDTH = 40;
  const CANVAS_HEIGHT = 30;
  const CANVAS_START_POSITION = {x: 200, y: 200};
  const canvas = document.createElement('canvas');
  const ctx = canvas.getContext('2d');
  const imageData = ctx.createImageData(CANVAS_WIDTH, CANVAS_HEIGHT);
  const LINE_WIDTH = 6;
  const LINE_CAP = 'round';
  const setting = {
    ctx: {
      lineWidth: LINE_WIDTH,
      lineCap: LINE_CAP,
    },
  };
  const DISPLAY_WIDTH = 40;
  const DISPLAY_HEIGHT = 30;
  const DISPLAY_MAGNIFICATION_PERCENT = 100;
  const display = {
    width: DISPLAY_WIDTH,
    height: DISPLAY_HEIGHT,
    magnificationPercent: DISPLAY_MAGNIFICATION_PERCENT,
  };
  let wrapper;
  let calledFunc;
  let executeActionReceivedArg;
  let inst;
  beforeEach(() => {
    calledFunc = null;
    executeActionReceivedArg = null;
    wrapper = shallow(
      <MouseMoveActionLayer
        callbackDidMount={() => {
          calledFunc = 'callbackDidMount';
        }}
        callbackDidUpdate={() => {
          calledFunc = 'callbackDidUpdate';
        }}
        executeAction={receivedArg => {
          calledFunc = 'executeAction';
          executeActionReceivedArg = receivedArg;
        }}
        imageData={imageData}
        setting={setting}
        display={display}
      />,
      {disableLifecycleMethods: true}
    );
    inst = wrapper.instance();
    inst.canvas = document.createElement('canvas');
    inst.ctx = document.createElement('canvas').getContext('2d');
    inst.canvasStartPosition = CANVAS_START_POSITION;
  });
  it('imageDataで渡されたサイズのCanvasが描画される', () => {
    inst.canvas = document.createElement('canvas');
    inst.componentDidMount();
    assert(inst.canvas.width === CANVAS_WIDTH);
    assert(inst.canvas.height === CANVAS_HEIGHT);
  });
  it('マウスイベントによって state.isAction が適切に切り替わる', () => {
    assert(wrapper.state('isAction') === false);
    wrapper.find('canvas').simulate('mouseDown', {pageX: 0, pageY: 0});
    assert(wrapper.state('isAction') === true);
    wrapper.find('canvas').simulate('mouseUp');
    assert(wrapper.state('isAction') === false);
  });
  it('ディスプレイの範囲外を押下しても、state.isAction は切り替わらない', () => {
    const {x, y} = CANVAS_START_POSITION;
    assert(wrapper.state('isAction') === false);
    wrapper.find('canvas').simulate('mouseDown', {
      pageX: x + DISPLAY_WIDTH + 1,
      pageY: y + DISPLAY_HEIGHT,
    });
    assert(wrapper.state('isAction') === false);
    wrapper.find('canvas').simulate('mouseDown', {
      pageX: x + DISPLAY_WIDTH,
      pageY: y + DISPLAY_HEIGHT,
    });
    assert(wrapper.state('isAction') === true);
  });
  it('componentDidMount すると props.callbackDidMount が実行される', () => {
    assert(calledFunc === null);
    inst.componentDidMount();
    assert(calledFunc === 'callbackDidMount');
  });
  it('componentDidMount すると ctx に props.setting で渡された内容が反映される', () => {
    assert(inst.ctx.lineWidth === 1);
    assert(inst.ctx.lineCap === 'butt');
    inst.componentDidMount();
    assert(inst.ctx.lineWidth === LINE_WIDTH);
    assert(inst.ctx.lineCap === LINE_CAP);
  });
  it('componentDidUpdate すると props.callbackDidUpdate と this.loadContextSetting が実行される', () => {
    const spy = sinon.spy(inst, 'loadContextSetting');
    assert(calledFunc === null);
    assert(spy.callCount === 0);
    inst.componentDidUpdate();
    assert(calledFunc === 'callbackDidUpdate');
    assert(spy.callCount === 1);
    spy.restore();
  });
  it('getCurrentPoint で、押下したポイントを取得できる', () => {
    const result = inst.getCurrentPoint(100, 105);
    assert(result.x === 100 - CANVAS_START_POSITION.x);
    assert(result.y === 105 - CANVAS_START_POSITION.y);
  });
  it('mouseDown の後に mouseMove すると props.executeAction が実行される', () => {
    assert(calledFunc === null);
    wrapper.find('canvas').simulate('mouseDown', {pageX: 0, pageY: 0});
    wrapper.find('canvas').simulate('mouseMove', {pageX: 0, pageY: 0});
    assert(calledFunc === 'executeAction');
  });
  it('executeAction に、正しくポイントが渡される', () => {
    assert(executeActionReceivedArg === null);
    wrapper.find('canvas').simulate('mouseDown', {pageX: 100, pageY: 60});
    wrapper.find('canvas').simulate('mouseMove', {pageX: 110, pageY: 70});
    const {x, y} = CANVAS_START_POSITION;
    assert(executeActionReceivedArg.startPoint.x === 100 - x);
    assert(executeActionReceivedArg.startPoint.y === 60 - y);
    assert(executeActionReceivedArg.currentPoint.x === 110 - x);
    assert(executeActionReceivedArg.currentPoint.y === 70 - y);
  });
  it('switchCurrentPointToStartPoint で受け取った値が state.startPoint になる', () => {
    assert(wrapper.state('startPoint').x === 0);
    assert(wrapper.state('startPoint').y === 0);
    inst.switchCurrentPointToStartPoint({x: 33, y: 44});
    assert(wrapper.state('startPoint').x === 33);
    assert(wrapper.state('startPoint').y === 44);
  });
  it('mouseDown の後に mouseMove すると switchCurrentPointToStartPoint が呼び出される', () => {
    const spy = sinon.spy(inst, 'switchCurrentPointToStartPoint');
    assert(spy.callCount === 0);
    wrapper.find('canvas').simulate('mouseDown', {pageX: 0, pageY: 0});
    assert(spy.callCount === 0);
    wrapper.find('canvas').simulate('mouseMove', {pageX: 0, pageY: 0});
    assert(spy.callCount === 1);
    spy.restore();
  });
});
<|endoftext|>


<commit_before>var app = getApp()
Page({
  data: {
    totalprice: 0,
    orderno: null,
    currentpage: 0,
    orderList: []
  },

  onLoad: function (info) {
    console.log('onLoad')
    console.log(info)
    var that = this

    wx.request({
      url: app.globalData.serverHost + '/api/user/orderquery',
      data: {
                openid : app.globalData.userOpenID,
                token : app.globalData.session_key,
                pageno : that.data.currentpage,
                pagesize : 10
              },
      method: 'POST', // OPTIONS, GET, HEAD, POST, PUT, DELETE, TRACE, CONNECT
      // header: {}, // 设置请求的 header
      success: function(res) {
        // success
        console.log(res)
        that.setData({
          orderList : res.data.orderlist
        })
      },
      fail: function() {
        // fail
      },
      complete: function() {
        // complete
      }
    })

    this.setData({
      totalprice: info.totalprice,
      orderno: info.orderno
    })
  }

})<commit_msg>parse string detail to json<commit_after>var app = getApp()
Page({
  data: {
    totalprice: 0,
    orderno: null,
    currentpage: 1,
    orderList: []
  },

  onLoad: function (info) {
    console.log('onLoad')
    console.log(info)
    var that = this

    wx.request({
      url: app.globalData.serverHost + '/api/user/orderquery',
      data: {
                openid : app.globalData.userOpenID,
                token : app.globalData.session_key,
                pageno : that.data.currentpage,
                pagesize : 10,
                date: '20170415'
              },
      method: 'POST', // OPTIONS, GET, HEAD, POST, PUT, DELETE, TRACE, CONNECT
      // header: {}, // 设置请求的 header
      success: function(res) {
        // success
        console.log(res)
        var orderList = res.data.orderlist || [];
        for(var i = 0, len = orderList.length; i < len; i++) {
          if(typeof orderList[i].detail === 'string') {
            orderList[i].detail = JSON.parse(orderList[i].detail);
          }
          console.log(orderList[i].detail)
        }
        that.setData({
          orderList : orderList
        })
      },
      fail: function() {
        // fail
      },
      complete: function() {
        // complete
      }
    })

    this.setData({
      totalprice: info.totalprice,
      orderno: info.orderno
    })
  }

})<|endoftext|>


<commit_before>import { expect } from 'chai';

import Sheet from 'Src/sheet';

import sheet1x1 from 'Test/fixtures/sheet-1x1';

describe('Sheet', () => {
  let sheet;

  it('should have data property', () => {
    sheet = new Sheet(sheet1x1);
    expect(sheet).to.have.property('data');
  });

  it('should have name property', () => {
    sheet = new Sheet(sheet1x1);
    expect(sheet).to.have.property('name');
  });

  it('should set data property on initialization', () => {
    sheet = new Sheet(sheet1x1);
    expect(sheet.data).to.equal(sheet1x1);
  });

  it('should throw an Error if data property was not given to constructor', () => {
    expect(() => new Sheet()).to.throw(Error);
  });
});
<commit_msg>Add name initialization test case<commit_after>import { expect } from 'chai';

import Sheet from 'Src/sheet';

import sheet1x1 from 'Test/fixtures/sheet-1x1';

describe('Sheet', () => {
  let sheet;

  it('should have data property', () => {
    sheet = new Sheet(sheet1x1);
    expect(sheet).to.have.property('data');
  });

  it('should have name property', () => {
    sheet = new Sheet(sheet1x1);
    expect(sheet).to.have.property('name');
  });

  it('should set data property on initialization', () => {
    sheet = new Sheet(sheet1x1);
    expect(sheet.data).to.equal(sheet1x1);
  });

  it('should set name property on initialization', () => {
    const name = 'defaultName';
    sheet = new Sheet(sheet1x1, name);
    expect(sheet.name).to.equal(name);
  });

  it('should throw an Error if data property was not given to constructor', () => {
    expect(() => new Sheet()).to.throw(Error);
  });
});
<|endoftext|>


<commit_before>var derby = require('derby')
  , app = derby.createApp(module)
  , get = app.get
  , view = app.view
  , ready = app.ready
  , start = +new Date()

derby.use(require('../../ui'))

//Example query motif to get the last time a bin was emptied
//THIS ISN'T A WORKING EXAMPLE AT THIS POINT. JUST ILLUSTRATING HOW WE MIGHT BUILD OUR QUERIES

/*store.query.expose('list-floor', 'lastEmptied', function (bin) { //Expose query syntax: .expose(namespace, motifName, fn)
	return this
		.where('binID').equals(bin) //Get only the bin you're interested in
		.sort('emptyDates','desc') //Sort the results in descending order by the dates it was emptied
		.limit(1); //Only get the last time it was emptied
});*/

//We could now call this query in the app by doing something like this:
/*var lastEmptied = model.query('list-floor').lastEmptied(1234);*/

// ROUTES //

// Derby routes can be rendered on the client and the server
get('/', function(page, model, params) {

  page.render('home', {page_name: 'Get Started'})
})

// A route for the building select view
get('/buildings', function(page, model, params) {
    page.render('list-building', { bins: bins, page_name: 'Buildings'} );
})

// A route for the floors/locations in a building
get('/buildings-:building?', function(page, model, params) {
    var building = params.building;
    building || (building = 'null');

    var buildingBins = null;
    for (build in bins){
        if (bins[build]['title']==building) {
            buildingBins = bins[build];
        }
    }

    page.render('list-floor',
        { building: buildingBins,
            page_name: 'Locations for '+buildingBins['title']} );
})

// View the bins at a location
get('/buildings-:building?/floor-:floor?/location-:loc?',
        function(page, model, params) {
    var buildName = params.building;
    buildName || (buildName = 'null');

    var floorName = params.floor;
    floorName || (floorName = 'null');

    var locName = params.loc;
    locName || (locName = 'null');

    var loc = null;
    for (build in bins){
        // for every building
        if (bins[build]['title']==buildName) {
            for (fl in bins[build]['floors']) {
                // for every floor
                if (bins[build]['floors'][fl]['title'] == floorName) {
                    for(ll in bins[build]['floors'][fl]['locations']) {
                        // for every location
                        if(bins[build]['floors'][fl]['locations'][ll]['title']
                            == locName) {
                            loc = bins[build]['floors'][fl]['locations'][ll];
                            break;
                        }
                    }
                }
            }
        }
    }

    page.render('list-bins',
        { building : buildName, floor : floorName, locBins: loc,
            page_name: 'bins for '+buildName+' in '+floorName+' at '+
            loc['title']});

  // Subscribes the model to any updates on this room's object.
//  model.subscribe('rooms.' + roomName, function(err, room) {
//    model.ref('_room', room)
//
//    // setNull will set a value if the object is currently null or undefined
//    room.setNull('welcome', 'Welcome to ' + roomName + '!')
//
//    room.incr('visits')
//
//    // This value is set for when the page initially renders
//    model.set('_timer', '0.0')
//    // Reset the counter when visiting a new route client-side
//    start = +new Date()
//
//    // Render will use the model data as well as an optional context object
//    page.render({
//      bins: bins
//    , roomName: roomName
//    , randomUrl: parseInt(Math.random() * 1e9).toString(36)
//    })
//  })

})

// CONTROLLER FUNCTIONS //

ready(function(model) {

    // EXAMPLES FROM OLD CODE
//  var timer
//
//  // Functions on the app can be bound to DOM events using the "x-bind"
//  // attribute in a template.
//  this.stop = function() {
//    // Any path name that starts with an underscore is private to the current
//    // client. Nothing set under a private path is synced back to the server.
//    model.set('_stopped', true)
//    clearInterval(timer)
//  }
//
//  this.start = function() {
//    model.set('_stopped', false)
//    timer = setInterval(function() {
//      model.set('_timer', (((+new Date()) - start) / 1000).toFixed(1))
//    }, 100)
//  }
//  this.start()
//
})

// LOGIC CODE //
bins = [{'title': 'WSC',
                floors: [{'title':'Basement', locations:[
                            {'title':'Shipping-Receiving', bins:[
                                'Toter','Glass','Cardboard']},
                            {'title':'Mail Room', bins:[
                                'Toter', 'Cardboard']},
                            {'title':'Cellar', bins:[
                                'Toter 1', 'Toter 2']}]},
                         {'title':'1st Floor', locations:[
                             {'title':'Diversions', bins:[
                                 'Toter']}]},
                         {'title':'2nd Floor', locations:[
                             {'title':'Elevator', bins:[
                                 'Toter', 'Glass']},
                             {'title':'ASUPS', bins:[
                                 'Toter']}]}]},
        {'title': 'Jones',
                  floors: [{'title':'Basement', locations:[
                              {'title':'Recycling Station', bins:[
                                  'Toter 1', 'Toter 2', 'Toter 3',
                                  'Toter 4', 'Cardboard', 'Glass', ]}]},
                           {'title':'1st Floor', locations:[
                               {'title':'Staff Kitchennette', bins:[
                                   'Glass']}]},
                           {'title':'2nd Floor', locations:[
                               {'title':'Hallway-North', bins:[
                                   'Toter 1', 'Toter 2']},
                               {'title':'Hallway-South', bins:[
                                   'Toter 1', 'Glass']}]}]}
]
<commit_msg>Added a nifty change to get to Mongo crashing on adding bins.<commit_after>var derby = require('derby')
  , app = derby.createApp(module)
  , get = app.get
  , view = app.view
  , ready = app.ready
  , start = +new Date()

derby.use(require('../../ui'))

//Example query motif to get the last time a bin was emptied
//THIS ISN'T A WORKING EXAMPLE AT THIS POINT. JUST ILLUSTRATING HOW WE MIGHT BUILD OUR QUERIES

/*store.query.expose('list-floor', 'lastEmptied', function (bin) { //Expose query syntax: .expose(namespace, motifName, fn)
	return this
		.where('binID').equals(bin) //Get only the bin you're interested in
		.sort('emptyDates','desc') //Sort the results in descending order by the dates it was emptied
		.limit(1); //Only get the last time it was emptied
});*/

//We could now call this query in the app by doing something like this:
/*var lastEmptied = model.query('list-floor').lastEmptied(1234);*/

// ROUTES //

// Derby routes can be rendered on the client and the server
get('/', function(page, model, params) {

  page.render('home', {page_name: 'Get Started'})
})

// A route for the building select view
get('/buildings', function(page, model, params) {
    page.render('list-building', { bins: bins, page_name: 'Buildings'} );
})

// A route for the floors/locations in a building
get('/buildings-:building?', function(page, model, params) {
    var building = params.building;
    building || (building = 'null');

    var buildingBins = null;
    for (build in bins){
        if (bins[build]['title']==building) {
            buildingBins = bins[build];
        }
    }

    page.render('list-floor',
        { building: buildingBins,
            page_name: 'Locations for '+buildingBins['title']} );
})

// View the bins at a location
get('/buildings-:building?/floor-:floor?/location-:loc?',
        function(page, model, params) {
    var buildName = params.building;
    buildName || (buildName = 'null');

    var floorName = params.floor;
    floorName || (floorName = 'null');

    var locName = params.loc;
    locName || (locName = 'null');

    var loc = null;
    for (build in bins){
        // for every building
        if (bins[build]['title']==buildName) {
            for (fl in bins[build]['floors']) {
                // for every floor
                if (bins[build]['floors'][fl]['title'] == floorName) {
                    for(ll in bins[build]['floors'][fl]['locations']) {
                        // for every location
                        if(bins[build]['floors'][fl]['locations'][ll]['title']
                            == locName) {
                            loc = bins[build]['floors'][fl]['locations'][ll];
                            break;
                        }
                    }
                }
            }
        }
    }

	model.subscribe('bins.' + buildName + '.' + floorName + '.'
                    + loc["title"], function(err, curLoc){
		model.ref('_bins', curLoc);
		var activityArr = [];
		loc['bins'].forEach(function(){
			var binName = this;
			var curTime = new Date();
			var binObj = {'bName':binName,
                          'activity':[{'time':curTime, 'activity': 'not-full'}]};
			activityArr.unshift(binObj);
		});

		curLoc.setNull('bins', activityArr);
        console.log("HEYYYYYYYYYYYYYYYYYYYYYYY!");
		page.render('list-bins',
                    { building : buildName,
                      floor : floorName,
                      locBins: loc,
                      page_name: 'bins for '+buildName+' in '+floorName+' at '+
                        loc['title']});
	});

  // Subscribes the model to any updates on this room's object.
//  model.subscribe('rooms.' + roomName, function(err, room) {
//    model.ref('_room', room)
//
//    // setNull will set a value if the object is currently null or undefined
//    room.setNull('welcome', 'Welcome to ' + roomName + '!')
//
//    room.incr('visits')
//
//    // This value is set for when the page initially renders
//    model.set('_timer', '0.0')
//    // Reset the counter when visiting a new route client-side
//    start = +new Date()
//
//    // Render will use the model data as well as an optional context object
//    page.render({
//      bins: bins
//    , roomName: roomName
//    , randomUrl: parseInt(Math.random() * 1e9).toString(36)
//    })
//  })

})

// CONTROLLER FUNCTIONS //

ready(function(model) {

    // EXAMPLES FROM OLD CODE
//  var timer
//
//  // Functions on the app can be bound to DOM events using the "x-bind"
//  // attribute in a template.
//  this.stop = function() {
//    // Any path name that starts with an underscore is private to the current
//    // client. Nothing set under a private path is synced back to the server.
//    model.set('_stopped', true)
//    clearInterval(timer)
//  }
//
//  this.start = function() {
//    model.set('_stopped', false)
//    timer = setInterval(function() {
//      model.set('_timer', (((+new Date()) - start) / 1000).toFixed(1))
//    }, 100)
//  }
//  this.start()
//
})

// LOGIC CODE //
bins = [{'title': 'WSC',
                floors: [{'title':'Basement', locations:[
                            {'title':'Shipping-Receiving', bins:[
                                'Toter','Glass','Cardboard']},
                            {'title':'Mail Room', bins:[
                                'Toter', 'Cardboard']},
                            {'title':'Cellar', bins:[
                                'Toter 1', 'Toter 2']}]},
                         {'title':'1st Floor', locations:[
                             {'title':'Diversions', bins:[
                                 'Toter']}]},
                         {'title':'2nd Floor', locations:[
                             {'title':'Elevator', bins:[
                                 'Toter', 'Glass']},
                             {'title':'ASUPS', bins:[
                                 'Toter']}]}]},
        {'title': 'Jones',
                  floors: [{'title':'Basement', locations:[
                              {'title':'Recycling Station', bins:[
                                  'Toter 1', 'Toter 2', 'Toter 3',
                                  'Toter 4', 'Cardboard', 'Glass', ]}]},
                           {'title':'1st Floor', locations:[
                               {'title':'Staff Kitchennette', bins:[
                                   'Glass']}]},
                           {'title':'2nd Floor', locations:[
                               {'title':'Hallway-North', bins:[
                                   'Toter 1', 'Toter 2']},
                               {'title':'Hallway-South', bins:[
                                   'Toter 1', 'Glass']}]}]}
]
<|endoftext|>


<commit_before>'use strict';

const apiai = require('apiai');
const express = require('express');
const bodyParser = require('body-parser');
const uuid = require('node-uuid');
const request = require('request');
const JSONbig = require('json-bigint');
const async = require('async');

const REST_PORT = (process.env.PORT || 5000);
const APIAI_ACCESS_TOKEN = process.env.APIAI_ACCESS_TOKEN;
const APIAI_LANG = process.env.APIAI_LANG || 'nl';
const FB_VERIFY_TOKEN = process.env.FB_VERIFY_TOKEN;
const FB_PAGE_ACCESS_TOKEN = process.env.FB_PAGE_ACCESS_TOKEN;

const apiAiService = apiai(APIAI_ACCESS_TOKEN, {language: APIAI_LANG, requestSource: "fb"});
const sessionIds = new Map();

const DEFAULT_INTENTS = ['57b82498-053c-4776-8be9-228c420e6c13', 'b429ecdc-21f4-4a07-8165-3620023185ba'];
const DEFAULT_INTENT_REFER_TO = '1648152645194926';

function processEvent(event) {
    var sender = event.sender.id.toString();

    if ((event.message && event.message.text) || (event.postback && event.postback.payload)) {
        var text = event.message ? event.message.text : event.postback.payload;
        // Handle a text message from this sender

        if (!sessionIds.has(sender)) {
            sessionIds.set(sender, uuid.v1());
        }

        console.log("proces event: ", text);
        //send message to api.ai
        let apiaiRequest = apiAiService.textRequest(text,
            {
                sessionId: sessionIds.get(sender)
            });
        //receive message from api.ai
        apiaiRequest.on('response', (response) => {
            if (isDefined(response.result)) {
                let responseText = response.result.fulfillment.speech;
                let responseData = response.result.fulfillment.data;
                let action = response.result.action; //actie in intent
                let intent = response.result.metadata.intentId;

                if (isDefined(responseData) && isDefined(responseData.facebook)) {
                    if (!Array.isArray(responseData.facebook)) {
                        try {
                            console.log('Response as formatted message');
                            sendFBMessage(sender, responseData.facebook + ' geformatteerd bericht');
                        } catch (err) {
                            sendFBMessage(sender, {text: err.message});
                        }
                    } else {
                        responseData.facebook.forEach((facebookMessage) => {
                            try {
                                if (facebookMessage.sender_action) {
                                    console.log('Response as sender action');
                                    //sendFBMessage(sender, ' debug fb action: ' + sender_action);
                                    sendFBSenderAction(sender, facebookMessage.sender_action);
                                }
                                else {
                                    console.log('Response as formatted message');
                                    sendFBMessage(sender, facebookMessage + ' geformatteerd bericht 2');
                                }
                            } catch (err) {
                                sendFBMessage(sender, {text: err.message});
                            }
                        });
                    }
                //hier komen de standaard tekst antwoorden van api.ai terecht
                } else if (isDefined(responseText)) {
                    console.log('Response as text message');

                    console.log(responseData);
                    console.log(intent);
                    if(DEFAULT_INTENTS.includes(intent)){
                        getFBProfile(sender, (profile) => {
                            sendFBMessage(DEFAULT_INTENT_REFER_TO, 'Hallo, ik heb een vraag gekregen van ' + profile.first_name + ' ' + profile.last_name + ' die ik niet kan beantwoorden')
                        });
                    }

                    //achterhaal of er intelligentie nodig is
                    var speech ="";
                        switch(action) {
                        case "who_are_you": //check if user is known
                            speech += action;
                        break;
                        case "pam_sum": //calculate PAM score
                            speech += response.result.parameters.pam_score;
                            //hoe geef je waarde aan api.ai variabele?
                            //apiaiRequest.contexts.pam_sum.paramaters.pam_total += response.result.parameters.pam_score
                        break;
                        default:
                        speech += 'Sorry, de actie is niet bekend.';
                        }

                    // facebook API limit for text length is 320,
                    // so we must split message if needed
                    var splittedText = splitResponse(responseText);

                    async.eachSeries(splittedText, (textPart, callback) => {
                        //sendFBMessage(sender, {text: textPart + ' debug callback: ' + speech}, callback);
                        sendFBMessage(sender, {text: textPart}, callback);
                    });
                }

            }
        });
        apiaiRequest.on('error', (error) => console.error(error));
        apiaiRequest.end();
    }
}

function splitResponse(str) {
    if (str.length <= 320) {
        return [str];
    }

    return chunkString(str, 300);
}

function chunkString(s, len) {
    var curr = len, prev = 0;

    var output = [];

    while (s[curr]) {
        if (s[curr++] == ' ') {
            output.push(s.substring(prev, curr));
            prev = curr;
            curr += len;
        }
        else {
            var currReverse = curr;
            do {
                if (s.substring(currReverse - 1, currReverse) == ' ') {
                    output.push(s.substring(prev, currReverse));
                    prev = currReverse;
                    curr = currReverse + len;
                    break;
                }
                currReverse--;
            } while (currReverse > prev)
        }
    }
    output.push(s.substr(prev));
    return output;
}

function getFBProfile (facebookId, callback) {
    request({
        url: 'https://graph.facebook.com/v2.6/' + facebookId,
        qs: {access_token: FB_PAGE_ACCESS_TOKEN},
        method: 'GET'
    }, (error, response, body) => {
        if (error) {
            console.log('Error sending message: ', error);
        } else if (response.body.error) {
            console.log('Error: ', response.body.error);
        } else if (callback) {
            callback(JSON.parse(body));
        }
    });
}

function sendFBMessage(sender, messageData, callback) {
    request({
        url: 'https://graph.facebook.com/v2.6/me/messages',
        qs: {access_token: FB_PAGE_ACCESS_TOKEN},
        method: 'POST',
        json: {
            recipient: {id: sender},
            message: messageData
        }
    }, (error, response, body) => {
        if (error) {
            console.log('Error sending message: ', error);
        } else if (response.body.error) {
            console.log('Error: ', response.body.error);
        }

        if (callback) {
            callback();
        }
    });
}

function sendFBSenderAction(sender, action, callback) {
    setTimeout(() => {
        request({
            url: 'https://graph.facebook.com/v2.6/me/messages',
            qs: {access_token: FB_PAGE_ACCESS_TOKEN},
            method: 'POST',
            json: {
                recipient: {id: sender},
                sender_action: action
            }
        }, (error, response, body) => {
            if (error) {
                console.log('Error sending action: ', error);
            } else if (response.body.error) {
                console.log('Error: ', response.body.error);
            }
            if (callback) {
                callback();
            }
        });
    }, 1000);
}

function doSubscribeRequest() {
    request({
            method: 'POST',
            uri: "https://graph.facebook.com/v2.6/me/subscribed_apps?access_token=" + FB_PAGE_ACCESS_TOKEN
        },
        (error, response, body) => {
            if (error) {
                console.error('Error while subscription: ', error);
            } else {
                console.log('Subscription result: ', response.body);
            }
        });
}

function isDefined(obj) {
    if (typeof obj == 'undefined') {
        return false;
    }

    if (!obj) {
        return false;
    }

    return obj != null;
}

const app = express();
const frontofficeid = 1533050426761050;
app.use(bodyParser.text({type: 'application/json'})); //geen response als deze weggelaten wordt
app.use(bodyParser.urlencoded({extended: false})); //toegevoegd: heeft invloed verwerking event
app.use(bodyParser.json()); //toegevoegd: corrigeert de werking weer

var debugtekst = "";

// Server frontpage
app.get('/', function (req, res) {
        res.send('This is Paula');
        });

app.get('/webhook/', (req, res) => {
    if (req.query['hub.verify_token'] == FB_VERIFY_TOKEN) {
        res.send(req.query['hub.challenge']);

        setTimeout(() => {
            doSubscribeRequest();
        }, 5000);
    } else {
        res.send('Error, wrong validation token');
    }
});

//ontvangen van FB bericht
app.post('/webhook/', (req, res) => {
    try {
        var data = JSONbig.parse(req.body);

        if (data.entry) {
            let entries = data.entry;
            entries.forEach((entry) => {
                let messaging_events = entry.messaging;
                if (messaging_events) {
                    messaging_events.forEach((event) => {
                        if (event.message && !event.message.is_echo ||
                            event.postback && event.postback.payload) {
                            //sendFBMessage(event.sender.id, {text: "Debugtekst fb: " + debugtekst});
                            processEvent(event);
                            //sendFBMessage(event.sender.id, {text: "Jij bent: " + event.sender.id});
                        }
                    });
                }
            });
        }

        return res.status(200).json({
            status: "ok"
        });
    } catch (err) {
        return res.status(400).json({
            status: "error",
            error: err
        });
    }

});

//bewerking van api.ai vanuit webhook alvorens terug te sturen
//app.post('/herokuai', function (req1, res1) {
//         try {
//         var requestBody = req1.action;
//         debugtekst = "herokuai webhook: " + requestBody.action;
//            } catch (err) {
//                console.error("Can't process request", err);
//                debugtekst = "herokuai webhook err: " + err;
//         }
//});

app.listen(REST_PORT, () => {
    console.log('Rest service ready on port ' + REST_PORT);
});

doSubscribeRequest();
<commit_msg>Default intent referra<commit_after>'use strict';

const apiai = require('apiai');
const express = require('express');
const bodyParser = require('body-parser');
const uuid = require('node-uuid');
const request = require('request');
const JSONbig = require('json-bigint');
const async = require('async');

const REST_PORT = (process.env.PORT || 5000);
const APIAI_ACCESS_TOKEN = process.env.APIAI_ACCESS_TOKEN;
const APIAI_LANG = process.env.APIAI_LANG || 'nl';
const FB_VERIFY_TOKEN = process.env.FB_VERIFY_TOKEN;
const FB_PAGE_ACCESS_TOKEN = process.env.FB_PAGE_ACCESS_TOKEN;

const apiAiService = apiai(APIAI_ACCESS_TOKEN, {language: APIAI_LANG, requestSource: "fb"});
const sessionIds = new Map();

const DEFAULT_INTENTS = ['57b82498-053c-4776-8be9-228c420e6c13', 'b429ecdc-21f4-4a07-8165-3620023185ba'];
const DEFAULT_INTENT_REFER_TO = '1648152645194926';

function processEvent(event) {
    var sender = event.sender.id.toString();

    if ((event.message && event.message.text) || (event.postback && event.postback.payload)) {
        var text = event.message ? event.message.text : event.postback.payload;
        // Handle a text message from this sender

        if (!sessionIds.has(sender)) {
            sessionIds.set(sender, uuid.v1());
        }

        console.log("proces event: ", text);
        //send message to api.ai
        let apiaiRequest = apiAiService.textRequest(text,
            {
                sessionId: sessionIds.get(sender)
            });
        //receive message from api.ai
        apiaiRequest.on('response', (response) => {
            if (isDefined(response.result)) {
                let responseText = response.result.fulfillment.speech;
                let responseData = response.result.fulfillment.data;
                let action = response.result.action; //actie in intent
                let intent = response.result.metadata.intentId;

                if (isDefined(responseData) && isDefined(responseData.facebook)) {
                    if (!Array.isArray(responseData.facebook)) {
                        try {
                            console.log('Response as formatted message');
                            sendFBMessage(sender, responseData.facebook + ' geformatteerd bericht');
                        } catch (err) {
                            sendFBMessage(sender, {text: err.message});
                        }
                    } else {
                        responseData.facebook.forEach((facebookMessage) => {
                            try {
                                if (facebookMessage.sender_action) {
                                    console.log('Response as sender action');
                                    //sendFBMessage(sender, ' debug fb action: ' + sender_action);
                                    sendFBSenderAction(sender, facebookMessage.sender_action);
                                }
                                else {
                                    console.log('Response as formatted message');
                                    sendFBMessage(sender, facebookMessage + ' geformatteerd bericht 2');
                                }
                            } catch (err) {
                                sendFBMessage(sender, {text: err.message});
                            }
                        });
                    }
                //hier komen de standaard tekst antwoorden van api.ai terecht
                } else if (isDefined(responseText)) {
                    console.log('Response as text message');

                    console.log(responseData);
                    console.log(intent);
                    if(DEFAULT_INTENTS.includes(intent)){
                        getFBProfile(sender, (profile) => {
                            sendFBMessage(DEFAULT_INTENT_REFER_TO, {text:'Hallo, ik heb een vraag gekregen van ' + profile.first_name + ' ' + profile.last_name + ' die ik niet kan beantwoorden'})
                        });
                    }

                    //achterhaal of er intelligentie nodig is
                    var speech ="";
                        switch(action) {
                        case "who_are_you": //check if user is known
                            speech += action;
                        break;
                        case "pam_sum": //calculate PAM score
                            speech += response.result.parameters.pam_score;
                            //hoe geef je waarde aan api.ai variabele?
                            //apiaiRequest.contexts.pam_sum.paramaters.pam_total += response.result.parameters.pam_score
                        break;
                        default:
                        speech += 'Sorry, de actie is niet bekend.';
                        }

                    // facebook API limit for text length is 320,
                    // so we must split message if needed
                    var splittedText = splitResponse(responseText);

                    async.eachSeries(splittedText, (textPart, callback) => {
                        //sendFBMessage(sender, {text: textPart + ' debug callback: ' + speech}, callback);
                        sendFBMessage(sender, {text: textPart}, callback);
                    });
                }

            }
        });
        apiaiRequest.on('error', (error) => console.error(error));
        apiaiRequest.end();
    }
}

function splitResponse(str) {
    if (str.length <= 320) {
        return [str];
    }

    return chunkString(str, 300);
}

function chunkString(s, len) {
    var curr = len, prev = 0;

    var output = [];

    while (s[curr]) {
        if (s[curr++] == ' ') {
            output.push(s.substring(prev, curr));
            prev = curr;
            curr += len;
        }
        else {
            var currReverse = curr;
            do {
                if (s.substring(currReverse - 1, currReverse) == ' ') {
                    output.push(s.substring(prev, currReverse));
                    prev = currReverse;
                    curr = currReverse + len;
                    break;
                }
                currReverse--;
            } while (currReverse > prev)
        }
    }
    output.push(s.substr(prev));
    return output;
}

function getFBProfile (facebookId, callback) {
    request({
        url: 'https://graph.facebook.com/v2.6/' + facebookId,
        qs: {access_token: FB_PAGE_ACCESS_TOKEN},
        method: 'GET'
    }, (error, response, body) => {
        if (error) {
            console.log('Error sending message: ', error);
        } else if (response.body.error) {
            console.log('Error: ', response.body.error);
        } else if (callback) {
            callback(JSON.parse(body));
        }
    });
}

function sendFBMessage(sender, messageData, callback) {
    request({
        url: 'https://graph.facebook.com/v2.6/me/messages',
        qs: {access_token: FB_PAGE_ACCESS_TOKEN},
        method: 'POST',
        json: {
            recipient: {id: sender},
            message: messageData
        }
    }, (error, response, body) => {
        if (error) {
            console.log('Error sending message: ', error);
        } else if (response.body.error) {
            console.log('Error: ', response.body.error);
        }

        if (callback) {
            callback();
        }
    });
}

function sendFBSenderAction(sender, action, callback) {
    setTimeout(() => {
        request({
            url: 'https://graph.facebook.com/v2.6/me/messages',
            qs: {access_token: FB_PAGE_ACCESS_TOKEN},
            method: 'POST',
            json: {
                recipient: {id: sender},
                sender_action: action
            }
        }, (error, response, body) => {
            if (error) {
                console.log('Error sending action: ', error);
            } else if (response.body.error) {
                console.log('Error: ', response.body.error);
            }
            if (callback) {
                callback();
            }
        });
    }, 1000);
}

function doSubscribeRequest() {
    request({
            method: 'POST',
            uri: "https://graph.facebook.com/v2.6/me/subscribed_apps?access_token=" + FB_PAGE_ACCESS_TOKEN
        },
        (error, response, body) => {
            if (error) {
                console.error('Error while subscription: ', error);
            } else {
                console.log('Subscription result: ', response.body);
            }
        });
}

function isDefined(obj) {
    if (typeof obj == 'undefined') {
        return false;
    }

    if (!obj) {
        return false;
    }

    return obj != null;
}

const app = express();
const frontofficeid = 1533050426761050;
app.use(bodyParser.text({type: 'application/json'})); //geen response als deze weggelaten wordt
app.use(bodyParser.urlencoded({extended: false})); //toegevoegd: heeft invloed verwerking event
app.use(bodyParser.json()); //toegevoegd: corrigeert de werking weer

var debugtekst = "";

// Server frontpage
app.get('/', function (req, res) {
        res.send('This is Paula');
        });

app.get('/webhook/', (req, res) => {
    if (req.query['hub.verify_token'] == FB_VERIFY_TOKEN) {
        res.send(req.query['hub.challenge']);

        setTimeout(() => {
            doSubscribeRequest();
        }, 5000);
    } else {
        res.send('Error, wrong validation token');
    }
});

//ontvangen van FB bericht
app.post('/webhook/', (req, res) => {
    try {
        var data = JSONbig.parse(req.body);

        if (data.entry) {
            let entries = data.entry;
            entries.forEach((entry) => {
                let messaging_events = entry.messaging;
                if (messaging_events) {
                    messaging_events.forEach((event) => {
                        if (event.message && !event.message.is_echo ||
                            event.postback && event.postback.payload) {
                            //sendFBMessage(event.sender.id, {text: "Debugtekst fb: " + debugtekst});
                            processEvent(event);
                            //sendFBMessage(event.sender.id, {text: "Jij bent: " + event.sender.id});
                        }
                    });
                }
            });
        }

        return res.status(200).json({
            status: "ok"
        });
    } catch (err) {
        return res.status(400).json({
            status: "error",
            error: err
        });
    }

});

//bewerking van api.ai vanuit webhook alvorens terug te sturen
//app.post('/herokuai', function (req1, res1) {
//         try {
//         var requestBody = req1.action;
//         debugtekst = "herokuai webhook: " + requestBody.action;
//            } catch (err) {
//                console.error("Can't process request", err);
//                debugtekst = "herokuai webhook err: " + err;
//         }
//});

app.listen(REST_PORT, () => {
    console.log('Rest service ready on port ' + REST_PORT);
});

doSubscribeRequest();
<|endoftext|>