<commit_before>
    // Broadphase
    var dist = V.create();
    var rot = M.create();
    var worldNormal = V.create();
    var yAxis = V.create(0,1);
    function checkCircleCircle(c1,c2,result){
        Vsub(c1.position,c2.position,dist);
        var R1 = c1.shape.radius;
        var R2 = c2.shape.radius;
        if(Vnorm2(dist) < (R1+R2)*(R1+R2)){
            result.push(c1);
            result.push(c2);
        }
    }
    function checkCirclePlane(c,p,result){
        Vsub(c.position,p.position,dist);
        M.setFromRotation(rot,p.angle);
        M.vectorMultiply(rot,yAxis,worldNormal);
        if(Vdot(dist,worldNormal) <= c.shape.radius){
            result.push(c);
            result.push(p);
        }
    }
    function checkCircleParticle(c,p,result){
        result.push(c);
        result.push(p);
    }

    // Generate contacts / do nearphase
    function nearphaseCircleCircle(c1,c2,result,oldContacts){
        //var c = new p2.ContactEquation(c1,c2);
        var c = oldContacts.length ? oldContacts.pop() : new p2.ContactEquation(c1,c2);
        c.bi = c1;
        c.bj = c2;
        Vsub(c2.position,c1.position,c.ni);
        V.normalize(c.ni,c.ni);
        Vscale(c.ni, c1.shape.radius, c.ri);
        Vscale(c.ni,-c2.shape.radius, c.rj);
        result.push(c);
    }
    function nearphaseCircleParticle(c,p,result,oldContacts){
        // todo
    }
    var nearphaseCirclePlane_rot = M.create();
    var nearphaseCirclePlane_planeToCircle = V.create();
    var nearphaseCirclePlane_temp = V.create();
    function nearphaseCirclePlane(c,p,result,oldContacts){
        var rot = nearphaseCirclePlane_rot;
        var contact = oldContacts.length ? oldContacts.pop() : new p2.ContactEquation(p,c);
        contact.bi = p;
        contact.bj = c;
        var planeToCircle = nearphaseCirclePlane_planeToCircle;
        var temp = nearphaseCirclePlane_temp;

        M.setFromRotation(rot,p.angle);
        M.vectorMultiply(rot,yAxis,contact.ni);

        V.scale(contact.ni, -c.shape.radius, contact.rj);

        V.subtract(c.position,p.position,planeToCircle);
        var d = V.dot(contact.ni , planeToCircle );
        V.scale(contact.ni,d,temp);
        V.subtract(planeToCircle , temp , contact.ri );

        result.push(contact);
    }

    var step_r = V.create();
    var step_runit = V.create();
    var step_u = V.create();
    var step_f = V.create();
    var step_fhMinv = V.create();
    var step_velodt = V.create();
    function now(){
        if(performance.now) return performance.now();
        else if(performance.webkitNow) return performance.webkitNow();
        else new Date().getTime();
    }

    p2.Broadphase = function(){

    };
<commit_msg>Broadphase doc<commit_after>    // Broadphase
    var dist = V.create();
    var rot = M.create();
    var worldNormal = V.create();
    var yAxis = V.create(0,1);
    function checkCircleCircle(c1,c2,result){
        Vsub(c1.position,c2.position,dist);
        var R1 = c1.shape.radius;
        var R2 = c2.shape.radius;
        if(Vnorm2(dist) < (R1+R2)*(R1+R2)){
            result.push(c1);
            result.push(c2);
        }
    }
    function checkCirclePlane(c,p,result){
        Vsub(c.position,p.position,dist);
        M.setFromRotation(rot,p.angle);
        M.vectorMultiply(rot,yAxis,worldNormal);
        if(Vdot(dist,worldNormal) <= c.shape.radius){
            result.push(c);
            result.push(p);
        }
    }
    function checkCircleParticle(c,p,result){
        result.push(c);
        result.push(p);
    }

    // Generate contacts / do nearphase
    function nearphaseCircleCircle(c1,c2,result,oldContacts){
        //var c = new p2.ContactEquation(c1,c2);
        var c = oldContacts.length ? oldContacts.pop() : new p2.ContactEquation(c1,c2);
        c.bi = c1;
        c.bj = c2;
        Vsub(c2.position,c1.position,c.ni);
        V.normalize(c.ni,c.ni);
        Vscale(c.ni, c1.shape.radius, c.ri);
        Vscale(c.ni,-c2.shape.radius, c.rj);
        result.push(c);
    }
    function nearphaseCircleParticle(c,p,result,oldContacts){
        // todo
    }
    var nearphaseCirclePlane_rot = M.create();
    var nearphaseCirclePlane_planeToCircle = V.create();
    var nearphaseCirclePlane_temp = V.create();
    function nearphaseCirclePlane(c,p,result,oldContacts){
        var rot = nearphaseCirclePlane_rot;
        var contact = oldContacts.length ? oldContacts.pop() : new p2.ContactEquation(p,c);
        contact.bi = p;
        contact.bj = c;
        var planeToCircle = nearphaseCirclePlane_planeToCircle;
        var temp = nearphaseCirclePlane_temp;

        M.setFromRotation(rot,p.angle);
        M.vectorMultiply(rot,yAxis,contact.ni);

        V.scale(contact.ni, -c.shape.radius, contact.rj);

        V.subtract(c.position,p.position,planeToCircle);
        var d = V.dot(contact.ni , planeToCircle );
        V.scale(contact.ni,d,temp);
        V.subtract(planeToCircle , temp , contact.ri );

        result.push(contact);
    }

    var step_r = V.create();
    var step_runit = V.create();
    var step_u = V.create();
    var step_f = V.create();
    var step_fhMinv = V.create();
    var step_velodt = V.create();
    function now(){
        if(performance.now) return performance.now();
        else if(performance.webkitNow) return performance.webkitNow();
        else new Date().getTime();
    }

    /**
     * Base class for broadphase implementations.
     * @class
     */
    p2.Broadphase = function(){

    };
<|endoftext|>


<commit_before>/*
 * This program is part of the OpenLMIS logistics management information system platform software.
 * Copyright © 2013 VillageReach
 *
 * This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Affero General Public License for more details.
 * You should have received a copy of the GNU Affero General Public License along with this program.  If not, see http://www.gnu.org/licenses.  For additional information contact info@OpenLMIS.org.
 */

var services = angular.module('openlmis.services', ['ngResource']);
var update = {update: {method: 'PUT'}};

services.value('version', '@version@');

services.factory('Programs', function ($resource) {
  return $resource('/programs/:type.json', {type: '@type'}, {});
});

services.factory('RnRColumnList', function ($resource) {
  return $resource('/program/:programId/rnr-template.json', {}, {post: {isArray: true, method: 'POST'}});
});

services.factory('ProgramRnRColumnList', function ($resource) {
  return $resource('/rnr/:programId/columns.json', {}, {});
});

services.factory('Facility', function ($resource) {
  var resource = $resource('/facilities/:id.json', {id: '@id'}, update);

  resource.restore = function (pathParams, success, error) {
    $resource('/facilities/:id/restore.json', {}, update).update(pathParams, {}, success, error);
  };

  return resource;
});

services.factory('UserContext', function ($resource) {
  return $resource('/user-context.json', {}, {});
});

services.factory('Users', function ($resource) {
  var resource = $resource('/users/:id.json', {id: '@id'}, update);

  resource.disable = function (pathParams, success, error) {
    $resource('/users/:id.json', {}, {update: {method: 'DELETE'}}).update(pathParams, {}, success, error);
  };

  return resource;
});

services.factory('UserFacilityList', function ($resource) {
  return $resource('/user/facilities.json', {}, {});
});

services.factory('UserFacilityWithViewRequisition', function ($resource) {
  return $resource('/user/facilities/view.json', {}, {});
});

services.factory('ProgramsToViewRequisitions', function ($resource) {
  return $resource('/facility/:facilityId/view/requisition/programs.json', {}, {});
});

services.factory('ProgramSupportedByFacility', function ($resource) {
  return $resource('/facilities/:facilityId/programs.json', {}, {});
});

services.factory('FacilityReferenceData', function ($resource) {
  return $resource('/facilities/reference-data.json', {}, {});
});

services.factory('Rights', function ($resource) {
  return $resource('/rights.json', {}, {});
});

services.factory('Roles', function ($resource) {
  return $resource('/roles/:id.json', {id: '@id'}, update);
});

services.factory('CreateRequisitionProgramList', function ($resource) {
  return $resource('/create/requisition/programs.json', {}, {});
});

services.factory('UserSupervisedFacilitiesForProgram', function ($resource) {
  return $resource('/create/requisition/supervised/:programId/facilities.json', {}, {});
});

services.factory('ReferenceData', function ($resource) {
  return $resource('/reference-data/currency.json', {}, {});
});

services.factory('LineItemPageSize', function ($resource) {
  return $resource('/reference-data/lineitem/pagesize.json', {}, {});
});

services.factory('Requisitions', function ($resource) {
  return $resource('/requisitions/:id/:operation.json', {id: '@id', operation: '@operation'}, update);
});

services.factory('RequisitionForApproval', function ($resource) {
  return $resource('/requisitions-for-approval.json', {}, {});
});

services.factory('RequisitionsForViewing', function ($resource) {
  return $resource('/requisitions.json', {}, {});
});

services.factory('RequisitionForConvertToOrder', function ($resource) {
  return $resource('/requisitions-for-convert-to-order.json', {}, {});
});

services.factory('LossesAndAdjustmentsReferenceData', function ($resource) {
  return $resource('/requisitions/lossAndAdjustments/reference-data.json', {}, {});
});

services.factory('Schedule', function ($resource) {
  return $resource('/schedules/:id.json', {id: '@id'}, update);
});

services.factory('Periods', function ($resource) {
  return $resource('/schedules/:scheduleId/periods.json', {}, {});
});

services.factory('PeriodsForFacilityAndProgram', function ($resource) {
  return $resource('/logistics/periods.json', {}, {});
});

services.factory('Period', function ($resource) {
  return $resource('/periods/:id.json', {}, {});
});

services.factory('Program', function ($resource) {
  return $resource('/programs/:id.json', {id: '@id'}, {});
});

services.factory('SupportedUploads', function ($resource) {
  return $resource('/supported-uploads.json', {}, {});
});

services.factory('ForgotPassword', function ($resource) {
  return $resource('/forgot-password.json', {}, {});
});

services.factory('FacilityApprovedProducts', function ($resource) {
  return $resource('/facilityApprovedProducts/facility/:facilityId/program/:programId/nonFullSupply.json', {}, {});
});

services.factory('RequisitionLineItem', function ($resource) {
  return $resource('/logistics/requisition/lineItem.json', {}, {});
});

services.factory('UpdateUserPassword', function ($resource) {
  return $resource('/user/resetPassword/:token.json', {}, update);
});

services.factory('ValidatePasswordToken', function ($resource) {
  return $resource('/user/validatePasswordResetToken/:token.json', {}, {});
});

services.factory('Messages', function ($resource) {
  return $resource('/messages.json', {}, {});
});

services.factory('SupervisoryNodes', function ($resource) {
  return $resource('/supervisory-nodes.json', {}, {});
});

services.factory('FacilityProgramRights', function ($resource) {
  return $resource('/facility/:facilityId/program/:programId/rights.json');
});

services.factory('RequisitionComment', function ($resource) {
  return $resource('/requisitions/:id/comments.json', {}, {});
});

services.factory('Orders', function ($resource) {
  return $resource('/orders.json', {}, {post: {isArray: true, method: 'POST'}});
});

services.factory('ReportTemplates', function ($resource) {
  return $resource('/report-templates.json', {}, {});
});

//Allocation

services.factory('ProgramProducts', function ($resource) {
  return $resource('/programProducts/programId/:programId.json', {}, {});
});

services.factory('FacilityProgramProducts', function ($resource) {
  return $resource('/facility/:facilityId/program/:programId/isa.json', {}, {update: {method: 'PUT', isArray: true}});
});

services.factory('ProgramProductsISA', function ($resource) {
  return $resource('/programProducts/:programProductId/isa/:isaId.json', {isaId: '@isaId'}, update);
});

services.factory('AllocationProgramProducts', function ($resource) {
  return $resource('/facility/:facilityId/programProduct/:programProductId.json', {}, update);
});

services.factory('UserDeliveryZones', function ($resource) {
  return $resource('/user/deliveryZones.json', {}, {});
});

services.factory('DeliveryZone', function ($resource) {
  return $resource('/deliveryZones/:id.json', {id: '@id'}, {});
});

services.factory('DeliveryZoneActivePrograms', function ($resource) {
  return $resource('/deliveryZones/:zoneId/activePrograms.json', {}, {});
});

services.factory('DeliveryZonePrograms', function ($resource) {
  return $resource('/deliveryZones/:zoneId/programs.json', {}, {});
});

services.factory('DeliveryZoneProgramPeriods', function ($resource) {
  return $resource('/deliveryZones/:zoneId/programs/:programId/periods.json', {}, {});
});

services.factory('DeliveryZoneFacilities', function ($resource) {
  return $resource('/deliveryZones/:deliveryZoneId/programs/:programId/facilities.json', {}, {});
});

services.factory('ProgramRegimens', function ($resource) {
  return $resource('/programId/:programId/regimens.json', {}, {});
});
services.factory('Regimens', function ($resource) {
  return $resource('/programId/:programId/regimens.json', {}, {post: {method: 'POST', isArray: true}});
});

services.factory('RegimenColumns', function ($resource) {
  return $resource('/programId/:programId/regimenColumns.json', {}, {});
});

services.factory('RegimenTemplate', function ($resource) {
  return $resource('/programId/:programId/configureRegimenTemplate.json', {}, {});
});

services.factory('ProgramRegimenTemplate', function ($resource) {
  return $resource('/programId/:programId/programRegimenTemplate.json', {}, {});
});

services.factory('GeographicZones', function ($resource) {
  return $resource('/geographicZones/:id.json', {}, {});
});

services.factory('Distributions', function ($resource) {
  return $resource('/distributions.json', {}, {});
});

services.factory('SyncFacilityDistributionData', function ($resource) {
  return $resource('/distributions/:id/facilities/:facilityId.json', {}, update);
});

services.factory('Locales', function ($resource) {
  return $resource('/locales.json', {}, {});
});

services.factory('ChangeLocale', function ($resource) {
  return $resource('/changeLocale.json', {}, update);
});

services.factory('UpdatePassword', function ($resource) {
  return $resource('/admin/resetPassword/:userId.json', {}, update);
});

services.factory('Refrigerators', function ($resource) {
  return $resource('/deliveryZone/:deliveryZoneId/program/:programId/refrigerators.json', {}, {});
});

services.factory('OrderFileTemplate', function ($resource) {
  return $resource('/order-file-template.json', {}, {post: {method: 'POST', isArray: true}});
});

services.factory('DateFormats', function ($resource) {
  return $resource('/date-formats.json', {}, {});
});

services.factory('ShipmentFileTemplate', function ($resource) {
  return $resource('/shipment-file-template.json', {}, {post: {method: 'POST', isArray: true}});
});

services.factory('BudgetFileTemplate', function ($resource) {
  return $resource('/budget-file-template.json', {}, {post: {method: 'POST', isArray: true}});
});

services.factory('EnabledWarehouse', function ($resource) {
  return $resource('/enabledWarehouses.json', {}, {});
});<commit_msg>ELMIS-980: fix the regimen template edit feature not loading<commit_after>/*
 * This program is part of the OpenLMIS logistics management information system platform software.
 * Copyright © 2013 VillageReach
 *
 * This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Affero General Public License for more details.
 * You should have received a copy of the GNU Affero General Public License along with this program.  If not, see http://www.gnu.org/licenses.  For additional information contact info@OpenLMIS.org.
 */

var services = angular.module('openlmis.services', ['ngResource']);
var update = {update: {method: 'PUT'}};

services.value('version', '@version@');

services.factory('Programs', function ($resource) {
  return $resource('/programs/:type.json', {type: '@type'}, {});
});

services.factory('RnRColumnList', function ($resource) {
  return $resource('/program/:programId/rnr-template.json', {}, {post: {isArray: true, method: 'POST'}});
});

services.factory('ProgramRnRColumnList', function ($resource) {
  return $resource('/rnr/:programId/columns.json', {}, {});
});

services.factory('Facility', function ($resource) {
  var resource = $resource('/facilities/:id.json', {id: '@id'}, update);

  resource.restore = function (pathParams, success, error) {
    $resource('/facilities/:id/restore.json', {}, update).update(pathParams, {}, success, error);
  };

  return resource;
});

services.factory('UserContext', function ($resource) {
  return $resource('/user-context.json', {}, {});
});

services.factory('Users', function ($resource) {
  var resource = $resource('/users/:id.json', {id: '@id'}, update);

  resource.disable = function (pathParams, success, error) {
    $resource('/users/:id.json', {}, {update: {method: 'DELETE'}}).update(pathParams, {}, success, error);
  };

  return resource;
});

services.factory('UserFacilityList', function ($resource) {
  return $resource('/user/facilities.json', {}, {});
});

services.factory('UserFacilityWithViewRequisition', function ($resource) {
  return $resource('/user/facilities/view.json', {}, {});
});

services.factory('ProgramsToViewRequisitions', function ($resource) {
  return $resource('/facility/:facilityId/view/requisition/programs.json', {}, {});
});

services.factory('ProgramSupportedByFacility', function ($resource) {
  return $resource('/facilities/:facilityId/programs.json', {}, {});
});

services.factory('FacilityReferenceData', function ($resource) {
  return $resource('/facilities/reference-data.json', {}, {});
});

services.factory('Rights', function ($resource) {
  return $resource('/rights.json', {}, {});
});

services.factory('Roles', function ($resource) {
  return $resource('/roles/:id.json', {id: '@id'}, update);
});

services.factory('CreateRequisitionProgramList', function ($resource) {
  return $resource('/create/requisition/programs.json', {}, {});
});

services.factory('UserSupervisedFacilitiesForProgram', function ($resource) {
  return $resource('/create/requisition/supervised/:programId/facilities.json', {}, {});
});

services.factory('ReferenceData', function ($resource) {
  return $resource('/reference-data/currency.json', {}, {});
});

services.factory('LineItemPageSize', function ($resource) {
  return $resource('/reference-data/lineitem/pagesize.json', {}, {});
});

services.factory('Requisitions', function ($resource) {
  return $resource('/requisitions/:id/:operation.json', {id: '@id', operation: '@operation'}, update);
});

services.factory('RequisitionForApproval', function ($resource) {
  return $resource('/requisitions-for-approval.json', {}, {});
});

services.factory('RequisitionsForViewing', function ($resource) {
  return $resource('/requisitions.json', {}, {});
});

services.factory('RequisitionForConvertToOrder', function ($resource) {
  return $resource('/requisitions-for-convert-to-order.json', {}, {});
});

services.factory('LossesAndAdjustmentsReferenceData', function ($resource) {
  return $resource('/requisitions/lossAndAdjustments/reference-data.json', {}, {});
});

services.factory('Schedule', function ($resource) {
  return $resource('/schedules/:id.json', {id: '@id'}, update);
});

services.factory('Periods', function ($resource) {
  return $resource('/schedules/:scheduleId/periods.json', {}, {});
});

services.factory('PeriodsForFacilityAndProgram', function ($resource) {
  return $resource('/logistics/periods.json', {}, {});
});

services.factory('Period', function ($resource) {
  return $resource('/periods/:id.json', {}, {});
});

services.factory('Program', function ($resource) {
  return $resource('/programs/:id.json', {id: '@id'}, {});
});

services.factory('SupportedUploads', function ($resource) {
  return $resource('/supported-uploads.json', {}, {});
});

services.factory('ForgotPassword', function ($resource) {
  return $resource('/forgot-password.json', {}, {});
});

services.factory('FacilityApprovedProducts', function ($resource) {
  return $resource('/facilityApprovedProducts/facility/:facilityId/program/:programId/nonFullSupply.json', {}, {});
});

services.factory('RequisitionLineItem', function ($resource) {
  return $resource('/logistics/requisition/lineItem.json', {}, {});
});

services.factory('UpdateUserPassword', function ($resource) {
  return $resource('/user/resetPassword/:token.json', {}, update);
});

services.factory('ValidatePasswordToken', function ($resource) {
  return $resource('/user/validatePasswordResetToken/:token.json', {}, {});
});

services.factory('Messages', function ($resource) {
  return $resource('/messages.json', {}, {});
});

services.factory('SupervisoryNodes', function ($resource) {
  return $resource('/supervisory-nodes.json', {}, {});
});

services.factory('FacilityProgramRights', function ($resource) {
  return $resource('/facility/:facilityId/program/:programId/rights.json');
});

services.factory('RequisitionComment', function ($resource) {
  return $resource('/requisitions/:id/comments.json', {}, {});
});

services.factory('Orders', function ($resource) {
  return $resource('/orders.json', {}, {post: {isArray: true, method: 'POST'}});
});

services.factory('ReportTemplates', function ($resource) {
  return $resource('/report-templates.json', {}, {});
});

//Allocation

services.factory('ProgramProducts', function ($resource) {
  return $resource('/programProducts/programId/:programId.json', {}, {});
});

services.factory('FacilityProgramProducts', function ($resource) {
  return $resource('/facility/:facilityId/program/:programId/isa.json', {}, {update: {method: 'PUT', isArray: true}});
});

services.factory('ProgramProductsISA', function ($resource) {
  return $resource('/programProducts/:programProductId/isa/:isaId.json', {isaId: '@isaId'}, update);
});

services.factory('AllocationProgramProducts', function ($resource) {
  return $resource('/facility/:facilityId/programProduct/:programProductId.json', {}, update);
});

services.factory('UserDeliveryZones', function ($resource) {
  return $resource('/user/deliveryZones.json', {}, {});
});

services.factory('DeliveryZone', function ($resource) {
  return $resource('/deliveryZones/:id.json', {id: '@id'}, {});
});

services.factory('DeliveryZoneActivePrograms', function ($resource) {
  return $resource('/deliveryZones/:zoneId/activePrograms.json', {}, {});
});

services.factory('DeliveryZonePrograms', function ($resource) {
  return $resource('/deliveryZones/:zoneId/programs.json', {}, {});
});

services.factory('DeliveryZoneProgramPeriods', function ($resource) {
  return $resource('/deliveryZones/:zoneId/programs/:programId/periods.json', {}, {});
});

services.factory('DeliveryZoneFacilities', function ($resource) {
  return $resource('/deliveryZones/:deliveryZoneId/programs/:programId/facilities.json', {}, {});
});

services.factory('ProgramRegimens', function ($resource) {
  return $resource('/programId/:programId/regimens.json', {}, {});
});

services.factory('RegimenCategories', function ($resource) {
  return $resource('/regimenCategories.json', {}, {});
});

services.factory('Regimens', function ($resource) {
  return $resource('/programId/:programId/regimens.json', {}, {post: {method: 'POST', isArray: true}});
});

services.factory('RegimenColumns', function ($resource) {
  return $resource('/programId/:programId/regimenColumns.json', {}, {});
});

services.factory('RegimenTemplate', function ($resource) {
  return $resource('/programId/:programId/configureRegimenTemplate.json', {}, {});
});

services.factory('ProgramRegimenTemplate', function ($resource) {
  return $resource('/programId/:programId/programRegimenTemplate.json', {}, {});
});

services.factory('GeographicZones', function ($resource) {
  return $resource('/geographicZones/:id.json', {}, {});
});

services.factory('Distributions', function ($resource) {
  return $resource('/distributions.json', {}, {});
});

services.factory('SyncFacilityDistributionData', function ($resource) {
  return $resource('/distributions/:id/facilities/:facilityId.json', {}, update);
});

services.factory('Locales', function ($resource) {
  return $resource('/locales.json', {}, {});
});

services.factory('ChangeLocale', function ($resource) {
  return $resource('/changeLocale.json', {}, update);
});

services.factory('UpdatePassword', function ($resource) {
  return $resource('/admin/resetPassword/:userId.json', {}, update);
});

services.factory('Refrigerators', function ($resource) {
  return $resource('/deliveryZone/:deliveryZoneId/program/:programId/refrigerators.json', {}, {});
});

services.factory('OrderFileTemplate', function ($resource) {
  return $resource('/order-file-template.json', {}, {post: {method: 'POST', isArray: true}});
});

services.factory('DateFormats', function ($resource) {
  return $resource('/date-formats.json', {}, {});
});

services.factory('ShipmentFileTemplate', function ($resource) {
  return $resource('/shipment-file-template.json', {}, {post: {method: 'POST', isArray: true}});
});

services.factory('BudgetFileTemplate', function ($resource) {
  return $resource('/budget-file-template.json', {}, {post: {method: 'POST', isArray: true}});
});

services.factory('EnabledWarehouse', function ($resource) {
  return $resource('/enabledWarehouses.json', {}, {});
});<|endoftext|>


<commit_before>define(function(require, exports, module) {
    var ui = require("zed/ui");
    var zpm = require("configfs!./zpm.js");
    var project = require("zed/project");

    return function(callback) {
       ui.prompt("URL to install extension from:", "", 400, 150, function(err, url) {
            if (url) {
                zpm.install(url, function(err) {
                    callback(err);
                    if (err) {
                        ui.prompt(err, undefined, 300, 150, function() {});
                    } else {
                        project.isConfig(function(err, isConfig) {
                            if (isConfig) {
                                project.reloadFileList();
                            }
                        });
                        ui.prompt("Extension installed!", undefined, 300, 150, function() {});
                    }
                });
            }
       });
    };
});<commit_msg>Fix install<commit_after>define(function(require, exports, module) {
    var ui = require("zed/ui");
    var zpm = require("configfs!./zpm.js");
    var project = require("zed/project");

    return function(info, callback) {
       ui.prompt("URL to install extension from:", "", 400, 150, function(err, url) {
            if (url) {
                zpm.install(url, function(err) {
                    if (err) {
                        ui.prompt(err, undefined, 300, 150, function() {});
                        callback(err);
                    } else {
                        project.isConfig(function(err, isConfig) {
                            if (isConfig) {
                                project.reloadFileList();
                            }
                        });
                        ui.prompt("Extension installed!", undefined, 300, 150, callback);
                    }
                });
            }
       });
    };
});<|endoftext|>


<commit_before>/**
 * Client tests
 */
import React from "react";
import { shallow, render } from "enzyme";
import VictoryLegend from "src/victory-legend/victory-legend";

const initialData = [{
  name: "Series 1",
  symbol: {
    type: "circle"
  }
}, {
  name: "Series 2",
  label: {
    fill: "red"
  },
  symbol: {
    type: "triangleUp",
    style: {
      fill: "blue"
    }
  }
}];

describe("components/victory-legend", () => {
  let wrapper = shallow(
    <VictoryLegend data={initialData} />
  );

  it("has expected content with shallow render", () => {
    const output = wrapper.find("VictoryLabel");
    expect(output.length).to.be.equal(2);
  });

  it("has expected horizontal symbol position", () => {
    const wrappedLegend = shallow(<VictoryLegend data={initialData} orientation="horizontal" />);
    const output = wrappedLegend.find("Point");

    expect(output.at(0).prop("x")).to.be.equal(0);
    expect(output.at(1).prop("x")).to.be.equal(87.68016194331983);
    expect(output.at(0).prop("y")).to.be.equal(0);
    expect(output.at(1).prop("y")).to.be.equal(0);
  });

  it("has expected vertical symbol position", () => {
    const wrappedLegend = shallow(<VictoryLegend data={initialData} orientation="vertical" />);
    const output = wrappedLegend.find("Point");

    expect(output.at(0).prop("x")).to.be.equal(0);
    expect(output.at(1).prop("x")).to.be.equal(0);
    expect(output.at(0).prop("y")).to.be.equal(0);
    expect(output.at(1).prop("y")).to.be.equal(22);
  });

  it("has expected horizontal legend labels position", () => {
    const wrappedLegend = render(<VictoryLegend data={initialData} orientation="horizontal" />);
    const output = wrappedLegend.find("text");

    expect(output.eq(0).prop("x")).to.be.equal("12.18");
    expect(output.eq(1).prop("x")).to.be.equal("99.86016194331984");

    expect(output.eq(0).prop("y")).to.be.equal("0");
    expect(output.eq(1).prop("y")).to.be.equal("0");
  });

  it("has expected vertical legend labels position", () => {
    const wrappedLegend = render(<VictoryLegend data={initialData} orientation="vertical" />);
    const output = wrappedLegend.find("text");
    expect(output.eq(0).prop("x")).to.be.equal("12.18");
    expect(output.eq(1).prop("x")).to.be.equal("12.18");

    expect(output.eq(0).prop("y")).to.be.equal("0");
    expect(output.eq(1).prop("y")).to.be.equal("22");
  });

  describe("symbols", () => {
    const legendData = [{
      name: "Seria 1",
      label: {
        fontSize: 10
      },
      symbol: {
        type: "circle",
        style: {
          fill: "red"
        }
      }
    }, {
      name: "Long Seria Name",
      label: {
        fontSize: 12
      },
      symbol: {
        type: "triangleUp",
        style: {
          fill: "blue"
        }
      }
    }];

    wrapper = shallow(
      <VictoryLegend data={legendData} />
    );

    const output = wrapper.find("Point");

    it("has expected symbols length", () => {
      expect(output.length).to.be.equal(2);
    });

    it("has expected symbol colors", () => {
      expect(output.get(0).props.style.fill).to.be.equal("red");
      expect(output.get(1).props.style.fill).to.be.equal("blue");
    });

    it("has expected symbol type", () => {
      expect(output.get(0).props.symbol).to.be.equal("circle");
      expect(output.get(1).props.symbol).to.be.equal("triangleUp");
    });
  });

  describe("legend style prop", () => {
    const legendData = [{
      name: "Thing 1"
    }, {
      name: "Thing 2"
    }];

    const styleObject = {
      symbol: {
        type: "triangleUp",
        fill: "green"
      },
      labels: {
        fontSize: 16
      }
    };

    wrapper = shallow(
      <VictoryLegend data={legendData} style={styleObject} />
    );
    const outputPoints = wrapper.find("Point");
    const outputLabels = wrapper.find("VictoryLabel");

    it("has expected symbol type", () => {
      expect(outputPoints.at(0).prop("type")).to.be.equal("triangleUp");
      expect(outputPoints.at(1).prop("type")).to.be.equal("triangleUp");
    });

    it("has expected symbol colors", () => {
      expect(outputPoints.at(0).prop("fill")).to.be.equal("green");
      expect(outputPoints.at(1).prop("fill")).to.be.equal("green");
    });

    it("has expected symbol colors", () => {
      expect(outputLabels.at(0).prop("color")).to.be.equal("#252525");
      expect(outputLabels.at(1).prop("color")).to.be.equal("#252525");
    });
  });
});
<commit_msg>update tests<commit_after>/**
 * Client tests
 */
import React from "react";
import { shallow, render } from "enzyme";
import VictoryLegend from "src/victory-legend/victory-legend";

const initialData = [{
  name: "Series 1",
  symbol: {
    type: "circle"
  }
}, {
  name: "Series 2",
  label: {
    fill: "red"
  },
  symbol: {
    type: "triangleUp",
    fill: "blue"
  }
}];

describe("components/victory-legend", () => {
  let wrapper = shallow(<VictoryLegend data={initialData} />);

  it("has expected content with shallow render", () => {
    const output = wrapper.find("VictoryLabel");
    expect(output.length).to.equal(2);
  });

  it("has expected horizontal symbol position", () => {
    const wrappedLegend = shallow(<VictoryLegend data={initialData} orientation="horizontal" />);
    const output = wrappedLegend.find("Point");

    expect(output.at(0).prop("x")).to.equal(7);
    expect(output.at(1).prop("x")).to.equal(95.68016194331983);
    expect(output.at(0).prop("y")).to.equal(7);
    expect(output.at(1).prop("y")).to.equal(7);
  });

  it("has expected vertical symbol position", () => {
    const wrappedLegend = shallow(<VictoryLegend data={initialData} orientation="vertical" />);
    const output = wrappedLegend.find("Point");

    expect(output.at(0).prop("x")).to.equal(7);
    expect(output.at(1).prop("x")).to.equal(7);
    expect(output.at(0).prop("y")).to.equal(7);
    expect(output.at(1).prop("y")).to.equal(31);
  });

  it("has expected horizontal legend labels position", () => {
    const wrappedLegend = render(<VictoryLegend data={initialData} orientation="horizontal" />);
    const output = wrappedLegend.find("text");

    expect(output.eq(0).prop("x")).to.equal("22");
    expect(output.eq(1).prop("x")).to.equal("110.68016194331983");
    expect(output.eq(0).prop("y")).to.equal("7");
    expect(output.eq(1).prop("y")).to.equal("7");
  });

  it("has expected vertical legend labels position", () => {
    const wrappedLegend = render(<VictoryLegend data={initialData} orientation="vertical" />);
    const output = wrappedLegend.find("text");

    expect(output.eq(0).prop("x")).to.equal("22");
    expect(output.eq(1).prop("x")).to.equal("22");
    expect(output.eq(0).prop("y")).to.equal("7");
    expect(output.eq(1).prop("y")).to.equal("31");
  });

  describe("symbols", () => {
    const legendData = [{
      name: "Series 1",
      label: {
        fontSize: 10
      },
      symbol: {
        type: "circle",
        fill: "red"
      }
    }, {
      name: "Long Series Name",
      label: {
        fontSize: 12
      },
      symbol: {
        type: "triangleUp",
        fill: "blue"
      }
    }];

    wrapper = shallow(<VictoryLegend data={legendData} />);
    const output = wrapper.find("Point");

    it("has expected symbols length", () => {
      expect(output.length).to.equal(2);
    });

    it("has expected symbol colors", () => {
      expect(output.get(0).props.style.fill).to.equal("red");
      expect(output.get(1).props.style.fill).to.equal("blue");
    });

    it("has expected symbol type", () => {
      expect(output.get(0).props.symbol).to.equal("circle");
      expect(output.get(1).props.symbol).to.equal("triangleUp");
    });
  });

  describe("legend style prop", () => {
    const legendData = [{
      name: "Thing 1"
    }, {
      name: "Thing 2"
    }];

    const styleObject = {
      symbol: {
        type: "triangleUp",
        fill: "green"
      },
      label: {
        fontSize: 16
      }
    };

    wrapper = shallow(<VictoryLegend data={legendData} style={styleObject} />);
    const outputPoints = wrapper.find("Point");
    const outputLabels = wrapper.find("VictoryLabel");

    it("has expected symbol type", () => {
      expect(outputPoints.at(0).prop("symbol")).to.equal("triangleUp");
      expect(outputPoints.at(1).prop("symbol")).to.equal("triangleUp");
    });

    it("has expected symbol colors", () => {
      expect(outputPoints.get(0).props.style.fill).to.equal("green");
      expect(outputPoints.get(1).props.style.fill).to.equal("green");
    });

    it("has expected symbol colors", () => {
      expect(outputLabels.get(0).props.style.color).to.equal("#252525");
      expect(outputLabels.get(1).props.style.color).to.equal("#252525");
    });
  });
});
<|endoftext|>


<commit_before>var warp10 = require('warp10');

var escape = require('./escape');
var escapeString = escape.escapeString;
var escapeXmlAttr = escape.escapeXmlAttr;

var stringifiedAttrTest = /[&\'\n]/;
var stringifiedAttrReplace = /[&\'\n]/g;

function attr(name, value, shouldEscape) {
    if (typeof value === 'string') {
        return ' ' + name + '="' + (shouldEscape !== false ? escapeXmlAttr(value) : value) + '"';
    } else if (value === true) {
        return ' ' + name;
    } else if (value == null || value === false) {
        return '';
    } else if (typeof value === 'object') {
        if (name.substring(0, 6) === 'data-_') {
            value = warp10.stringify(value);
        } else {
            value = JSON.stringify(value);
        }
        return ' ' + name + "='" + escapeString(value, stringifiedAttrTest, stringifiedAttrReplace) + "'";
    } else {
        return ' ' + name + '=' + value; // number (doesn't need quotes)
    }
}

module.exports = attr;<commit_msg>Performance optimization<commit_after>var warp10 = require('warp10');

var escape = require('./escape');
var escapeString = escape.escapeString;
var escapeXmlAttr = escape.escapeXmlAttr;

var stringifiedAttrTest = /[&\'\n]/;
var stringifiedAttrReplace = /[&\'\n]/g;

function attr(name, value, shouldEscape) {
    shouldEscape = shouldEscape !== false;

    if (typeof value === 'string') {
        return ' ' + name + '="' + (shouldEscape ? escapeXmlAttr(value) : value) + '"';
    } else if (value === true) {
        return ' ' + name;
    } else if (value == null || value === false) {
        return '';
    } else if (typeof value === 'object') {
        if (name.substring(0, 6) === 'data-_') {
            value = warp10.stringify(value);
        } else {
            value = JSON.stringify(value);
        }
        return ' ' + name + "='" + escapeString(value, stringifiedAttrTest, stringifiedAttrReplace) + "'";
    } else {
        return ' ' + name + '=' + value; // number (doesn't need quotes)
    }
}

module.exports = attr;<|endoftext|>


<commit_before>/** Script ACLs do not delete
 read=nobody
write=nobody
execute=authenticated
  **/
 /*#*beginblockly*#*<xml xmlns="http://www.w3.org/1999/xhtml"><block type="variables_set" id="1" inline="true" x="2" y="14"><field name="VAR">msg</field><value name="VALUE"><block type="scriptr_jsonstringify" id="2" inline="true"><value name="stringJson"><block type="dicts_create_with" id="3" inline="false"><mutation items="2"></mutation><field name="KEY0">id</field><field name="KEY1">value</field><value name="INPUT0"><block type="text" id="4"><field name="TEXT">slider</field></block></value><value name="INPUT1"><block type="text" id="5"><field name="TEXT">888</field></block></value></block></value></block></value><next><block type="scriptr_return" id="6" inline="false"><value name="return"><block type="scriptr_publish" id="7" inline="true"><value name="message"><block type="variables_get" id="8"><field name="VAR">msg</field></block></value><value name="channel"><block type="text" id="9"><field name="TEXT">virtualDeviceSend</field></block></value></block></value></block></next></block></xml>*#*#*/
var msg;

msg = ((function(){var obj = {"id": 'slider',
	"value": '888'}; if(typeof obj == "object") return JSON.stringify(obj); else return obj;})());
return publish ('virtualDeviceSend', msg,false)			<commit_msg>Delete testVirtualDeviceSend.js<commit_after><|endoftext|>


<commit_before>'use strict'

class Buffer {
  static get (opts) {
    return new Buffer(opts)
  }

  constructor (opts) {
    opts = opts || {}
    this._lineSep = opts.lineSep || '\n'
    this._sectionSep = opts.sectionSep || this._lineSep + this._lineSep
    this._pad = opts.pad || ' '
    this._indent = opts.indent || this._pad + this._pad
    this._split = opts.split || /\s/g // note that global is needed for the chunk method and doesn't affect split() usage
    // stuff
    this._icon = opts.icon || ''     // think alain
    this._slogan = opts.slogan || '' // "Need a product name? Ask alain!"
    this._usage = opts.usage || ''   // "Usage: $0 [options] <command>"
    this._groups = opts.groups || {} // Commands, Options, Examples
    this._groupOrder = opts.groupOrder || ['Commands:', 'Arguments:', 'Options:']
    // each group keyed by heading
    // with a value of array<types>
    // each type should have:
    // - flags with or without placeholder
    // - description
    // - hints
    this._epilogue = opts.epilogue || '' // "See alainasaservice.com for more details"
    this._error = opts.error
    this._errorMsg = opts.errorMsg || ''
    this._maxWidth = opts.maxWidth || Math.min(process.stdout.columns || 100, 100)
    // dependencies
    this._utils = opts.utils
  }

  reset () {
    // TODO reset error stuff
  }

  get utils () {
    if (!this._utils) this._utils = require('./lib/utils').get()
    return this._utils
  }

  get lineSep () {
    return this._lineSep
  }

  get sectionSep () {
    return this._sectionSep
  }

  get pad () {
    return this._pad
  }

  get indent () {
    return this._indent
  }

  get split () {
    return this._split
  }

  get maxWidth () {
    return this._maxWidth
  }

  get icon () {
    return this._icon
  }

  get slogan () {
    return this._slogan
  }

  get usage () {
    return this._usage
  }

  get groups () {
    return this._groups
  }

  set groups (g) {
    this._groups = g
  }

  get groupOrder () {
    return this._groupOrder
  }

  get epilogue () {
    return this._epilogue
  }

  toString (opts) {
    opts = opts || {}
    let str = this.helpContent(opts)
    str = this.appendSection(str, this.errorContent(opts), this.sectionSep)
    return str
  }

  helpContent (opts) {
    opts = Object.assign({
      includePreface: true,
      includeUsage: true,
      includeGroups: true,
      includeEpilogue: true
    }, opts)
    let str = this.appendSection('', !!opts.includePreface && this.icon, this.sectionSep)
    if (opts.includePreface) str = this.appendSection(str, this.slogan, this.sectionSep)
    if (opts.includeUsage) str = this.appendSection(str, this.usage, this.sectionSep)
    if (opts.includeGroups) str = this.appendSection(str, this.groupsContent(), this.sectionSep)
    if (opts.includeEpilogue) str = this.appendSection(str, this.epilogue, this.sectionSep)
    return str
  }

  groupsContent () {
    let str = ''
    let groupsLeft = JSON.parse(JSON.stringify(this.groups))
    let order = this.groupOrder
    if (!order || !order.length) order = Object.keys(groupsLeft)
    let types
    order.forEach(heading => {
      types = groupsLeft[heading] // array of types
      if (!types || !types.length) {
        delete groupsLeft[heading]
        return undefined
      }

      // first determine width needed for all flags
      let flagsWidth = 0
      types.forEach(type => {
        if (type.isHidden) return undefined
        if (type.helpFlags) flagsWidth = Math.max(flagsWidth, this.utils.stripAnsi(type.helpFlags).length)
      })

      if (heading) str = this.appendSection(str, heading, this.sectionSep)

      // then add each line:
      // indent + flags + padding + indent + ((desc + padding + hints) || (descMultiline + hintsMultiline))
      // let p = true
      types.forEach(type => {
        // if (p) {
        //   p = false
        //   str += '\n' + new Array(this.maxWidth + 1).join('.')
        // }
        str = this.appendTypeSimple(str, type, flagsWidth)
      })

      delete groupsLeft[heading]
    })
    Object.keys(groupsLeft).forEach(heading => {
      // TODO ditto
    })
    return str
  }

  groupsContentX () {
    let str = ''
    let groupsLeft = JSON.parse(JSON.stringify(this.groups))
    let order = this.groupOrder
    if (!order || !order.length) order = Object.keys(groupsLeft)
    let types
    order.forEach(heading => {
      types = groupsLeft[heading] // array of types
      if (!types || !types.length) {
        delete groupsLeft[heading]
        return undefined
      }
      let flagsWidth = 0
      let descWidth = 0
      let hintsWidth = 0
      let minHintsWidth = 0
      let hintsNoAnsi
      types.forEach(type => {
        if (type.isHidden) return undefined
        if (type.helpFlags) flagsWidth = Math.max(flagsWidth, this.utils.stripAnsi(type.helpFlags).length)
        if (type.helpDesc) descWidth = Math.max(descWidth, this.utils.stripAnsi(type.helpDesc).length)
        // TODO perhaps helpHints should be an array ??
        if (type.helpHints) {
          hintsNoAnsi = this.utils.stripAnsi(type.helpHints)
          hintsWidth = Math.max(hintsWidth, hintsNoAnsi.length)
          minHintsWidth = Math.max(minHintsWidth, hintsNoAnsi.split(this.split).filter(Boolean).reduce((x, y) => Math.max(x, y.length), 0))
        }
      })
      if (flagsWidth === 0 && descWidth === 0 && hintsWidth === 0) return undefined
      if (heading) {
        str += heading
        // str += this.lineSep
      }
      let maxDescWidth = (this.maxWidth - (this.indent.length * 3) - flagsWidth) * (descWidth / (descWidth + hintsWidth))
      let maxHintsWidth = (this.maxWidth - (this.indent.length * 3) - flagsWidth) * (hintsWidth / (descWidth + hintsWidth))
      maxHintsWidth = Math.max(Math.floor(maxHintsWidth), minHintsWidth)
      maxDescWidth = Math.min(Math.floor(maxDescWidth), this.maxWidth - (this.indent.length * 3) - flagsWidth - maxHintsWidth)
      // let line
      let p = true
      types.forEach(type => {
        if (p) {
          p = false
          str += '\n' + new Array(this.maxWidth + 1).join('.')
          str += '\n' + new Array((this.indent.length * 3) + flagsWidth + maxDescWidth + maxHintsWidth + 1).join('=')
          str = this.appendType(str, {
            helpFlags: String(flagsWidth),
            helpDesc: String(maxDescWidth),
            helpHints: String(maxHintsWidth)
          }, flagsWidth, maxDescWidth, maxHintsWidth)
        }
        str = this.appendType(str, type, flagsWidth, maxDescWidth, maxHintsWidth)
      })

      delete groupsLeft[heading]
    })
    Object.keys(groupsLeft).forEach(heading => {
      // TODO ditto
    })
    return str
  }

  errorContent () {
    return '' // TODO
  }

  appendTypeSimple (str, type, flagsWidth) {
    if (type.isHidden || (!type.helpFlags && !type.helpDesc && !type.helpHints)) return str

    let maxWidth = Math.max(this.maxWidth, this.indent.length + flagsWidth)
    let flag = type.helpFlags
    let desc = type.helpDesc
    let hint = type.helpHints
    let line = ''

    // single line case
    let singleLineWidth = 0
    if (flag) singleLineWidth += this.indent.length + flagsWidth
    if (desc) singleLineWidth += this.indent.length + this.utils.stripAnsi(desc).length
    if (hint) singleLineWidth += this.indent.length + this.utils.stripAnsi(hint).length
    if (singleLineWidth <= maxWidth) {
      if (flag) {
        line += this.indent + flag + new Array(this.pos(flagsWidth, flag)).join(this.pad)
      } else if (flagsWidth > 0) {
        line += this.indent + new Array(flagsWidth + 1).join(this.pad)
      }

      if (desc) {
        line += this.indent + desc
      }
      if (hint) {
        line += new Array(this.pos(maxWidth, line + hint)).join(this.pad)
        line += hint
      }
      return this.appendSection(str, line, this.lineSep)
    }

    // multi line case
    let leftOverWidth = maxWidth
    if (flag) {
      line += this.indent + flag + new Array(this.pos(flagsWidth, flag)).join(this.pad)
    } else if (flagsWidth > 0) {
      line += this.indent + new Array(flagsWidth + 1).join(this.pad)
    }
    if (line) leftOverWidth -= this.utils.stripAnsi(line).length
    if (desc) {
      leftOverWidth -= this.indent.length
      // line += this.indent
      let chunks = this.chunk(desc, leftOverWidth)
      desc = chunks.shift()
      let first = true
      while (desc) {
        if (!first) line = ''
        if (!first && flagsWidth > 0) line += this.indent + new Array(flagsWidth + 1).join(this.pad)
        first = false
        line += this.indent + desc
        str = this.appendSection(str, line, this.lineSep)
        desc = chunks.shift()
      }
      line = ''
    }
    if (hint) {
      leftOverWidth -= this.indent.length
      // line += this.indent
      let chunks = this.chunk(hint, leftOverWidth)
      hint = chunks.shift()
      let first = true
      while (hint) {
        if (!first) line = ''
        first = false
        if (flagsWidth > 0) line += this.indent + new Array(flagsWidth + 1).join(this.pad)
        line += this.indent + hint
        str = this.appendSection(str, line, this.lineSep)
        hint = chunks.shift()
      }
    }
    return str
  }

  appendType (str, type, flagsWidth, descWidth, hintsWidth) {
    if (type.isHidden || (!type.helpFlags && !type.helpDesc && !type.helpHints)) return str
    let flag = type.helpFlags

    // split desc and hint into array of chunks <= width
    let descChunks = this.chunk(type.helpDesc, descWidth)
    let hintChunks = this.chunk(type.helpHints, hintsWidth)
    let desc = descChunks.shift()
    let hint = hintChunks.shift()

    let line
    while (flag || desc || hint) {
      line = ''

      if (flag) {
        line += this.indent + flag + new Array(this.pos(flagsWidth, flag)).join(this.pad)
        flag = ''
      } else {
        line += this.indent + new Array(flagsWidth + 1).join(this.pad)
      }

      if (desc) {
        line += this.indent + desc + new Array(this.pos(descWidth, desc)).join(this.pad)
        desc = descChunks.shift()
      } else {
        line += this.indent + new Array(descWidth + 1).join(this.pad)
      }

      if (hint) { // right-aligned, so padding first
        line += this.indent + new Array(this.pos(hintsWidth, hint)).join(this.pad) + hint
        hint = hintChunks.shift()
      } else {
        // TODO need anything here?
      }

      str = this.appendSection(str, line, this.lineSep)
    }
    return str
  }

  // split a string into an array of chunks which are each <= width
  chunk (str, width) {
    let chunks = []
    let chunk
    let ansiDiff
    let index
    let noAnsi
    while (str) {
      noAnsi = this.utils.stripAnsi(str)
      index = noAnsi.length <= width ? width : this.lastIndexOfRegex(noAnsi, this.split, width)
      if (index === -1) index = width
      // TODO this ain't cutting it for ansi reconstitution
      chunk = str.slice(0, index).trim()
      ansiDiff = chunk.length - this.utils.stripAnsi(chunk).length
      if (ansiDiff > 0) {
        index += ansiDiff
        chunk = str.slice(0, index).trim()
      }
      chunks.push(chunk)
      // prep for next iteration
      str = str.slice(index)
    }
    return chunks
  }

  lastIndexOfRegex (str, regex, fromIndex) {
    // based on http://stackoverflow.com/a/21420210/1174467
    str = fromIndex ? str.substring(0, fromIndex) : str
    let match = str.match(regex)
    return match ? str.lastIndexOf(match[match.length - 1]) : -1
  }

  // width diff
  pos (w, s) {
    return Math.max(0, w - this.utils.stripAnsi(s).length + 1)
  }

  appendSection (str, section, sep) {
    if (section && str.length) str += sep
    if (section) str += section
    return str
  }
}

module.exports = Buffer
<commit_msg>better impl of default group order<commit_after>'use strict'

class Buffer {
  static get (opts) {
    return new Buffer(opts)
  }

  constructor (opts) {
    opts = opts || {}
    this._lineSep = opts.lineSep || '\n'
    this._sectionSep = opts.sectionSep || this._lineSep + this._lineSep
    this._pad = opts.pad || ' '
    this._indent = opts.indent || this._pad + this._pad
    this._split = opts.split || /\s/g // note that global is needed for the chunk method and doesn't affect split() usage
    // stuff
    this._icon = opts.icon || ''     // think alain
    this._slogan = opts.slogan || '' // "Need a product name? Ask alain!"
    this._usage = opts.usage || ''   // "Usage: $0 [options] <command>"
    this._groups = opts.groups || {} // Commands, Options, Examples
    this._groupOrder = opts.groupOrder || []
    // each group keyed by heading
    // with a value of array<types>
    // each type should have:
    // - flags with or without placeholder
    // - description
    // - hints
    this._epilogue = opts.epilogue || '' // "See alainasaservice.com for more details"
    this._error = opts.error
    this._errorMsg = opts.errorMsg || ''
    this._maxWidth = opts.maxWidth || Math.min(process.stdout.columns || 100, 100)
    // dependencies
    this._utils = opts.utils
  }

  reset () {
    // TODO reset error stuff
  }

  get utils () {
    if (!this._utils) this._utils = require('./lib/utils').get()
    return this._utils
  }

  get lineSep () {
    return this._lineSep
  }

  get sectionSep () {
    return this._sectionSep
  }

  get pad () {
    return this._pad
  }

  get indent () {
    return this._indent
  }

  get split () {
    return this._split
  }

  get maxWidth () {
    return this._maxWidth
  }

  get icon () {
    return this._icon
  }

  get slogan () {
    return this._slogan
  }

  get usage () {
    return this._usage
  }

  get groups () {
    return this._groups
  }

  set groups (g) {
    this._groups = g
  }

  get groupOrder () {
    return this._groupOrder
  }

  get epilogue () {
    return this._epilogue
  }

  toString (opts) {
    opts = opts || {}
    let str = this.helpContent(opts)
    str = this.appendSection(str, this.errorContent(opts), this.sectionSep)
    return str
  }

  helpContent (opts) {
    opts = Object.assign({
      includePreface: true,
      includeUsage: true,
      includeGroups: true,
      includeEpilogue: true
    }, opts)
    let str = this.appendSection('', !!opts.includePreface && this.icon, this.sectionSep)
    if (opts.includePreface) str = this.appendSection(str, this.slogan, this.sectionSep)
    if (opts.includeUsage) str = this.appendSection(str, this.usage, this.sectionSep)
    if (opts.includeGroups) str = this.appendSection(str, this.groupsContent(), this.sectionSep)
    if (opts.includeEpilogue) str = this.appendSection(str, this.epilogue, this.sectionSep)
    return str
  }

  groupsContent () {
    let str = ''
    let groupsLeft = JSON.parse(JSON.stringify(this.groups))
    let order = this.groupOrder
    if (!order || !order.length) {
      // default order: Commands, Arguments, <custom>, Options
      order = Array.from(new Set(['Commands:', 'Arguments:'].concat(Object.keys(groupsLeft)).concat('Options:')))
    }
    let types
    order.forEach(heading => {
      types = groupsLeft[heading] // array of types
      if (!types || !types.length) {
        delete groupsLeft[heading]
        return undefined
      }

      // first determine width needed for all flags
      let flagsWidth = 0
      types.forEach(type => {
        if (type.isHidden) return undefined
        if (type.helpFlags) flagsWidth = Math.max(flagsWidth, this.utils.stripAnsi(type.helpFlags).length)
      })

      if (heading) str = this.appendSection(str, heading, this.sectionSep)

      // then add each line:
      // indent + flags + padding + indent + ((desc + padding + hints) || (descMultiline + hintsMultiline))
      // let p = true
      types.forEach(type => {
        // if (p) {
        //   p = false
        //   str += '\n' + new Array(this.maxWidth + 1).join('.')
        // }
        str = this.appendTypeSimple(str, type, flagsWidth)
      })

      delete groupsLeft[heading]
    })
    Object.keys(groupsLeft).forEach(heading => {
      // TODO ditto
    })
    return str
  }

  groupsContentX () {
    let str = ''
    let groupsLeft = JSON.parse(JSON.stringify(this.groups))
    let order = this.groupOrder
    if (!order || !order.length) order = Object.keys(groupsLeft)
    let types
    order.forEach(heading => {
      types = groupsLeft[heading] // array of types
      if (!types || !types.length) {
        delete groupsLeft[heading]
        return undefined
      }
      let flagsWidth = 0
      let descWidth = 0
      let hintsWidth = 0
      let minHintsWidth = 0
      let hintsNoAnsi
      types.forEach(type => {
        if (type.isHidden) return undefined
        if (type.helpFlags) flagsWidth = Math.max(flagsWidth, this.utils.stripAnsi(type.helpFlags).length)
        if (type.helpDesc) descWidth = Math.max(descWidth, this.utils.stripAnsi(type.helpDesc).length)
        // TODO perhaps helpHints should be an array ??
        if (type.helpHints) {
          hintsNoAnsi = this.utils.stripAnsi(type.helpHints)
          hintsWidth = Math.max(hintsWidth, hintsNoAnsi.length)
          minHintsWidth = Math.max(minHintsWidth, hintsNoAnsi.split(this.split).filter(Boolean).reduce((x, y) => Math.max(x, y.length), 0))
        }
      })
      if (flagsWidth === 0 && descWidth === 0 && hintsWidth === 0) return undefined
      if (heading) {
        str += heading
        // str += this.lineSep
      }
      let maxDescWidth = (this.maxWidth - (this.indent.length * 3) - flagsWidth) * (descWidth / (descWidth + hintsWidth))
      let maxHintsWidth = (this.maxWidth - (this.indent.length * 3) - flagsWidth) * (hintsWidth / (descWidth + hintsWidth))
      maxHintsWidth = Math.max(Math.floor(maxHintsWidth), minHintsWidth)
      maxDescWidth = Math.min(Math.floor(maxDescWidth), this.maxWidth - (this.indent.length * 3) - flagsWidth - maxHintsWidth)
      // let line
      let p = true
      types.forEach(type => {
        if (p) {
          p = false
          str += '\n' + new Array(this.maxWidth + 1).join('.')
          str += '\n' + new Array((this.indent.length * 3) + flagsWidth + maxDescWidth + maxHintsWidth + 1).join('=')
          str = this.appendType(str, {
            helpFlags: String(flagsWidth),
            helpDesc: String(maxDescWidth),
            helpHints: String(maxHintsWidth)
          }, flagsWidth, maxDescWidth, maxHintsWidth)
        }
        str = this.appendType(str, type, flagsWidth, maxDescWidth, maxHintsWidth)
      })

      delete groupsLeft[heading]
    })
    Object.keys(groupsLeft).forEach(heading => {
      // TODO ditto
    })
    return str
  }

  errorContent () {
    return '' // TODO
  }

  appendTypeSimple (str, type, flagsWidth) {
    if (type.isHidden || (!type.helpFlags && !type.helpDesc && !type.helpHints)) return str

    let maxWidth = Math.max(this.maxWidth, this.indent.length + flagsWidth)
    let flag = type.helpFlags
    let desc = type.helpDesc
    let hint = type.helpHints
    let line = ''

    // single line case
    let singleLineWidth = 0
    if (flag) singleLineWidth += this.indent.length + flagsWidth
    if (desc) singleLineWidth += this.indent.length + this.utils.stripAnsi(desc).length
    if (hint) singleLineWidth += this.indent.length + this.utils.stripAnsi(hint).length
    if (singleLineWidth <= maxWidth) {
      if (flag) {
        line += this.indent + flag + new Array(this.pos(flagsWidth, flag)).join(this.pad)
      } else if (flagsWidth > 0) {
        line += this.indent + new Array(flagsWidth + 1).join(this.pad)
      }

      if (desc) {
        line += this.indent + desc
      }
      if (hint) {
        line += new Array(this.pos(maxWidth, line + hint)).join(this.pad)
        line += hint
      }
      return this.appendSection(str, line, this.lineSep)
    }

    // multi line case
    let leftOverWidth = maxWidth
    if (flag) {
      line += this.indent + flag + new Array(this.pos(flagsWidth, flag)).join(this.pad)
    } else if (flagsWidth > 0) {
      line += this.indent + new Array(flagsWidth + 1).join(this.pad)
    }
    if (line) leftOverWidth -= this.utils.stripAnsi(line).length
    if (desc) {
      leftOverWidth -= this.indent.length
      // line += this.indent
      let chunks = this.chunk(desc, leftOverWidth)
      desc = chunks.shift()
      let first = true
      while (desc) {
        if (!first) line = ''
        if (!first && flagsWidth > 0) line += this.indent + new Array(flagsWidth + 1).join(this.pad)
        first = false
        line += this.indent + desc
        str = this.appendSection(str, line, this.lineSep)
        desc = chunks.shift()
      }
      line = ''
    }
    if (hint) {
      leftOverWidth -= this.indent.length
      // line += this.indent
      let chunks = this.chunk(hint, leftOverWidth)
      hint = chunks.shift()
      let first = true
      while (hint) {
        if (!first) line = ''
        first = false
        if (flagsWidth > 0) line += this.indent + new Array(flagsWidth + 1).join(this.pad)
        line += this.indent + hint
        str = this.appendSection(str, line, this.lineSep)
        hint = chunks.shift()
      }
    }
    return str
  }

  appendType (str, type, flagsWidth, descWidth, hintsWidth) {
    if (type.isHidden || (!type.helpFlags && !type.helpDesc && !type.helpHints)) return str
    let flag = type.helpFlags

    // split desc and hint into array of chunks <= width
    let descChunks = this.chunk(type.helpDesc, descWidth)
    let hintChunks = this.chunk(type.helpHints, hintsWidth)
    let desc = descChunks.shift()
    let hint = hintChunks.shift()

    let line
    while (flag || desc || hint) {
      line = ''

      if (flag) {
        line += this.indent + flag + new Array(this.pos(flagsWidth, flag)).join(this.pad)
        flag = ''
      } else {
        line += this.indent + new Array(flagsWidth + 1).join(this.pad)
      }

      if (desc) {
        line += this.indent + desc + new Array(this.pos(descWidth, desc)).join(this.pad)
        desc = descChunks.shift()
      } else {
        line += this.indent + new Array(descWidth + 1).join(this.pad)
      }

      if (hint) { // right-aligned, so padding first
        line += this.indent + new Array(this.pos(hintsWidth, hint)).join(this.pad) + hint
        hint = hintChunks.shift()
      } else {
        // TODO need anything here?
      }

      str = this.appendSection(str, line, this.lineSep)
    }
    return str
  }

  // split a string into an array of chunks which are each <= width
  chunk (str, width) {
    let chunks = []
    let chunk
    let ansiDiff
    let index
    let noAnsi
    while (str) {
      noAnsi = this.utils.stripAnsi(str)
      index = noAnsi.length <= width ? width : this.lastIndexOfRegex(noAnsi, this.split, width)
      if (index === -1) index = width
      // TODO this ain't cutting it for ansi reconstitution
      chunk = str.slice(0, index).trim()
      ansiDiff = chunk.length - this.utils.stripAnsi(chunk).length
      if (ansiDiff > 0) {
        index += ansiDiff
        chunk = str.slice(0, index).trim()
      }
      chunks.push(chunk)
      // prep for next iteration
      str = str.slice(index)
    }
    return chunks
  }

  lastIndexOfRegex (str, regex, fromIndex) {
    // based on http://stackoverflow.com/a/21420210/1174467
    str = fromIndex ? str.substring(0, fromIndex) : str
    let match = str.match(regex)
    return match ? str.lastIndexOf(match[match.length - 1]) : -1
  }

  // width diff
  pos (w, s) {
    return Math.max(0, w - this.utils.stripAnsi(s).length + 1)
  }

  appendSection (str, section, sep) {
    if (section && str.length) str += sep
    if (section) str += section
    return str
  }
}

module.exports = Buffer
<|endoftext|>


<commit_before>'use strict';

const test = require('ava');
const chai = require('chai');

const integrationHelper = require('../../../../helpers/integration');
const stubs = require('../../../../helpers/stubs');
const metadataParserConfig = require('../../../../../config/lib/middleware/metadata-parse');

chai.should();

test.before(async () => {
  await integrationHelper.hooks.db.connect();
});

test.beforeEach((t) => {
  integrationHelper.hooks.cache.broadcasts.set(
    stubs.getBroadcastId(),
    stubs.graphql.getBroadcastSingleResponse().data.broadcast,
  );
  integrationHelper.hooks.app(t.context);
});

test.afterEach(async () => {
  integrationHelper.hooks.interceptor.cleanAll();
  integrationHelper.hooks.cache.broadcasts.set(stubs.getBroadcastId(), null);
  await integrationHelper.hooks.db.messages.removeAll();
  await integrationHelper.hooks.db.conversations.removeAll();
});

test.after.always(async () => {
  await integrationHelper.hooks.db.disconnect();
});

/**
 * GET /
 */
test('GET /api/v2/messages should return 401 if not using valid credentials', async (t) => {
  const res = await t.context.request.get(integrationHelper.routes.v2.messages());
  res.status.should.be.equal(401);
});

test('GET /api/v2/messages should return 404', async (t) => {
  const res = await t.context.request.get(integrationHelper.routes.v2.messages())
    .set('Authorization', `Basic ${integrationHelper.getAuthKey()}`);
  res.status.should.be.equal(404);
});

test.serial('POST /api/v2/messages?origin=twilio should not re-send message to Twilio on retry', async (t) => {
  const member = stubs.northstar.getUser({ validUsNumber: true });
  const inboundRequestPayload = stubs.twilio.getInboundRequestBody(member);
  const requestId = stubs.getRequestId();

  integrationHelper.routes.graphql
    .intercept(stubs.graphql.fetchConversationTriggers(), 2);

  // mock user fetch twice
  integrationHelper.routes.northstar
    .intercept.fetchUserByMobile(inboundRequestPayload.From, member, 2);

  // mock user update twice
  integrationHelper.routes.northstar
    .intercept.updateUserById(member.data.id, member, 2);

  /**
   * 1st attempt
   */
  const res1 = await t.context.request
    .post(integrationHelper.routes.v2.messages(false, {
      origin: 'twilio',
    }))
    .set({
      Authorization: `Basic ${integrationHelper.getAuthKey()}`,
      [metadataParserConfig.metadata.headers.requestId]: requestId,
    })
    .send(inboundRequestPayload);

  res1.status.should.be.equal(200);
  res1.body.data.messages.inbound.length.should.be.equal(1);
  res1.body.data.messages.outbound.length.should.be.equal(1);

  const outboundMessage1 = res1.body.data.messages.outbound[0];

  /**
   * 2nd attempt (retry)
   */
  const res2 = await t.context.request
    .post(integrationHelper.routes.v2.messages(false, {
      origin: 'twilio',
    }))
    .set({
      Authorization: `Basic ${integrationHelper.getAuthKey()}`,
      [metadataParserConfig.metadata.headers.requestId]: requestId,
      [metadataParserConfig.metadata.headers.retryCount]: '1',
    })
    .send(inboundRequestPayload);

  res2.status.should.be.equal(200);
  res2.body.data.messages.inbound.length.should.be.equal(1);
  res2.body.data.messages.outbound.length.should.be.equal(1);

  const outboundMessage2 = res2.body.data.messages.outbound[0];

  // The retry should not have replaced the platformUserId of the message
  outboundMessage1.platformMessageId.should.be.equal(outboundMessage2.platformMessageId);
});

test('POST /api/v2/messages?origin=twilio outbound message should match sendInfoMessage if user texts INFO', async (t) => {
  const message = {
    getSmsMessageSid: stubs.twilio.getSmsMessageSid(),
    From: stubs.getMobileNumber('valid'),
    Body: 'info',
  };
  const member = stubs.northstar.getUser({
    validUsNumber: true,
  });

  integrationHelper.routes.graphql
    .intercept(stubs.graphql.fetchConversationTriggers(), 1);

  // mock user fetch
  integrationHelper.routes.northstar
    .intercept.fetchUserByMobile(message.From, member, 1);

  // mock user update
  integrationHelper.routes.northstar
    .intercept.updateUserById(member.data.id, member, 1);

  integrationHelper.routes.northstar
    .intercept.fetchUserById(stubs.getUserId(), member, 1);

  const res = await t.context.request
    .post(integrationHelper.routes.v2.messages(false, {
      origin: 'twilio',
    }))
    .set('Authorization', `Basic ${integrationHelper.getAuthKey()}`)
    .send(message);
  res.status.should.be.equal(200);
  res.body.data.messages.outbound[0].text.should.equal('These are Do Something Alerts - 4 messages/mo. Info help@dosomething.org or https://dosome.click/zt6mc. Txt STOP to quit. Msg&Data Rates May Apply.');
  res.body.data.messages.inbound[0].topic.should.equal(res.body.data.messages.outbound[0].topic);
});

test('POST /api/v2/messages?origin=twilio outbound message should match sendInfoMessage if user texts HELP', async (t) => {
  const message = {
    getSmsMessageSid: stubs.twilio.getSmsMessageSid(),
    From: stubs.getMobileNumber('valid'),
    Body: 'help',
  };
  const member = stubs.northstar.getUser({
    validUsNumber: true,
  });

  integrationHelper.routes.graphql
    .intercept(stubs.graphql.fetchConversationTriggers(), 1);

  // mock user fetch
  integrationHelper.routes.northstar
    .intercept.fetchUserByMobile(message.From, member, 1);

  // mock user update
  integrationHelper.routes.northstar
    .intercept.updateUserById(member.data.id, member, 1);

  integrationHelper.routes.northstar
    .intercept.fetchUserById(stubs.getUserId(), member, 1);

  const res = await t.context.request
    .post(integrationHelper.routes.v2.messages(false, {
      origin: 'twilio',
    }))
    .set('Authorization', `Basic ${integrationHelper.getAuthKey()}`)
    .send(message);
  res.status.should.be.equal(200);
  res.body.data.messages.outbound[0].text.should.equal('These are Do Something Alerts - 4 messages/mo. Info help@dosomething.org or https://dosome.click/zt6mc. Txt STOP to quit. Msg&Data Rates May Apply.');
  res.body.data.messages.inbound[0].topic.should.equal(res.body.data.messages.outbound[0].topic);
});
<commit_msg>hardcodes what the topic should equal<commit_after>'use strict';

const test = require('ava');
const chai = require('chai');

const integrationHelper = require('../../../../helpers/integration');
const stubs = require('../../../../helpers/stubs');
const metadataParserConfig = require('../../../../../config/lib/middleware/metadata-parse');

chai.should();

test.before(async () => {
  await integrationHelper.hooks.db.connect();
});

test.beforeEach((t) => {
  integrationHelper.hooks.cache.broadcasts.set(
    stubs.getBroadcastId(),
    stubs.graphql.getBroadcastSingleResponse().data.broadcast,
  );
  integrationHelper.hooks.app(t.context);
});

test.afterEach(async () => {
  integrationHelper.hooks.interceptor.cleanAll();
  integrationHelper.hooks.cache.broadcasts.set(stubs.getBroadcastId(), null);
  await integrationHelper.hooks.db.messages.removeAll();
  await integrationHelper.hooks.db.conversations.removeAll();
});

test.after.always(async () => {
  await integrationHelper.hooks.db.disconnect();
});

/**
 * GET /
 */
test('GET /api/v2/messages should return 401 if not using valid credentials', async (t) => {
  const res = await t.context.request.get(integrationHelper.routes.v2.messages());
  res.status.should.be.equal(401);
});

test('GET /api/v2/messages should return 404', async (t) => {
  const res = await t.context.request.get(integrationHelper.routes.v2.messages())
    .set('Authorization', `Basic ${integrationHelper.getAuthKey()}`);
  res.status.should.be.equal(404);
});

test.serial('POST /api/v2/messages?origin=twilio should not re-send message to Twilio on retry', async (t) => {
  const member = stubs.northstar.getUser({ validUsNumber: true });
  const inboundRequestPayload = stubs.twilio.getInboundRequestBody(member);
  const requestId = stubs.getRequestId();

  integrationHelper.routes.graphql
    .intercept(stubs.graphql.fetchConversationTriggers(), 2);

  // mock user fetch twice
  integrationHelper.routes.northstar
    .intercept.fetchUserByMobile(inboundRequestPayload.From, member, 2);

  // mock user update twice
  integrationHelper.routes.northstar
    .intercept.updateUserById(member.data.id, member, 2);

  /**
   * 1st attempt
   */
  const res1 = await t.context.request
    .post(integrationHelper.routes.v2.messages(false, {
      origin: 'twilio',
    }))
    .set({
      Authorization: `Basic ${integrationHelper.getAuthKey()}`,
      [metadataParserConfig.metadata.headers.requestId]: requestId,
    })
    .send(inboundRequestPayload);

  res1.status.should.be.equal(200);
  res1.body.data.messages.inbound.length.should.be.equal(1);
  res1.body.data.messages.outbound.length.should.be.equal(1);

  const outboundMessage1 = res1.body.data.messages.outbound[0];

  /**
   * 2nd attempt (retry)
   */
  const res2 = await t.context.request
    .post(integrationHelper.routes.v2.messages(false, {
      origin: 'twilio',
    }))
    .set({
      Authorization: `Basic ${integrationHelper.getAuthKey()}`,
      [metadataParserConfig.metadata.headers.requestId]: requestId,
      [metadataParserConfig.metadata.headers.retryCount]: '1',
    })
    .send(inboundRequestPayload);

  res2.status.should.be.equal(200);
  res2.body.data.messages.inbound.length.should.be.equal(1);
  res2.body.data.messages.outbound.length.should.be.equal(1);

  const outboundMessage2 = res2.body.data.messages.outbound[0];

  // The retry should not have replaced the platformUserId of the message
  outboundMessage1.platformMessageId.should.be.equal(outboundMessage2.platformMessageId);
});

test('POST /api/v2/messages?origin=twilio outbound message should match sendInfoMessage if user texts INFO', async (t) => {
  const message = {
    getSmsMessageSid: stubs.twilio.getSmsMessageSid(),
    From: stubs.getMobileNumber('valid'),
    Body: 'info',
  };
  const member = stubs.northstar.getUser({
    validUsNumber: true,
  });

  integrationHelper.routes.graphql
    .intercept(stubs.graphql.fetchConversationTriggers(), 1);

  // mock user fetch
  integrationHelper.routes.northstar
    .intercept.fetchUserByMobile(message.From, member, 1);

  // mock user update
  integrationHelper.routes.northstar
    .intercept.updateUserById(member.data.id, member, 1);

  integrationHelper.routes.northstar
    .intercept.fetchUserById(stubs.getUserId(), member, 1);

  const res = await t.context.request
    .post(integrationHelper.routes.v2.messages(false, {
      origin: 'twilio',
    }))
    .set('Authorization', `Basic ${integrationHelper.getAuthKey()}`)
    .send(message);
  res.status.should.be.equal(200);
  res.body.data.messages.outbound[0].text.should.equal('These are Do Something Alerts - 4 messages/mo. Info help@dosomething.org or https://dosome.click/zt6mc. Txt STOP to quit. Msg&Data Rates May Apply.');
  res.body.data.messages.outbound[0].topic.should.equal('random');
});

test('POST /api/v2/messages?origin=twilio outbound message should match sendInfoMessage if user texts HELP', async (t) => {
  const message = {
    getSmsMessageSid: stubs.twilio.getSmsMessageSid(),
    From: stubs.getMobileNumber('valid'),
    Body: 'help',
  };
  const member = stubs.northstar.getUser({
    validUsNumber: true,
  });

  integrationHelper.routes.graphql
    .intercept(stubs.graphql.fetchConversationTriggers(), 1);

  // mock user fetch
  integrationHelper.routes.northstar
    .intercept.fetchUserByMobile(message.From, member, 1);

  // mock user update
  integrationHelper.routes.northstar
    .intercept.updateUserById(member.data.id, member, 1);

  integrationHelper.routes.northstar
    .intercept.fetchUserById(stubs.getUserId(), member, 1);

  const res = await t.context.request
    .post(integrationHelper.routes.v2.messages(false, {
      origin: 'twilio',
    }))
    .set('Authorization', `Basic ${integrationHelper.getAuthKey()}`)
    .send(message);
  res.status.should.be.equal(200);
  res.body.data.messages.outbound[0].text.should.equal('These are Do Something Alerts - 4 messages/mo. Info help@dosomething.org or https://dosome.click/zt6mc. Txt STOP to quit. Msg&Data Rates May Apply.');
  res.body.data.messages.outbound[0].topic.should.equal('random');
});
<|endoftext|>


<commit_before>export default function() {
    return [
        {
            "id" : "DFW",
            "name" : "DFW International Airport",
            "position" : {"lat":32.9222,"lng":-97.0409},
            "elevation" : "603",
            "runway-length" : "11388",
            "city" : "Dallas",
            "size" : "large"
        },
        {
            "id" : "DAL",
            "name" : "Dallas Love Field Airport",
            "position" : {"lat":32.8439,"lng":-96.8496},
            "elevation" : "487",
            "runway-length" : "8800",
            "city" : "Dallas",
            "size" : "medium"
        },
        {
            "id" : "AUS",
            "name" : "Austin-Bergstrom International Airport",
            "position" : {"lat":30.2027,"lng":-97.6653},
            "elevation" : "542",
            "runway-length" : "12248",
            "city" : "Austin",
            "size" : "medium"
        },
        {
            "id" : "IAH",
            "name" : "George Bush Intercontinental Airport",
            "position" : {"lat":29.9784,"lng":-95.3424},
            "elevation" : "98",
            "runway-length" : "12001",
            "city" : "Houston",
            "size" : "medium"
        },
        {
            "id" : "ADS",
            "name" : "Addison Airport",
            "position" : {"lat":32.968611,"lng":-96.836389},
            "elevation" : "644",
            "runway-length" : "7202",
            "city" : "Dallas",
            "size" : "small"
        }
    ];
}<commit_msg>locations<commit_after>export default function () {
  return [
    {
      "id": "DFW",
      "name": "DFW International Airport",
      "position": {"lat": 32.9222, "lng": -97.0409},
      "elevation": "603",
      "runway-length": "11388",
      "city": "Dallas",
      "attributes": ["dallas", "large"]
    },
    {
      "id": "DAL",
      "name": "Dallas Love Field Airport",
      "position": {"lat": 32.8439, "lng": -96.8496},
      "elevation": "487",
      "runway-length": "8800",
      "city": "Dallas",
      "attributes": ["dallas", "medium"]
    },
    {
      "id": "AUS",
      "name": "Austin-Bergstrom International Airport",
      "position": {"lat": 30.2027, "lng": -97.6653},
      "elevation": "542",
      "runway-length": "12248",
      "city": "Austin",
      "attributes": ["austin", "large"]
    },
    {
      "id": "IAH",
      "name": "George Bush Intercontinental Airport",
      "position": {"lat": 29.9784, "lng": -95.3424},
      "elevation": "98",
      "runway-length": "12001",
      "city": "Houston",
      "attributes": ["houston", "large"]
    },
    {
      "id": "ADS",
      "name": "Addison Airport",
      "position": {"lat": 32.968611, "lng": -96.836389},
      "elevation": "644",
      "runway-length": "7202",
      "city": "Dallas",
      "attributes": ["dallas", "small"]
    }
  ];
}<|endoftext|>


<commit_before>// FunStyleJS
'use strict';

if (typeof APP == 'undefined') {

  var APP = {};
  APP.Whocare = {};
  APP.IdoCare = {};
  APP.IdontCare = {};
}

var APP = APP || {}
<commit_msg>findLagestNumber function create<commit_after>// FunStyleJS
'use strict';

if (typeof App == 'undefined') {

  var App = {};
  App.Whocare = {};
  App.IdoCare = {};
  App.IdontCare = {};

  App.findLagestNumber = {

  };

}

var App = App || {}
<|endoftext|>


<commit_before>(function(){angular
  .module('app')
  .controller('FactoryController', FactoryController);

  FactoryController.$inject = ["output"];

  function FactoryController(output) {
    var vm = this;

    vm.codemirrorLoaded = codemirrorLoaded;
    vm.editorOptions = {
      lineWrapping : true,
      lineNumbers: true,
      mode: 'text/javascript',
    };

    ////////////

    function codemirrorLoaded(_editor) {
      _editor.setValue();
      output.factory = _editor.getValue();
      output.render();
      _editor.on('change', function(inst, changes) {
        output.factory = _editor.getValue();
        output.render();
      });
    }
  }
}());
<commit_msg>reorder complete, factory works<commit_after>(function(){angular
  .module('app')
  .controller('FactoryController', FactoryController);

  FactoryController.$inject = ["output"];

  function FactoryController(output) {
    var vm = this;

    vm.codemirrorLoaded = codemirrorLoaded;
    vm.editorOptions = {
      lineWrapping : true,
      lineNumbers: true,
      mode: 'text/javascript',
    };

    ////////////

    function codemirrorLoaded(_editor) {
      output.factory = _editor.getValue();
      output.render();
      _editor.on('change', function(inst, changes) {
        console.log('im here');
        output.factory = _editor.getValue();
        output.render();
      });
    }
  }
}());
<|endoftext|>


<commit_before>import {clientAddress, getHostFromHeaders} from '../../util/host'
import Util from '../../api/util'
import Hook from '../../util/hook'
import {pubsub} from '../../api/subscription'

export const trackUser = async ({req, event, slug, db, context, data, meta}) => {

    const ip = clientAddress(req)

    if (ip && ip !== '::1' && ip !== '::ffff:127.0.0.1' && ip !== '::ffff:144.91.119.30') {
        const host = getHostFromHeaders(req.headers)

        let referer
        if (meta) {

            try {
                const metaJson = JSON.parse(meta)
                referer = metaJson.referer
            } catch (e) {
                console.log(e)
            }
        }

        if (!referer) {
            referer = req.headers['referer']
        }

        const insertData = {
            ip: ip.replace('::ffff:', ''),
            agent: req.headers['user-agent'],
            referer,
            data,
            event,
            host: host,
            slug,
            createdBy: await Util.userOrAnonymousId(db, context)
        }

        Hook.call('tracking', {insertData, db, context})
        db.collection('UserTracking').insertOne(insertData).then(result => {
            insertData._id = result.insertedId
            if (insertData.data && insertData.data.constructor === Object) {
                insertData.data = JSON.stringify(result.insertedId)
            }

            // for real time tracking
            pubsub.publish('subscribeUserTracking', {
                userId: context.id,
                subscribeUserTracking: {action: 'create', data: [insertData]}
            })
        }).catch(err => {
            // handle error
        })

    }

}
<commit_msg>Small improvements<commit_after>import {clientAddress, getHostFromHeaders} from '../../util/host'
import Util from '../../api/util'
import Hook from '../../util/hook'
import {pubsub} from '../../api/subscription'

export const trackUser = async ({req, event, slug, db, context, data, meta}) => {

    const ip = clientAddress(req)

    if (ip && ip !== '::1' && ip !== '::ffff:127.0.0.1' && ip !== '::ffff:144.91.119.30') {
        const host = getHostFromHeaders(req.headers)

        let referer
        if (meta) {

            try {
                const metaJson = JSON.parse(meta)
                referer = metaJson.referer
            } catch (e) {
                console.log(e)
            }
        }

        if (!referer) {
            referer = ''//req.headers['referer']
        }

        const insertData = {
            ip: ip.replace('::ffff:', ''),
            agent: req.headers['user-agent'],
            referer,
            data,
            event,
            host: host,
            slug,
            createdBy: await Util.userOrAnonymousId(db, context)
        }

        Hook.call('tracking', {insertData, db, context})
        db.collection('UserTracking').insertOne(insertData).then(result => {
            insertData._id = result.insertedId
            if (insertData.data && insertData.data.constructor === Object) {
                insertData.data = JSON.stringify(result.insertedId)
            }

            // for real time tracking
            pubsub.publish('subscribeUserTracking', {
                userId: context.id,
                subscribeUserTracking: {action: 'create', data: [insertData]}
            })
        }).catch(err => {
            // handle error
        })

    }

}
<|endoftext|>