<commit_before>import * as ActionCreators from './action-creators'
import * as ActionTypes from './action-types'
import {request, response, fail, requiresAuth, isFeedResponse} from './action-helpers'

//middleware for api requests
export const apiMiddleware = store => next => async (action) => {
  //ignore normal actions
  if (!action.apiRequest){
    return next(action)
  }

  //dispatch request begin action
  //clean apiRequest to not get caught by this middleware
  var t = store.dispatch({...action, type: request(action.type), apiRequest: null})
  try {
    const apiResponse = await action.apiRequest(action.payload)
    const obj = await apiResponse.json()
    if (apiResponse.status === 200) {
      return store.dispatch({payload: obj, type: response(action.type), request: action.payload})
    } else if (apiResponse.status === 401) {
      return store.dispatch(ActionCreators.unauthenticated(obj))
    } else {
      return store.dispatch({payload: obj, type: fail(action.type), request: action.payload})
    }
  } catch (e) {
    return store.dispatch(ActionCreators.serverError(e))
  }
}

import {setToken, persistUser} from '../services/auth'
import {userParser, getCurrentRouteName} from '../utils'
import {pushState} from 'redux-router'

export const authMiddleware = store => next => action => {

  //stop action propagation if it should be authed and user is not authed
  if (requiresAuth(action) && !store.getState().authenticated) {
    return
  }

  if(action.type === ActionTypes.UNAUTHENTICATED) {
    setToken()
    persistUser()
    next(action)
    const routeName = getCurrentRouteName(store.getState().router)
    if (!routeName || ['signin', 'signup'].indexOf(routeName) !== -1){
      return
    }
    return store.dispatch(pushState(null, '/signin', {}))
  }

  if(action.type === response(ActionTypes.SIGN_IN) ||
     action.type === response(ActionTypes.SIGN_UP) ) {
    setToken(action.payload.authToken)
    next(action)
    store.dispatch(ActionCreators.whoAmI())
    return store.dispatch(pushState(null, '/', {}))
  }

  if(action.type === response(ActionTypes.WHO_AM_I) ||
     action.type === response(ActionTypes.UPDATE_USER) ) {
    persistUser(userParser(action.payload.users))
    return next(action)
  }

  return next(action)
}

export const likesLogicMiddleware = store => next => action => {
  switch(action.type){
    case ActionTypes.SHOW_MORE_LIKES: {
      const postId = action.payload.postId
      const post = store.getState().posts[postId]
      const isSync = (post.omittedLikes === 0)
      if (isSync) {
        return store.dispatch(ActionCreators.showMoreLikesSync(postId))
      } else {
        return store.dispatch(ActionCreators.showMoreLikesAsync(postId))
      }
    }
  }

  return next(action)
}

export const userPhotoLogicMiddleware = store => next => action => {
  if (action.type === response(ActionCreators.UPDATE_USER_PHOTO)) {
    //update data after new photo posted
    store.dispatch(whoAmI())
  }

  return next(action)
}

export const redirectionMiddleware = store => next => action => {
  //go to home if single post has been removed
  if (action.type === response(ActionCreators.DELETE_POST) && store.getState().singlePostId) {
    return store.dispatch(pushState(null, '/', {}))
  }

  return next(action)
}

export const scrollMiddleware = store => next => action => {
  if (isFeedResponse(action) || action.type === response(ActionCreators.GET_SINGLE_POST)){
    scrollTo(0, 0)
  }
  return next(action)
}
<commit_msg>Fix regression after refactoring<commit_after>import * as ActionCreators from './action-creators'
import * as ActionTypes from './action-types'
import {request, response, fail, requiresAuth, isFeedResponse} from './action-helpers'

//middleware for api requests
export const apiMiddleware = store => next => async (action) => {
  //ignore normal actions
  if (!action.apiRequest){
    return next(action)
  }

  //dispatch request begin action
  //clean apiRequest to not get caught by this middleware
  var t = store.dispatch({...action, type: request(action.type), apiRequest: null})
  try {
    const apiResponse = await action.apiRequest(action.payload)
    const obj = await apiResponse.json()
    if (apiResponse.status === 200) {
      return store.dispatch({payload: obj, type: response(action.type), request: action.payload})
    } else if (apiResponse.status === 401) {
      return store.dispatch(ActionCreators.unauthenticated(obj))
    } else {
      return store.dispatch({payload: obj, type: fail(action.type), request: action.payload})
    }
  } catch (e) {
    return store.dispatch(ActionCreators.serverError(e))
  }
}

import {setToken, persistUser} from '../services/auth'
import {userParser, getCurrentRouteName} from '../utils'
import {pushState} from 'redux-router'

export const authMiddleware = store => next => action => {

  //stop action propagation if it should be authed and user is not authed
  if (requiresAuth(action) && !store.getState().authenticated) {
    return
  }

  if(action.type === ActionTypes.UNAUTHENTICATED) {
    setToken()
    persistUser()
    next(action)
    const routeName = getCurrentRouteName(store.getState().router)
    if (!routeName || ['signin', 'signup'].indexOf(routeName) !== -1){
      return
    }
    return store.dispatch(pushState(null, '/signin', {}))
  }

  if(action.type === response(ActionTypes.SIGN_IN) ||
     action.type === response(ActionTypes.SIGN_UP) ) {
    setToken(action.payload.authToken)
    next(action)
    store.dispatch(ActionCreators.whoAmI())
    return store.dispatch(pushState(null, '/', {}))
  }

  if(action.type === response(ActionTypes.WHO_AM_I) ||
     action.type === response(ActionTypes.UPDATE_USER) ) {
    persistUser(userParser(action.payload.users))
    return next(action)
  }

  return next(action)
}

export const likesLogicMiddleware = store => next => action => {
  switch(action.type){
    case ActionTypes.SHOW_MORE_LIKES: {
      const postId = action.payload.postId
      const post = store.getState().posts[postId]
      const isSync = (post.omittedLikes === 0)
      if (isSync) {
        return store.dispatch(ActionCreators.showMoreLikesSync(postId))
      } else {
        return store.dispatch(ActionCreators.showMoreLikesAsync(postId))
      }
    }
  }

  return next(action)
}

export const userPhotoLogicMiddleware = store => next => action => {
  if (action.type === response(ActionTypes.UPDATE_USER_PHOTO)) {
    //update data after new photo posted
    store.dispatch(whoAmI())
  }

  return next(action)
}

export const redirectionMiddleware = store => next => action => {
  //go to home if single post has been removed
  if (action.type === response(ActionTypes.DELETE_POST) && store.getState().singlePostId) {
    return store.dispatch(pushState(null, '/', {}))
  }

  return next(action)
}

export const scrollMiddleware = store => next => action => {
  if (isFeedResponse(action) || action.type === response(ActionTypes.GET_SINGLE_POST)){
    scrollTo(0, 0)
  }
  return next(action)
}
<|endoftext|>


<commit_before>"use strict";
var chai        = require("chai"),
    moment      = require("moment-timezone"),
    Q           = require("q"),
    patients    = require("../../patients/common.js");
var expect = chai.expect;

// we're testing everything other than the controller logic and API functionality here
describe("Schedule", function () {
    describe("matches doses to a generated schedule and returns the expected output", function () {
        // setup test user with patient, in West Coast timzone
        var patient, tz;
        before(function () {
            tz = "America/Los_Angeles";
            return patients.testMyPatient({
                tz: tz
            }).then(function (p) {
                patient = p;
            });
        });

        // setup test medication for them with daily schedule
        var medication, doseTime, doseDelta;
        before(function () {
            // rather than fixing the time the medication is taken at
            // and stubbing the clock so we know what to expect, we have to
            // generate the schedule time based on the current time
            var now = moment.tz(tz);
            doseDelta = Math.floor(now.diff(moment(now).startOf("day")) / 2);
            doseTime = moment.tz(now - doseDelta, tz).format("hh:mm a");

            // console.log("MEDICATION");
            // console.log("Medication should be taken daily at %s local time", doseTime);
            // console.log("=> Dose Delta = %s hours", doseDelta / (60 * 60 * 1000));
            // console.log();

            return Q.nbind(patient.createMedication, patient)({
                name: "foo bar",
                schedule: {
                    as_needed: false,
                    regularly: true,
                    until: { type: "forever" },
                    frequency: { n: 1, unit: "day" },
                    times: [{ type: "exact", time: doseTime }],
                    take_with_food: null,
                    take_with_medications: [],
                    take_without_medications: []
                }
            }).then(function (m) {
                medication = m;
            });
        });

        // set the default notification offset to be 15 minutes
        before(function () {
            var timeId = medication.schedule.times[0]._id;
            return Q.nbind(medication.updateNotificationSettings, medication)(timeId, patient.user, {
                default: 15
            });
        });

        // setup a timeline: day1, day2, day3 and day4, each at the
        // start of their respective days
        // to be used in the rest of this test
        // day3 is today, where the scheduled dose event has already happened
        var day1, day2, day3, day4;
        before(function () {
            day3 = moment.tz(tz).startOf("day");
            day2 = moment(day3).subtract(1, "day");
            day1 = moment(day2).subtract(1, "day");
            day4 = moment(day3).add(1, "day");

            // console.log("TIMELINE");
            // console.log("Day 1: %s", day1.format());
            // console.log("Day 2: %s", day2.format());
            // console.log("Day 3: %s", day3.format());
            // console.log("Day 4: %s", day4.format());
            // console.log();
        });

        // create 5 dose events: one on day1, one on day2, one on day2, one outside
        // the given date range, and one superfluous dose representing
        // the user taking a medication "as needed"
        before(function () {
            // console.log("DOSES");
            /*var createDose = function (d) {
                return Q.nbind(patient.createDose, patient)(d).then(function (e) {
                    console.log("Dose %d at %s", e._id, d.date.format());
                });
            };*/
            var createDose = Q.nbind(patient.createDose, patient);
            return createDose({
                medication_id: medication._id,
                date: moment(moment.tz(day1, tz).startOf("day") + doseDelta),
                scheduled: medication.schedule.times[0]._id,
                taken: false
            }).then(function () {
                return createDose({
                    medication_id: medication._id,
                    date: moment(moment.tz(day2, tz).startOf("day") + doseDelta),
                    scheduled: medication.schedule.times[0]._id,
                    taken: true
                });
            }).then(function () {
                return createDose({
                    medication_id: medication._id,
                    date: moment(moment.tz(day3, tz).startOf("day") + doseDelta),
                    scheduled: medication.schedule.times[0]._id,
                    taken: true
                });
            }).then(function () {
                return createDose({
                    medication_id: medication._id,
                    date: moment.tz(day1, tz).subtract(2, "days").utc(),
                    scheduled: medication.schedule.times[0]._id,
                    taken: true
                });
            }).then(function () {
                return createDose({
                    medication_id: medication._id,
                    date: moment(moment.tz(day3, tz).startOf("day") + doseDelta),
                    scheduled: null,
                    taken: true
                });
            //}).then(function () {
                //console.log();
            });
        });

        // get the response from generating the overall schedule in the patient
        var start, end, schedule;
        before(function () {
            start = day1.format("YYYY-MM-DD");
            end = day4.format("YYYY-MM-DD");
            var generate = Q.nbind(patient.generateSchedule, patient);
            return generate(start, end, patient.user, medication._id, patient.user._id).then(function (s) {
                schedule = s;
            });
        });

        it("has the right keys", function () {
            expect(Object.keys(schedule)).to.deep.equal(["schedule", "statistics"]);
        });

        it("returns the right number of items", function () {
            expect(schedule.schedule.length).to.equal(5);
        });

        it("returns 'happened' keys correctly", function () {
            expect(schedule.schedule.filter(function (item) {
                return item.happened;
            }).length).to.equal(4);
        });

        it("returns 'took_medication' and associated keys correctly", function () {
            /*console.log("SCHEDULE");
            schedule.schedule.forEach(function (item) {
                console.log("Event %s. Happened: %s, Scheduled: %d, DoseID: %d, TookMed: %s", moment(item.date).format(), item.happened, item.scheduled, item.dose_id, item.took_medication);
            });
            console.log();*/

            expect(schedule.schedule.filter(function (item) {
                return item.took_medication;
            }).length).to.equal(3);
            expect(schedule.schedule.filter(function (item) {
                return typeof item.dose_id !== "undefined";
            }).length).to.equal(4);
            expect(schedule.schedule.filter(function (item) {
                return typeof item.delay !== "undefined";
            }).length).to.equal(2);

            expect(schedule.schedule.filter(function (item) {
                return item.happened && (typeof item.scheduled !== "undefined");
            }).length).to.equal(3);
            expect(schedule.schedule.filter(function (item) {
                return (!item.happened) && (typeof item.scheduled !== "undefined");
            }).length).to.equal(1);
        });

        it("generates notification times correctly", function () {
            schedule.schedule.forEach(function (item) {
                if (item.type !== "time") return;

                // check notification time is 15 mins before (the default notification
                // offset we set above) the event time
                expect(item).to.include.keys("date");
                if (typeof item.scheduled !== "undefined") {
                    expect(item).to.include.keys("notification");
                    expect(moment(item.date).diff(item.notification, "minutes")).to.equal(15);
                }
            });
        });

        describe("with a user-specific notification", function () {
            // set the user notification offset to be 15 minutes
            before(function () {
                var timeId = medication.schedule.times[0]._id;
                return Q.nbind(medication.updateNotificationSettings, medication)(timeId, patient.user, {
                    default: 20,
                    user: 10
                });
            });

            before(function () {
                var generate = Q.nbind(patient.generateSchedule, patient);
                return generate(start, end, patient.user, medication._id, patient.user._id).then(function (s) {
                    schedule = s;
                });
            });

            it("generates notification times correctly", function () {
                schedule.schedule.forEach(function (item) {
                    if (item.type !== "time") return;

                    // check notification time is 10 mins before (the notification time we set
                    // for just this user above) the event time
                    expect(item).to.include.keys("date");
                    if (typeof item.scheduled !== "undefined") {
                        expect(item).to.include.keys("notification");
                        expect(moment(item.date).diff(item.notification, "minutes")).to.equal(10);
                    }
                });
            });
        });

        it("calculates statistics correctly", function () {
            expect(schedule.statistics.took_medication).to.equal(100 * 2.0 / 3.0);
            expect(schedule.statistics.delay).to.equal(0);
            expect(schedule.statistics.delta).to.equal(0);
        });
    });
});
<commit_msg>Linting<commit_after>"use strict";
var chai        = require("chai"),
    moment      = require("moment-timezone"),
    Q           = require("q"),
    patients    = require("../../patients/common.js");
var expect = chai.expect;

// we're testing everything other than the controller logic and API functionality here
describe("Schedule", function () {
    describe("matches doses to a generated schedule and returns the expected output", function () {
        // setup test user with patient, in West Coast timzone
        var patient, tz;
        before(function () {
            tz = "America/Los_Angeles";
            return patients.testMyPatient({
                tz: tz
            }).then(function (p) {
                patient = p;
            });
        });

        // setup test medication for them with daily schedule
        var medication, doseTime, doseDelta;
        before(function () {
            // rather than fixing the time the medication is taken at
            // and stubbing the clock so we know what to expect, we have to
            // generate the schedule time based on the current time
            var now = moment.tz(tz);
            doseDelta = Math.floor(now.diff(moment(now).startOf("day")) / 2);
            doseTime = moment.tz(now - doseDelta, tz).format("hh:mm a");

            // console.log("MEDICATION");
            // console.log("Medication should be taken daily at %s local time", doseTime);
            // console.log("=> Dose Delta = %s hours", doseDelta / (60 * 60 * 1000));
            // console.log();

            return Q.nbind(patient.createMedication, patient)({
                name: "foo bar",
                schedule: {
                    as_needed: false,
                    regularly: true,
                    until: { type: "forever" },
                    frequency: { n: 1, unit: "day" },
                    times: [{ type: "exact", time: doseTime }],
                    take_with_food: null,
                    take_with_medications: [],
                    take_without_medications: []
                }
            }).then(function (m) {
                medication = m;
            });
        });

        // set the default notification offset to be 15 minutes
        before(function () {
            var timeId = medication.schedule.times[0]._id;
            return Q.nbind(medication.updateNotificationSettings, medication)(timeId, patient.user, {
                default: 15
            });
        });

        // setup a timeline: day1, day2, day3 and day4, each at the
        // start of their respective days
        // to be used in the rest of this test
        // day3 is today, where the scheduled dose event has already happened
        var day1, day2, day3, day4;
        before(function () {
            day3 = moment.tz(tz).startOf("day");
            day2 = moment(day3).subtract(1, "day");
            day1 = moment(day2).subtract(1, "day");
            day4 = moment(day3).add(1, "day");

            // console.log("TIMELINE");
            // console.log("Day 1: %s", day1.format());
            // console.log("Day 2: %s", day2.format());
            // console.log("Day 3: %s", day3.format());
            // console.log("Day 4: %s", day4.format());
            // console.log();
        });

        // create 5 dose events: one on day1, one on day2, one on day2, one outside
        // the given date range, and one superfluous dose representing
        // the user taking a medication "as needed"
        before(function () {
            // console.log("DOSES");
            /*var createDose = function (d) {
                return Q.nbind(patient.createDose, patient)(d).then(function (e) {
                    console.log("Dose %d at %s", e._id, d.date.format());
                });
            };*/
            var createDose = Q.nbind(patient.createDose, patient);
            return createDose({
                medication_id: medication._id,
                date: moment(moment.tz(day1, tz).startOf("day") + doseDelta),
                scheduled: medication.schedule.times[0]._id,
                taken: false
            }).then(function () {
                return createDose({
                    medication_id: medication._id,
                    date: moment(moment.tz(day2, tz).startOf("day") + doseDelta),
                    scheduled: medication.schedule.times[0]._id,
                    taken: true
                });
            }).then(function () {
                return createDose({
                    medication_id: medication._id,
                    date: moment(moment.tz(day3, tz).startOf("day") + doseDelta),
                    scheduled: medication.schedule.times[0]._id,
                    taken: true
                });
            }).then(function () {
                return createDose({
                    medication_id: medication._id,
                    date: moment.tz(day1, tz).subtract(2, "days").utc(),
                    scheduled: medication.schedule.times[0]._id,
                    taken: true
                });
            }).then(function () {
                return createDose({
                    medication_id: medication._id,
                    date: moment(moment.tz(day3, tz).startOf("day") + doseDelta),
                    scheduled: null,
                    taken: true
                });
            //}).then(function () {
                //console.log();
            });
        });

        // get the response from generating the overall schedule in the patient
        var start, end, schedule;
        before(function () {
            start = day1.format("YYYY-MM-DD");
            end = day4.format("YYYY-MM-DD");
            var generate = Q.nbind(patient.generateSchedule, patient);
            return generate(start, end, patient.user, medication._id, patient.user._id).then(function (s) {
                schedule = s;
            });
        });

        it("has the right keys", function () {
            expect(Object.keys(schedule)).to.deep.equal(["schedule", "statistics"]);
        });

        it("returns the right number of items", function () {
            expect(schedule.schedule.length).to.equal(5);
        });

        it("returns 'happened' keys correctly", function () {
            expect(schedule.schedule.filter(function (item) {
                return item.happened;
            }).length).to.equal(4);
        });

        it("returns 'took_medication' and associated keys correctly", function () {
            /*console.log("SCHEDULE");
            schedule.schedule.forEach(function (item) {
                console.log("Event %s. Happened: %s, Scheduled: %d, DoseID: %d, TookMed: %s",
                    moment(item.date).format(), item.happened, item.scheduled, item.dose_id, item.took_medication);
            });
            console.log();*/

            expect(schedule.schedule.filter(function (item) {
                return item.took_medication;
            }).length).to.equal(3);
            expect(schedule.schedule.filter(function (item) {
                return typeof item.dose_id !== "undefined";
            }).length).to.equal(4);
            expect(schedule.schedule.filter(function (item) {
                return typeof item.delay !== "undefined";
            }).length).to.equal(2);

            expect(schedule.schedule.filter(function (item) {
                return item.happened && (typeof item.scheduled !== "undefined");
            }).length).to.equal(3);
            expect(schedule.schedule.filter(function (item) {
                return (!item.happened) && (typeof item.scheduled !== "undefined");
            }).length).to.equal(1);
        });

        it("generates notification times correctly", function () {
            schedule.schedule.forEach(function (item) {
                if (item.type !== "time") return;

                // check notification time is 15 mins before (the default notification
                // offset we set above) the event time
                expect(item).to.include.keys("date");
                if (typeof item.scheduled !== "undefined") {
                    expect(item).to.include.keys("notification");
                    expect(moment(item.date).diff(item.notification, "minutes")).to.equal(15);
                }
            });
        });

        describe("with a user-specific notification", function () {
            // set the user notification offset to be 15 minutes
            before(function () {
                var timeId = medication.schedule.times[0]._id;
                return Q.nbind(medication.updateNotificationSettings, medication)(timeId, patient.user, {
                    default: 20,
                    user: 10
                });
            });

            before(function () {
                var generate = Q.nbind(patient.generateSchedule, patient);
                return generate(start, end, patient.user, medication._id, patient.user._id).then(function (s) {
                    schedule = s;
                });
            });

            it("generates notification times correctly", function () {
                schedule.schedule.forEach(function (item) {
                    if (item.type !== "time") return;

                    // check notification time is 10 mins before (the notification time we set
                    // for just this user above) the event time
                    expect(item).to.include.keys("date");
                    if (typeof item.scheduled !== "undefined") {
                        expect(item).to.include.keys("notification");
                        expect(moment(item.date).diff(item.notification, "minutes")).to.equal(10);
                    }
                });
            });
        });

        it("calculates statistics correctly", function () {
            expect(schedule.statistics.took_medication).to.equal(100 * 2.0 / 3.0);
            expect(schedule.statistics.delay).to.equal(0);
            expect(schedule.statistics.delta).to.equal(0);
        });
    });
});
<|endoftext|>


<commit_before>/**
 * Module dependencies.
 */

var express = require("express");
var app = express();
var paper = require('paper');
paper.setup(new paper.Canvas(1920, 1080));
var socket = require('socket.io');
var ueberDB = require("ueberDB");
var db = new ueberDB.database("dirty", {"filename" : "var/dirty.db"});
var async = require('async');
var fs = require('fs');

app.configure(function(){
  app.use(express.static(__dirname + '/'));
});

/**
 * A setting, just one
 */

var port = 3000;

/** Below be dragons
 *
 */

// SESSIONS
app.use(express.cookieParser());
app.use(express.session({secret: 'secret', key: 'express.sid'}));

// DEV MODE
app.configure('development', function(){
  app.use(express.errorHandler({ dumpExceptions: true, showStack: true }));
});

// PRODUCTON MODE
app.configure('production', function(){
  app.use(express.errorHandler());
});

// ROUTES
// Index page
app.get('/', function(req, res){
  res.sendfile(__dirname + '/src/static/html/index.html');
});

// Drawings
app.get('/d/*', function(req, res){
  res.sendfile(__dirname + '/src/static/html/draw.html');
});

// Front-end tests
app.get('/tests/frontend/specs_list.js', function(req, res){

  async.parallel({
    coreSpecs: function(callback){
      exports.getCoreTests(callback);
    },
    pluginSpecs: function(callback){
      exports.getPluginTests(callback);
    }
  },
  function(err, results){
    var files = results.coreSpecs; // push the core specs to a file object
    files = files.concat(results.pluginSpecs); // add the plugin Specs to the core specs
    //console.debug("Sent browser the following test specs:", files.sort());
    console.log("Sent browser the following test specs:", files.sort());
    res.send("var specs_list = " + JSON.stringify(files.sort()) + ";\n");
  });

});

// Used for front-end tests
var url2FilePath = function(url){
  var subPath = url.substr("/tests/frontend".length);
  if (subPath == ""){
    subPath = "index.html"
  }
  subPath = subPath.split("?")[0];

  var filePath = path.normalize(npm.root + "/../tests/frontend/")
  filePath += subPath.replace("..", "");
  return filePath;
}

// Used for front-end tests
app.get('/tests/frontend/specs/*', function (req, res) {
  var specFilePath = url2FilePath(req.url);
  var specFileName = path.basename(specFilePath);

  fs.readFile(specFilePath, function(err, content){
    if(err){ return res.send(500); }

    content = "describe(" + JSON.stringify(specFileName) + ", function(){   " + content + "   });";

    res.send(content);
  });
});

// Used for front-end tests
app.get('/tests/frontend/*', function (req, res) {
  var filePath = url2FilePath(req.url);
  res.sendfile(filePath);
});

// Used for front-end tests
app.get('/tests/frontend', function (req, res) {
  res.redirect('/tests/frontend/');
});

// Used for front-end tests
exports.getPluginTests = function(callback){
  var pluginSpecs = [];
  var plugins = fs.readdirSync('node_modules');
  plugins.forEach(function(plugin){
    if(fs.existsSync("node_modules/"+plugin+"/static/tests/frontend/specs")){ // if plugins exists
      var specFiles = fs.readdirSync("node_modules/"+plugin+"/static/tests/frontend/specs/");
      async.forEach(specFiles, function(spec){ // for each specFile push it to pluginSpecs
         pluginSpecs.push("/static/plugins/"+plugin+"/static/tests/frontend/specs/" + spec);
      },
      function(err){
         // blow up if something bad happens!
      });
    }
  });
  callback(null, pluginSpecs);
}

// Used for front-end tests
exports.getCoreTests = function(callback){
  fs.readdir('tests/frontend/specs', function(err, coreSpecs){ // get the core test specs
    if(err){ return res.send(500); }
    callback(null, coreSpecs);
  });
}

// Static files IE Javascript and CSS
app.use("/static", express.static(__dirname + '/src/static'));

// LISTEN FOR REQUESTS
var server = app.listen(port);
var io = socket.listen(server);

// SOCKET IO
io.sockets.on('connection', function (socket) {

  socket.on('disconnect', function () {
    disconnect(socket);
  });

  // EVENT: User stops drawing something
  // Having room as a parameter is not good for secure rooms
  socket.on('draw:progress', function (room, uid, co_ordinates) {
    if (!projects[room] || !projects[room].project) {
      loadError(socket);
      return;
    }
    io.sockets.in(room).emit('draw:progress', uid, co_ordinates);
    progress_external_path(room, JSON.parse(co_ordinates), uid);
  });

  // EVENT: User stops drawing something
  // Having room as a parameter is not good for secure rooms
  socket.on('draw:end', function (room, uid, co_ordinates) {
    if (!projects[room] || !projects[room].project) {
      loadError(socket);
      return;
    }
    io.sockets.in(room).emit('draw:end', uid, co_ordinates);
    end_external_path(room, JSON.parse(co_ordinates), uid);
  });

  // User joins a room
  socket.on('subscribe', function(data) {
    subscribe(socket, data);
  });

  // User clears canvas
  socket.on('canvas:clear', function(room) {
    if (!projects[room] || !projects[room].project) {
      loadError(socket);
      return;
    }
    clearCanvas(room);
    io.sockets.in(room).emit('canvas:clear');
  });

  // User removes an item
  socket.on('item:remove', function(room, uid, itemName) {
    removeItem(room, uid, itemName);
  });

  // User moves one or more items on their canvas - progress
  socket.on('item:move:progress', function(room, uid, itemNames, delta) {
    moveItemsProgress(room, uid, itemNames, delta);
  });

  // User moves one or more items on their canvas - end
  socket.on('item:move:end', function(room, uid, itemNames, delta) {
    moveItemsEnd(room, uid, itemNames, delta);
  });

  // User adds a raster image
  socket.on('image:add', function(room, uid, data, position, name) {
    addImage(room, uid, data, position, name);
  });

});

var projects = {};
var closeTimer = {}; // setTimeout function for closing a project when
// there are no active connections
// Subscribe a client to a room
function subscribe(socket, data) {
  var room = data.room;

  // Subscribe the client to the room
  socket.join(room);

  // If the close timer is set, cancel it
  if (closeTimer[room]) {
    clearTimeout(closeTimer[room]);
  }

  // Create Paperjs instance for this room if it doesn't exist
  var project = projects[room];
  if (!project) {
    projects[room] = {};
    projects[room].project = new paper.Project(paper.projects[0].view);
    projects[room].external_paths = {};
    loadFromDB(room, socket);
  } else { // Project exists in memory, no need to load from database
    loadFromMemory(room, socket);
  }

  // Broadcast to room the new user count
  var active_connections = io.sockets.manager.rooms['/' + room].length;
  io.sockets.in(room).emit('user:connect', active_connections);

}

// Try to load room from database
function loadFromDB(room, socket) {
  if (projects[room] && projects[room].project) {
    var project = projects[room].project;
    db.init(function (err) {
      if(err) {
        console.error(err);
      }
      db.get(room, function(err, value) {
        if (value && project && project instanceof paper.Project && project.activeLayer) {
          socket.emit('loading:start');
          // Clear default layer as importing JSON adds a new layer.
          // We want the project to always only have one layer.
          project.activeLayer.remove();
          project.importJSON(value.project);
          socket.emit('project:load', value);
        }
        socket.emit('loading:end');
        db.close(function(){});
      });
    });
  } else {
    loadError(socket);
  }
}

// Send current project to new client
function loadFromMemory(room, socket) {
  var project = projects[room].project;
  if (!project) { // Additional backup check, just in case
    loadFromDB(room, socket);
    return;
  }
  socket.emit('loading:start');
  var value = project.exportJSON();
  socket.emit('project:load', {project: value});
  socket.emit('loading:end');
}

// When a client disconnects, unsubscribe him from
// the rooms he subscribed to
function disconnect(socket) {
  // Get a list of rooms for the client
  var rooms = io.sockets.manager.roomClients[socket.id];

  // Unsubscribe from the rooms
  for(var room in rooms) {
    if(room && rooms[room]) {
      unsubscribe(socket, { room: room.replace('/','') });
    }
  }

}

// Unsubscribe a client from a room
function unsubscribe(socket, data) {
  var room = data.room;

  // Remove the client from socket.io room
  // This is optional for the disconnect event, we do it anyway
  // because we want to broadcast the new room population
  socket.leave(room);

  // Broadcast to room the new user count
  if (io.sockets.manager.rooms['/' + room]) {
    var active_connections = io.sockets.manager.rooms['/' + room].length;
    io.sockets.in(room).emit('user:disconnect', active_connections);
  } else {

    // Wait a few seconds before closing the project to finish pending writes to pad
    closeTimer[room] = setTimeout(function() {
      // Iff no one left in room, remove Paperjs instance
      // from the array to free up memory
      var project = projects[room].project;
      // All projects share one View, calling remove() on one project destroys the View
      // for all projects. Set to false first.
      project.view = false;
      project.remove();
      projects[room] = undefined;
    }, 5000);
  }

}

function loadError(socket) {
  socket.emit('project:load:error');
}

// Ends a path
var end_external_path = function (room, points, artist) {

  var project = projects[room].project;
  project.activate();
  var path = projects[room].external_paths[artist];

  if (path) {

    // Close the path
    path.add(new paper.Point(points.end[1], points.end[2]));
    path.closed = true;
    path.smooth();
    project.view.draw();

    // Remove the old data
    projects[room].external_paths[artist] = false;

  }

  writeProjectToDB(room);
};

// Continues to draw a path in real time
progress_external_path = function (room, points, artist) {

  var project = projects[room].project;
  project.activate();
  var path = projects[room].external_paths[artist];

  // The path hasn't already been started
  // So start it
  if (!path) {

    projects[room].external_paths[artist] = new paper.Path();
    path = projects[room].external_paths[artist];

    // Starts the path
    var start_point = new paper.Point(points.start[1], points.start[2]);
    var color = new paper.Color(points.rgba.red, points.rgba.green, points.rgba.blue, points.rgba.opacity);
    path.fillColor = color;
    path.name = points.name;
    path.add(start_point);

  }

  // Draw all the points along the length of the path
  var paths = points.path;
  var length = paths.length;
  for (var i = 0; i < length; i++) {

    path.add(new paper.Point(paths[i].top[1], paths[i].top[2]));
    path.insert(0, new paper.Point(paths[i].bottom[1], paths[i].bottom[2]));

  }

  path.smooth();

  project.view.draw();

};

function writeProjectToDB(room) {
  var project = projects[room].project;
  var json = project.exportJSON();
  db.init(function (err) {
    if(err) {
      console.error(err);
    }
    db.set(room, {project: json});
  });
}

function clearCanvas(room) {
  var project = projects[room].project;

  if (project && project.activeLayer && project.activeLayer.hasChildren()) {
    // Remove all but the active layer
    if (project.layers.length > 1) {
      var activeLayerID = project.activeLayer._id;
      for (var i=0; i<project.layers.length; i++) {
        if (project.layers[i]._id != activeLayerID) {
          project.layers[i].remove();
          i--;
        }
      }
    }
    // Remove all of the children from the active layer
    if (paper.project.activeLayer && paper.project.activeLayer.hasChildren()) {
      paper.project.activeLayer.removeChildren();
    }
    writeProjectToDB(room);
  }
}

// Remove an item from the canvas
function removeItem(room, artist, itemName) {
  var project = projects[room].project;
  if (project && project.activeLayer && project.activeLayer._namedChildren[itemName] && project.activeLayer._namedChildren[itemName][0]) {
    project.activeLayer._namedChildren[itemName][0].remove();
    io.sockets.in(room).emit('item:remove', artist, itemName);
    writeProjectToDB(room);
  }
}

// Move one or more existing items on the canvas
function moveItemsProgress(room, artist, itemNames, delta) {
  var project = projects[room].project;
  if (project && project.activeLayer) {
    for (x in itemNames) {
      var itemName = itemNames[x];
      var namedChildren = project.activeLayer._namedChildren;
      if (namedChildren && namedChildren[itemName] && namedChildren[itemName][0]) {
        project.activeLayer._namedChildren[itemName][0].position.x += delta[1];
        project.activeLayer._namedChildren[itemName][0].position.y += delta[2];
      }
    }
    if (itemNames) {
      io.sockets.in(room).emit('item:move', artist, itemNames, delta);
    }
  }
}

// Move one or more existing items on the canvas
// and write to DB
function moveItemsEnd(room, artist, itemNames, delta) {
  var project = projects[room].project;
  if (project && project.activeLayer) {
    for (x in itemNames) {
      var itemName = itemNames[x];
      var namedChildren = project.activeLayer._namedChildren;
      if (namedChildren && namedChildren[itemName] && namedChildren[itemName][0]) {
        project.activeLayer._namedChildren[itemName][0].position.x += delta[1];
        project.activeLayer._namedChildren[itemName][0].position.y += delta[2];
      }
    }
    if (itemNames) {
      io.sockets.in(room).emit('item:move', artist, itemNames, delta);
    }
    writeProjectToDB(room);
  }
}

// Add image to canvas
function addImage(room, artist, data, position, name) {
  var project = projects[room].project;
  if (project && project.activeLayer) {
    var image = JSON.parse(data);
    var raster = new paper.Raster(image);
    raster.position = new paper.Point(position[1], position[2]);
    raster.name = name;
    io.sockets.in(room).emit('image:add', artist, data, position, name);
    writeProjectToDB(room);
  }
}<commit_msg>Added comment<commit_after>/**
 * Module dependencies.
 */

var express = require("express");
var app = express();
var paper = require('paper');
paper.setup(new paper.Canvas(1920, 1080));
var socket = require('socket.io');
var ueberDB = require("ueberDB");
var db = new ueberDB.database("dirty", {"filename" : "var/dirty.db"});
var async = require('async');
var fs = require('fs');

app.configure(function(){
  app.use(express.static(__dirname + '/'));
});

/**
 * A setting, just one
 */

var port = 3000;

/** Below be dragons
 *
 */

// SESSIONS
app.use(express.cookieParser());
app.use(express.session({secret: 'secret', key: 'express.sid'}));

// DEV MODE
app.configure('development', function(){
  app.use(express.errorHandler({ dumpExceptions: true, showStack: true }));
});

// PRODUCTON MODE
app.configure('production', function(){
  app.use(express.errorHandler());
});

// ROUTES
// Index page
app.get('/', function(req, res){
  res.sendfile(__dirname + '/src/static/html/index.html');
});

// Drawings
app.get('/d/*', function(req, res){
  res.sendfile(__dirname + '/src/static/html/draw.html');
});

// Front-end tests
app.get('/tests/frontend/specs_list.js', function(req, res){

  async.parallel({
    coreSpecs: function(callback){
      exports.getCoreTests(callback);
    },
    pluginSpecs: function(callback){
      exports.getPluginTests(callback);
    }
  },
  function(err, results){
    var files = results.coreSpecs; // push the core specs to a file object
    files = files.concat(results.pluginSpecs); // add the plugin Specs to the core specs
    //console.debug("Sent browser the following test specs:", files.sort());
    console.log("Sent browser the following test specs:", files.sort());
    res.send("var specs_list = " + JSON.stringify(files.sort()) + ";\n");
  });

});

// Used for front-end tests
var url2FilePath = function(url){
  var subPath = url.substr("/tests/frontend".length);
  if (subPath == ""){
    subPath = "index.html"
  }
  subPath = subPath.split("?")[0];

  var filePath = path.normalize(npm.root + "/../tests/frontend/")
  filePath += subPath.replace("..", "");
  return filePath;
}

// Used for front-end tests
app.get('/tests/frontend/specs/*', function (req, res) {
  var specFilePath = url2FilePath(req.url);
  var specFileName = path.basename(specFilePath);

  fs.readFile(specFilePath, function(err, content){
    if(err){ return res.send(500); }

    content = "describe(" + JSON.stringify(specFileName) + ", function(){   " + content + "   });";

    res.send(content);
  });
});

// Used for front-end tests
app.get('/tests/frontend/*', function (req, res) {
  var filePath = url2FilePath(req.url);
  res.sendfile(filePath);
});

// Used for front-end tests
app.get('/tests/frontend', function (req, res) {
  res.redirect('/tests/frontend/');
});

// Used for front-end tests
exports.getPluginTests = function(callback){
  var pluginSpecs = [];
  var plugins = fs.readdirSync('node_modules');
  plugins.forEach(function(plugin){
    if(fs.existsSync("node_modules/"+plugin+"/static/tests/frontend/specs")){ // if plugins exists
      var specFiles = fs.readdirSync("node_modules/"+plugin+"/static/tests/frontend/specs/");
      async.forEach(specFiles, function(spec){ // for each specFile push it to pluginSpecs
         pluginSpecs.push("/static/plugins/"+plugin+"/static/tests/frontend/specs/" + spec);
      },
      function(err){
         // blow up if something bad happens!
      });
    }
  });
  callback(null, pluginSpecs);
}

// Used for front-end tests
exports.getCoreTests = function(callback){
  fs.readdir('tests/frontend/specs', function(err, coreSpecs){ // get the core test specs
    if(err){ return res.send(500); }
    callback(null, coreSpecs);
  });
}

// Static files IE Javascript and CSS
app.use("/static", express.static(__dirname + '/src/static'));

// LISTEN FOR REQUESTS
var server = app.listen(port);
var io = socket.listen(server);

// SOCKET IO
io.sockets.on('connection', function (socket) {

  socket.on('disconnect', function () {
    disconnect(socket);
  });

  // EVENT: User stops drawing something
  // Having room as a parameter is not good for secure rooms
  socket.on('draw:progress', function (room, uid, co_ordinates) {
    if (!projects[room] || !projects[room].project) {
      loadError(socket);
      return;
    }
    io.sockets.in(room).emit('draw:progress', uid, co_ordinates);
    progress_external_path(room, JSON.parse(co_ordinates), uid);
  });

  // EVENT: User stops drawing something
  // Having room as a parameter is not good for secure rooms
  socket.on('draw:end', function (room, uid, co_ordinates) {
    if (!projects[room] || !projects[room].project) {
      loadError(socket);
      return;
    }
    io.sockets.in(room).emit('draw:end', uid, co_ordinates);
    end_external_path(room, JSON.parse(co_ordinates), uid);
  });

  // User joins a room
  socket.on('subscribe', function(data) {
    subscribe(socket, data);
  });

  // User clears canvas
  socket.on('canvas:clear', function(room) {
    if (!projects[room] || !projects[room].project) {
      loadError(socket);
      return;
    }
    clearCanvas(room);
    io.sockets.in(room).emit('canvas:clear');
  });

  // User removes an item
  socket.on('item:remove', function(room, uid, itemName) {
    removeItem(room, uid, itemName);
  });

  // User moves one or more items on their canvas - progress
  socket.on('item:move:progress', function(room, uid, itemNames, delta) {
    moveItemsProgress(room, uid, itemNames, delta);
  });

  // User moves one or more items on their canvas - end
  socket.on('item:move:end', function(room, uid, itemNames, delta) {
    moveItemsEnd(room, uid, itemNames, delta);
  });

  // User adds a raster image
  socket.on('image:add', function(room, uid, data, position, name) {
    addImage(room, uid, data, position, name);
  });

});

var projects = {};
var closeTimer = {}; // setTimeout function for closing a project when
// there are no active connections
// Subscribe a client to a room
function subscribe(socket, data) {
  var room = data.room;

  // Subscribe the client to the room
  socket.join(room);

  // If the close timer is set, cancel it
  if (closeTimer[room]) {
    clearTimeout(closeTimer[room]);
  }

  // Create Paperjs instance for this room if it doesn't exist
  var project = projects[room];
  if (!project) {
    projects[room] = {};
    // Use the view from the default project. This project is the default
    // one created when paper is instantiated. Nothing is ever written to
    // this project as each room has its own project. We share the View
    // object but that just helps it "draw" stuff to the invisible server
    // canvas.
    projects[room].project = new paper.Project(paper.projects[0].view);
    projects[room].external_paths = {};
    loadFromDB(room, socket);
  } else { // Project exists in memory, no need to load from database
    loadFromMemory(room, socket);
  }

  // Broadcast to room the new user count
  var active_connections = io.sockets.manager.rooms['/' + room].length;
  io.sockets.in(room).emit('user:connect', active_connections);

}

// Try to load room from database
function loadFromDB(room, socket) {
  if (projects[room] && projects[room].project) {
    var project = projects[room].project;
    db.init(function (err) {
      if(err) {
        console.error(err);
      }
      db.get(room, function(err, value) {
        if (value && project && project instanceof paper.Project && project.activeLayer) {
          socket.emit('loading:start');
          // Clear default layer as importing JSON adds a new layer.
          // We want the project to always only have one layer.
          project.activeLayer.remove();
          project.importJSON(value.project);
          socket.emit('project:load', value);
        }
        socket.emit('loading:end');
        db.close(function(){});
      });
    });
  } else {
    loadError(socket);
  }
}

// Send current project to new client
function loadFromMemory(room, socket) {
  var project = projects[room].project;
  if (!project) { // Additional backup check, just in case
    loadFromDB(room, socket);
    return;
  }
  socket.emit('loading:start');
  var value = project.exportJSON();
  socket.emit('project:load', {project: value});
  socket.emit('loading:end');
}

// When a client disconnects, unsubscribe him from
// the rooms he subscribed to
function disconnect(socket) {
  // Get a list of rooms for the client
  var rooms = io.sockets.manager.roomClients[socket.id];

  // Unsubscribe from the rooms
  for(var room in rooms) {
    if(room && rooms[room]) {
      unsubscribe(socket, { room: room.replace('/','') });
    }
  }

}

// Unsubscribe a client from a room
function unsubscribe(socket, data) {
  var room = data.room;

  // Remove the client from socket.io room
  // This is optional for the disconnect event, we do it anyway
  // because we want to broadcast the new room population
  socket.leave(room);

  // Broadcast to room the new user count
  if (io.sockets.manager.rooms['/' + room]) {
    var active_connections = io.sockets.manager.rooms['/' + room].length;
    io.sockets.in(room).emit('user:disconnect', active_connections);
  } else {

    // Wait a few seconds before closing the project to finish pending writes to pad
    closeTimer[room] = setTimeout(function() {
      // Iff no one left in room, remove Paperjs instance
      // from the array to free up memory
      var project = projects[room].project;
      // All projects share one View, calling remove() on one project destroys the View
      // for all projects. Set to false first.
      project.view = false;
      project.remove();
      projects[room] = undefined;
    }, 5000);
  }

}

function loadError(socket) {
  socket.emit('project:load:error');
}

// Ends a path
var end_external_path = function (room, points, artist) {

  var project = projects[room].project;
  project.activate();
  var path = projects[room].external_paths[artist];

  if (path) {

    // Close the path
    path.add(new paper.Point(points.end[1], points.end[2]));
    path.closed = true;
    path.smooth();
    project.view.draw();

    // Remove the old data
    projects[room].external_paths[artist] = false;

  }

  writeProjectToDB(room);
};

// Continues to draw a path in real time
progress_external_path = function (room, points, artist) {

  var project = projects[room].project;
  project.activate();
  var path = projects[room].external_paths[artist];

  // The path hasn't already been started
  // So start it
  if (!path) {

    projects[room].external_paths[artist] = new paper.Path();
    path = projects[room].external_paths[artist];

    // Starts the path
    var start_point = new paper.Point(points.start[1], points.start[2]);
    var color = new paper.Color(points.rgba.red, points.rgba.green, points.rgba.blue, points.rgba.opacity);
    path.fillColor = color;
    path.name = points.name;
    path.add(start_point);

  }

  // Draw all the points along the length of the path
  var paths = points.path;
  var length = paths.length;
  for (var i = 0; i < length; i++) {

    path.add(new paper.Point(paths[i].top[1], paths[i].top[2]));
    path.insert(0, new paper.Point(paths[i].bottom[1], paths[i].bottom[2]));

  }

  path.smooth();
  project.view.draw();

};

function writeProjectToDB(room) {
  var project = projects[room].project;
  var json = project.exportJSON();
  db.init(function (err) {
    if(err) {
      console.error(err);
    }
    db.set(room, {project: json});
  });
}

function clearCanvas(room) {
  var project = projects[room].project;

  if (project && project.activeLayer && project.activeLayer.hasChildren()) {
    // Remove all but the active layer
    if (project.layers.length > 1) {
      var activeLayerID = project.activeLayer._id;
      for (var i=0; i<project.layers.length; i++) {
        if (project.layers[i]._id != activeLayerID) {
          project.layers[i].remove();
          i--;
        }
      }
    }
    // Remove all of the children from the active layer
    if (paper.project.activeLayer && paper.project.activeLayer.hasChildren()) {
      paper.project.activeLayer.removeChildren();
    }
    writeProjectToDB(room);
  }
}

// Remove an item from the canvas
function removeItem(room, artist, itemName) {
  var project = projects[room].project;
  if (project && project.activeLayer && project.activeLayer._namedChildren[itemName] && project.activeLayer._namedChildren[itemName][0]) {
    project.activeLayer._namedChildren[itemName][0].remove();
    io.sockets.in(room).emit('item:remove', artist, itemName);
    writeProjectToDB(room);
  }
}

// Move one or more existing items on the canvas
function moveItemsProgress(room, artist, itemNames, delta) {
  var project = projects[room].project;
  if (project && project.activeLayer) {
    for (x in itemNames) {
      var itemName = itemNames[x];
      var namedChildren = project.activeLayer._namedChildren;
      if (namedChildren && namedChildren[itemName] && namedChildren[itemName][0]) {
        project.activeLayer._namedChildren[itemName][0].position.x += delta[1];
        project.activeLayer._namedChildren[itemName][0].position.y += delta[2];
      }
    }
    if (itemNames) {
      io.sockets.in(room).emit('item:move', artist, itemNames, delta);
    }
  }
}

// Move one or more existing items on the canvas
// and write to DB
function moveItemsEnd(room, artist, itemNames, delta) {
  var project = projects[room].project;
  if (project && project.activeLayer) {
    for (x in itemNames) {
      var itemName = itemNames[x];
      var namedChildren = project.activeLayer._namedChildren;
      if (namedChildren && namedChildren[itemName] && namedChildren[itemName][0]) {
        project.activeLayer._namedChildren[itemName][0].position.x += delta[1];
        project.activeLayer._namedChildren[itemName][0].position.y += delta[2];
      }
    }
    if (itemNames) {
      io.sockets.in(room).emit('item:move', artist, itemNames, delta);
    }
    writeProjectToDB(room);
  }
}

// Add image to canvas
function addImage(room, artist, data, position, name) {
  var project = projects[room].project;
  if (project && project.activeLayer) {
    var image = JSON.parse(data);
    var raster = new paper.Raster(image);
    raster.position = new paper.Point(position[1], position[2]);
    raster.name = name;
    io.sockets.in(room).emit('image:add', artist, data, position, name);
    writeProjectToDB(room);
  }
}<|endoftext|>


<commit_before>'use strict';

(function () {
  var editorHasFocus = false;
  var commandIsActive = false;
  var EVENT_NAMES = {
    ALL_IDS_COMPLETE: 'allIdsComplete'
  };

  CKEDITOR.plugins.add('autoid', {
    init: function (editor) {
      var self = this;

      editor.addFeature({
        allowedContent: 'h1 h2 h3 h4 h5 h6; *[id]'
      });

      if (editor && !editor.config.autoid) {
        editor.config.autoid = {};
      }
      self.settings = editor.config.autoid;
      if (!self.settings) {
        self.settings = {};
      }

      editor.addCommand('autoid', {
        exec: function (editor) {
          if (!commandIsActive) {
            start();
          } else {
            stop();
          }
        },
        editorFocus: true
      });

      editor.on("instanceReady", function () {
        if (self.settings.autostart !== false) {
          start()
        }
      });

      function start() {
        editor.getCommand('autoid').setState(CKEDITOR.TRISTATE_ON);
        commandIsActive = true;

        addAllIds();
      }

      function stop() {
        editor.getCommand('autoid').setState(CKEDITOR.TRISTATE_OFF);
        commandIsActive = false;
      }

      function addAllIds() {
        var headings = findAllHeadings(),
        i, heading;

        for (i = 0; i < headings.count(); i++) {
          heading = headings.getItem(i);
          if (heading.hasAttribute('id')) {
            continue;
          }
          addId(heading);
        }
        editor.fire(EVENT_NAMES.ALL_IDS_COMPLETE);
      }

      function findAllHeadings() {
        return editor.document.find('h1, h2, h3, h4, h5, h6');
      }

      function addId(heading) {
        var uuid = CKEDITOR.tools.getUniqueId();
        heading.setAttributes({ id: uuid });
      }

    }
  });
})();
<commit_msg>Add event listener to check for new headings and add id<commit_after>'use strict';

(function () {
  var editorHasFocus = false;
  var commandIsActive = false;
  var EVENT_NAMES = {
    ALL_IDS_COMPLETE: 'allIdsComplete'
  };

  CKEDITOR.plugins.add('autoid', {
    init: function (editor) {
      var self = this;

      editor.addFeature({
        allowedContent: 'h1 h2 h3 h4 h5 h6; *[id]'
      });

      if (editor && !editor.config.autoid) {
        editor.config.autoid = {};
      }
      self.settings = editor.config.autoid;
      if (!self.settings) {
        self.settings = {};
      }

      editor.addCommand('autoid', {
        exec: function (editor) {
          if (!commandIsActive) {
            start();
          } else {
            stop();
          }
        },
        editorFocus: true
      });

      editor.on("instanceReady", function () {
        if (self.settings.autostart !== false) {
          start()
        }
      });

      editor.on('selectionChange', addIdIfNewHeading);

      function start() {
        editor.getCommand('autoid').setState(CKEDITOR.TRISTATE_ON);
        commandIsActive = true;

        addAllIds();
      }

      function stop() {
        editor.getCommand('autoid').setState(CKEDITOR.TRISTATE_OFF);
        commandIsActive = false;
      }

      function addAllIds() {
        var headings = findAllHeadings(),
        i, heading;

        for (i = 0; i < headings.count(); i++) {
          heading = headings.getItem(i);
          if (heading.hasAttribute('id')) {
            continue;
          }
          addId(heading);
        }
        editor.fire(EVENT_NAMES.ALL_IDS_COMPLETE);
      }

      function findAllHeadings() {
        return editor.document.find('h1, h2, h3, h4, h5, h6');
      }

      function addId(heading) {
        var uuid = CKEDITOR.tools.getUniqueId();
        heading.setAttributes({ id: uuid });
      }

      function addIdIfNewHeading() {
        var element = editor.getSelection().getStartElement();
        if (isHeading(element) && !element.hasAttribute('id')) {
          addId(element);
        }
      }

      function isHeading(element) {
        return element.is('h1', 'h2', 'h3', 'h4', 'h5', 'h6');
      }

    }
  });
})();
<|endoftext|>


<commit_before><commit_msg>updated to clear composing element dropdowns in chemical association form<commit_after><|endoftext|>


<commit_before>/**
 * require,angular bootstrap
 */
require.config({
    "paths": {
        "jquery": "libs/jquery/dist/jquery.min",
        "lodash": "libs/lodash/dist/lodash.min",
        "semantic-ui": "libs/semantic-ui/dist/semantic.min",
        "angular": "libs/angular/angular",
        "angular-ui-router": "libs/angular-ui-router/release/angular-ui-router",
        "common": "common/common",
        "restangular": "libs/restangular/dist/restangular.min",
        "home": "modules/home",
        "register": "modules/register"
    },
    "shim": {
        "angular": {
            "deps": ['jquery'],
            "exports": "angular"
        },
        "angular-ui-router": ['angular'],
        "restangular": {
            "deps": ['angular']
        },
        "semantic-ui": {
            "deps": ['jquery']
        }
    }
});
// load modules 所有的模块路由配置文件定义了模块
require(['angular', 'common'], function (angular, app) {
    // 配置路由不存在处理函数
    /*app.config(['$urlRouterProvider', function ($urlRouterProvider) {
        $urlRouterProvider.otherwise('/error');
    }]);*/
    app.config([ function () {
        console.log('app config',new Date().getTime());
    }]);
    app.run(['$rootScope', '$state', function ($rootScope, $state) {
        $rootScope.$on('$stateNotFound', function (event, unfoundState, from, fromParams) {
            event.preventDefault();
            $state.go('pageError');
        });
    }]);

    //TODO:app.configRouter([all modules ])

    app.configRouter('register/config');
    setTimeout(function () {
        app.requires = ['register'];
        angular.bootstrap(document.querySelector('html'), [app.name]);

    },100);
});<commit_msg>Update main.js<commit_after>/**
 * require,angular bootstrap
 */
require.config({
    "paths": {
        "jquery": "libs/jquery/dist/jquery.min",
        "lodash": "libs/lodash/dist/lodash.min",
        "semantic-ui": "libs/semantic-ui/dist/semantic.min",
        "angular": "libs/angular/angular",
        "angular-ui-router": "libs/angular-ui-router/release/angular-ui-router",
        "common": "common/common",
        "restangular": "libs/restangular/dist/restangular.min",
        "home": "modules/home",
        "register": "modules/register"
    },
    "shim": {
        "angular": {
            "deps": ['jquery'],
            "exports": "angular"
        },
        "angular-ui-router": ['angular'],
        "restangular": {
            "deps": ['angular']
        },
        "semantic-ui": {
            "deps": ['jquery']
        }
    }
});
// load modules 所有的模块路由配置文件定义了模块
require(['angular', 'common'], function (angular, app) {
    // 配置路由不存在处理函数
    /*app.config(['$urlRouterProvider', function ($urlRouterProvider) {
        $urlRouterProvider.otherwise('/error');
    }]);*/
    app.config([ function () {
        console.log('app config',new Date().getTime());
    }]);
    app.run(['$rootScope', '$state', function ($rootScope, $state) {
        $rootScope.$on('$stateNotFound', function (event, unfoundState, from, fromParams) {
            event.preventDefault();
            $state.go('pageError');
        });
    }]);

    //TODO:app.configRouter([all modules ])

    app.configRouter('register/config');
    setTimeout(function () {
        app.requires = ['register'];
        angular.bootstrap(document.querySelector('html'), [app.name]);

    },1000);
});
<|endoftext|>


<commit_before>
var misago = {};

if (!Element)
{
	// Garbage Collector, to prevent memory leaks in MSIE
	misago.garbage = [window, document.body];
	misago.garbageCollector = function()
	{
		for (var i=0, len=misago.garbage.length; i<len; i++)
		{
			var element = this.garbage[i];

			if (element.clearAttributes) {
				element.clearAttributes();
			}
			if (element.clearEvents) {
				element.clearEvents();
			}
			delete element;
			delete this.garbage[i];
		}
		delete misago.garbage;
	}
	window.attachEvent('onunload', misago.garbageCollector);

	// Emulates an Object Prototype
	misago.prototypeEmulator = function()
	{
		var Obj       = {};
		Obj.prototype = {};

		Obj.$extend = function(o)
		{
			if (!o.$extended)
			{
				misago.garbage.push(o);

				for (var method in Obj.prototype) {
					o[method] = Obj.prototype[method];
				}
				o.$extended = true;
			}
			return o;
		}
		return Obj;
	};

	// Emulates the Element DOM prototype
	var Element = new misago.prototypeEmulator();

	// Manually extends an element
	misago.extendElement = function(elm) {
		return Element.$extend(elm);
	}

	// Manually extends many elements
	misago.extendElements = function(elms)
	{
		var rs = [];
		for (var i=0, len=elms.length; i<len; i++) {
			rs[i] = Element.$extend(elms[i]);
		}
		return misago.nodeListEmulator(rs);
	}

	// Emulates a NodeList
	misago.nodeListEmulator = function(nodes)
	{
		this.length = nodes.length;
		this.item = function(i) {
			return nodes[i];
		}
	}

	// Makes document.createElement to extend the newly created element
	misago._MSIE_createElement = document.createElement;
	document.createElement = function(tagName)
	{
		var elm = misago._MSIE_createElement(tagName);
		return misago.extendElement(elm);
	}

	// Makes document.getElementById to return an extended element
	misago._MSIE_getElementById = document.getElementById;
	document.getElementById = function(id)
	{
		var elm = misago._MSIE_getElementById(id);
		return elm ? misago.extendElement(elm) : elm;
	}

	// Makes document.getElementsByTagName to return extended elements
	misago._MSIE_getElementsByTagName = document.getElementsByTagName;
	document.getElementsByTagName = function(id)
	{
		var elms = misago._MSIE_getElementsByTagName.call(this, id);
		if (elms.length) {
			return misago.extendElements(elms);
		}
		return elms;
	}

	// Makes elm.getElementsByTagName to return extended elements
	Element.prototype.getElementsByTagName = document.getElementsByTagName;
}
else
{
	// Compatibility layer for Standards Compliant Browsers
	misago.extendElement = function(elm) {
		return elm;
	}
}

/**
 * Shortcut for document.getElementsById, and will auto-extend the element in MSIE < 8.
 */
misago.$ = function(element)
{
	if (typeof element == 'string') {
		element = document.getElementById(element)
	}
	return misago.extendElement(element);
}

/**
 * Shortcut: $ => misago.$
 */
if (!window.$) {
	window.$ = misago.$;
}

<commit_msg>Added some browser sniffing<commit_after>
var misago = {};

// browser sniffing (might come handy)
misago.browser     = new (
	var ua = navigator.userAgent.toLowerCase();

	this.ie    = (window.VBArray);
	this.ie6   = (this.ie && document.implementation);
	this.ie7   = (this.ie && window.XMLHttpRequest);
	this.opera = (window.opera);
	this.gecko = (window.netscape && !this.opera);
	this.khtml = (ua.indexOf("safari") + 1 || ua.indexOf("konqueror") + 1);
)();

if (!Element)
{
	// Garbage Collector, to prevent memory leaks in MSIE
	misago.garbage = [window, document.body];
	misago.garbageCollector = function()
	{
		for (var i=0, len=misago.garbage.length; i<len; i++)
		{
			var element = this.garbage[i];

			if (element.clearAttributes) {
				element.clearAttributes();
			}
			if (element.clearEvents) {
				element.clearEvents();
			}
			delete element;
			delete this.garbage[i];
		}
		delete misago.garbage;
	}
	window.attachEvent('onunload', misago.garbageCollector);

	// Emulates an Object Prototype
	misago.prototypeEmulator = function()
	{
		var Obj       = {};
		Obj.prototype = {};

		Obj.$extend = function(o)
		{
			if (!o.$extended)
			{
				misago.garbage.push(o);

				for (var method in Obj.prototype) {
					o[method] = Obj.prototype[method];
				}
				o.$extended = true;
			}
			return o;
		}
		return Obj;
	};

	// Emulates the Element DOM prototype
	var Element = new misago.prototypeEmulator();

	// Manually extends an element
	misago.extendElement = function(elm) {
		return Element.$extend(elm);
	}

	// Manually extends many elements
	misago.extendElements = function(elms)
	{
		var rs = [];
		for (var i=0, len=elms.length; i<len; i++) {
			rs[i] = Element.$extend(elms[i]);
		}
		return misago.nodeListEmulator(rs);
	}

	// Emulates a NodeList
	misago.nodeListEmulator = function(nodes)
	{
		this.length = nodes.length;
		this.item = function(i) {
			return nodes[i];
		}
	}

	// Makes document.createElement to extend the newly created element
	misago._MSIE_createElement = document.createElement;
	document.createElement = function(tagName)
	{
		var elm = misago._MSIE_createElement(tagName);
		return misago.extendElement(elm);
	}

	// Makes document.getElementById to return an extended element
	misago._MSIE_getElementById = document.getElementById;
	document.getElementById = function(id)
	{
		var elm = misago._MSIE_getElementById(id);
		return elm ? misago.extendElement(elm) : elm;
	}

	// Makes document.getElementsByTagName to return extended elements
	misago._MSIE_getElementsByTagName = document.getElementsByTagName;
	document.getElementsByTagName = function(id)
	{
		var elms = misago._MSIE_getElementsByTagName.call(this, id);
		if (elms.length) {
			return misago.extendElements(elms);
		}
		return elms;
	}

	// Makes elm.getElementsByTagName to return extended elements
	Element.prototype.getElementsByTagName = document.getElementsByTagName;
}
else
{
	// Compatibility layer for Standards Compliant Browsers
	misago.extendElement = function(elm) {
		return elm;
	}
}

/// Shortcut for document.getElementsById, and will auto-extend the element in MSIE < 8.
misago.$ = function(element)
{
	if (typeof element == 'string') {
		element = document.getElementById(element)
	}
	return misago.extendElement(element);
}

/// Shortcut: $ => misago.$
if (!window.$) {
	window.$ = misago.$;
}

<|endoftext|>


<commit_before>import Component from '@ember/component';
import { classNames, layout } from '@ember-decorators/component';
import template from './template';
import { argument } from '@ember-decorators/argument';
import { assert } from '@ember/debug';
import { optional, type } from '@ember-decorators/argument/type';
import { ClosureAction } from '@ember-decorators/argument/types';

const MIN_THUMB_LENGTH = 15;
const COMPRESSION_MULTIPLIER = 3.1416;

@layout(template)
@classNames('VerticalScrollBar')
export default class VerticalScrollBar extends Component {
  @argument @type(optional('number')) contentHeight;
  @argument @type(optional('number')) scrollerHeight;
  @argument @type(ClosureAction) registerWithScrollView;

  _isScrolling = false;
  _scrollTop = 0;

  init() {
    super.init(...arguments);
    this.trackHeight = this.clientHeight;
  }

  didInsertElement(){
    this._super(...arguments);
    assert("vertical-scroll-bar has zero height (missing CSS?)", this.element.offsetHeight !== 0);
    this.trackHeight = this.element.offsetHeight;

    this.thumb = this.element.querySelector('[data-thumb]');
    this.updateThumbStyle();

    this.registerWithScrollView(this.updateScrollingParameters.bind(this));
  }

  updateScrollingParameters(isScrolling, scrollTop) {
    this._scrollTop = scrollTop;
    this._isScrolling = isScrolling;
    this.updateThumbStyle();
  }

  updateThumbStyle() {
    let { scrollerHeight, trackHeight, contentRatio, scrollTopRatio, _isScrolling, compressionFactor } = this;
    if (!scrollerHeight) {
      return;
    }
    let thumbHeight = contentRatio * trackHeight;

    let trackAreaScrollSize = trackHeight - thumbHeight
    // let maxThumbY = trackHeight - thumbHeight;
    let thumbY = scrollTopRatio * trackAreaScrollSize;
    let isAtMax = thumbY + thumbHeight >= trackHeight;
    // thumbHeight = Math.max(MIN_THUMB_LENGTH, thumbHeight * compressionFactor);
    thumbHeight = Math.max(MIN_THUMB_LENGTH, thumbHeight);
    if (isAtMax) {
      thumbY = trackHeight - thumbHeight;
    }
    if (thumbY < 0) {
      thumbY = 0;
    }
    // console.log({ _scrollTop: this._scrollTop, contentRatio, scrollTopRatio, compressionFactor });
    // thumbY = Math.min(maxThumbY, Math.max(0, thumbY));
    // if (this.scrollTopRatio < 0) {
    //   thumbY = 0;
    // } else if (this.contentRatio > 0.9) {
    //   thumbY = maxThumbY;
    // }
    // console.log({ thumbHeight, thumbY, trackHeight })
    let styleParts = {
      opacity: _isScrolling ? '1' : '0',
      height: `${thumbHeight}px`,
      transform: `translateY(${thumbY}px)`
    };
    Object.assign(this.thumb.style, styleParts);
  }

  get compressionFactor() {
    // when overscrolled, the thumb compresses
    if (this.scrollTopRatio < 0) {
      return (1 + (this.scrollTopRatio * COMPRESSION_MULTIPLIER));
    }
    if ((this.scrollTopRatio) > 1) {
      return 1 - ((this.scrollTopRatio - 1) * COMPRESSION_MULTIPLIER);
    }
    return 1;
  }

  get contentRatio() {
    let ratioBeforeOverscrollAdjustment = this.scrollerHeight / this.effectiveContentHeight;
    return this.scrollerHeight / (this.effectiveContentHeight + (this.overscrollAmount * (1/ratioBeforeOverscrollAdjustment)));
  }

  get effectiveContentHeight() {
    return Math.max(this.scrollerHeight + 1, this.contentHeight);
  }

  get scrollTopRatio() {
    return this._scrollTop / this.scrollAreaSize;
  }

  get overscrollAmount() {
    let scrollTop = this._scrollTop;
    if (scrollTop < 0) {
      return -scrollTop;
    } else if (scrollTop > this.scrollAreaSize) {
      return scrollTop - this.scrollAreaSize;
    }
    return 0;
  }

  get scrollAreaSize() {
    let size = this.effectiveContentHeight - this.scrollerHeight;
    // if (this._scrollTop < 0) {
    //   size = size + this._scrollTop;
    // } else if (this._scrollTop > this.contentHeight) {
    //   size = size - (this._scrollTop - this.contentHeight);
    // }
    return size;
  }
}
<commit_msg>Tidy up vertical scroll bar component<commit_after>import Component from '@ember/component';
import { classNames, layout } from '@ember-decorators/component';
import template from './template';
import { argument } from '@ember-decorators/argument';
import { assert } from '@ember/debug';
import { optional, type } from '@ember-decorators/argument/type';
import { ClosureAction } from '@ember-decorators/argument/types';

const MIN_THUMB_LENGTH = 15;

@layout(template)
@classNames('VerticalScrollBar')
export default class VerticalScrollBar extends Component {
  @argument @type(optional('number')) contentHeight;
  @argument @type(optional('number')) scrollerHeight;
  @argument @type(ClosureAction) registerWithScrollView;

  _isScrolling = false;
  _scrollTop = 0;

  init() {
    super.init(...arguments);
    this.trackHeight = this.clientHeight;
  }

  didInsertElement() {
    this._super(...arguments);
    assert(
      'vertical-scroll-bar has zero height (missing CSS?)',
      this.element.offsetHeight !== 0
    );

    this.trackHeight = this.element.offsetHeight;
    this.thumb = this.element.querySelector('[data-thumb]');
    this.updateThumbStyle();
    this.registerWithScrollView(this.updateScrollingParameters.bind(this));
  }

  updateScrollingParameters(isScrolling, scrollTop) {
    this._scrollTop = scrollTop;
    this._isScrolling = isScrolling;

    this.updateThumbStyle();
  }

  updateThumbStyle() {
    let { scrollerHeight, trackHeight, contentRatio, scrollTopRatio, _isScrolling } = this;
    if (!scrollerHeight) {
      return;
    }

    let thumbHeight = contentRatio * trackHeight;
    let trackAreaScrollSize = trackHeight - thumbHeight;
    let thumbY = scrollTopRatio * trackAreaScrollSize;
    let isAtMax = thumbY + thumbHeight >= trackHeight;
    thumbHeight = Math.max(MIN_THUMB_LENGTH, thumbHeight);

    if (isAtMax) {
      thumbY = trackHeight - thumbHeight;
    }

    if (thumbY < 0) {
      thumbY = 0;
    }

    Object.assign(this.thumb.style, {
      opacity: _isScrolling ? '1' : '0',
      height: `${thumbHeight}px`,
      transform: `translateY(${thumbY}px)`
    });
  }

  get contentRatio() {
    let ratioBeforeOverscrollAdjustment = this.scrollerHeight / this.effectiveContentHeight;
    return this.scrollerHeight / (this.effectiveContentHeight + (this.overscrollAmount * (1/ratioBeforeOverscrollAdjustment)));
  }

  get effectiveContentHeight() {
    return Math.max(this.scrollerHeight + 1, this.contentHeight);
  }

  get scrollTopRatio() {
    return this._scrollTop / this.scrollAreaSize;
  }

  get overscrollAmount() {
    let scrollTop = this._scrollTop;

    if (scrollTop < 0) {
      return -scrollTop;
    } else if (scrollTop > this.scrollAreaSize) {
      return scrollTop - this.scrollAreaSize;
    }
    return 0;
  }

  get scrollAreaSize() {
    return this.effectiveContentHeight - this.scrollerHeight;
  }
}
<|endoftext|>


<commit_before>import React from 'react';
import { renderToString } from 'react-dom/server';
import { Provider } from 'react-redux';
import Cookies from 'universal-cookie';
import { match, RouterContext } from 'react-router';
import { ReduxAsyncConnect, loadOnServer } from 'redux-async-connect'
import { syncHistoryWithStore } from 'react-router-redux';
import createHistory from 'react-router/lib/createMemoryHistory';

import * as Constant from '../../utils/constant';
import Html from '../../helpers/Html';
import APIClient from '../../helpers/APIClient';
import createStore from '../../store';
import routes from '../../routes';
import { loadCookieSync, isEmptyObject } from '../../containers/Login/module/login';

const serverRouterMiddleware = () => (req, res, next) => {
	if (__DEV__) {
		webpackIsomorphicTools.refresh();
	}

	const client = new APIClient();
	const memoryHistory = createHistory(req.originalUrl);
	const store = createStore(memoryHistory, client);
	if (!isEmptyObject(req.universalCookies.cookies)) {
		store.dispatch(loadCookieSync(req.universalCookies.get(Constant.USER_COOKIE)));
	}
	const history = syncHistoryWithStore(memoryHistory, store);
	match({ history, routes: routes(store), location: req.originalUrl }, (error, redirectLocation, renderProps) => {
    	if (error) {
      		res.status(500).send(error.message);
    	} else if (redirectLocation) {
      		res.redirect(302, redirectLocation.pathname + redirectLocation.search);
	    } else if (renderProps) {
			global.navigator = {userAgent: req.headers['user-agent']};
			loadOnServer({ ...renderProps, store, helpers: { client, serverSide: true }, filter: (item) => item.deferred }).then(() => {
				console.log(store.getState().hotdetail)
				const component = (
		    		<Provider store={store} key="provider">
		    			<ReduxAsyncConnect {...renderProps} />
		    		</Provider>
		    	);
				res.status(200).send('<!doctype html>\n' + renderToString(<Html component={component} store={store} assets={webpackIsomorphicTools.assets()} />));
			});
	    } else {
     		res.status(404).send('Not found');
	    }
	});
}
export default serverRouterMiddleware;
<commit_msg>注释掉了log<commit_after>import React from 'react';
import { renderToString } from 'react-dom/server';
import { Provider } from 'react-redux';
import Cookies from 'universal-cookie';
import { match, RouterContext } from 'react-router';
import { ReduxAsyncConnect, loadOnServer } from 'redux-async-connect'
import { syncHistoryWithStore } from 'react-router-redux';
import createHistory from 'react-router/lib/createMemoryHistory';

import * as Constant from '../../utils/constant';
import Html from '../../helpers/Html';
import APIClient from '../../helpers/APIClient';
import createStore from '../../store';
import routes from '../../routes';
import { loadCookieSync, isEmptyObject } from '../../containers/Login/module/login';

const serverRouterMiddleware = () => (req, res, next) => {
	if (__DEV__) {
		webpackIsomorphicTools.refresh();
	}

	const client = new APIClient();
	const memoryHistory = createHistory(req.originalUrl);
	const store = createStore(memoryHistory, client);
	if (!isEmptyObject(req.universalCookies.cookies)) {
		store.dispatch(loadCookieSync(req.universalCookies.get(Constant.USER_COOKIE)));
	}
	const history = syncHistoryWithStore(memoryHistory, store);
	match({ history, routes: routes(store), location: req.originalUrl }, (error, redirectLocation, renderProps) => {
    	if (error) {
      		res.status(500).send(error.message);
    	} else if (redirectLocation) {
      		res.redirect(302, redirectLocation.pathname + redirectLocation.search);
	    } else if (renderProps) {
			global.navigator = {userAgent: req.headers['user-agent']};
			loadOnServer({ ...renderProps, store, helpers: { client, serverSide: true }, filter: (item) => item.deferred }).then(() => {
				const component = (
		    		<Provider store={store} key="provider">
		    			<ReduxAsyncConnect {...renderProps} />
		    		</Provider>
		    	);
				res.status(200).send('<!doctype html>\n' + renderToString(<Html component={component} store={store} assets={webpackIsomorphicTools.assets()} />));
			});
	    } else {
     		res.status(404).send('Not found');
	    }
	});
}
export default serverRouterMiddleware;
<|endoftext|>


<commit_before>var i$putStr = (function() {
  var util = require('util');
  return function(s) {
    util.print(s);
  };
})();

var i$systemInfo = function(index) {
  var os = require('os')
    switch(index) {
      case 0:
        return "node";
      case 1:
        return os.platform();
    }
  return "";
}
<commit_msg>javascript: fix node warning for printing<commit_after>var i$putStr = (function() {
  var fs = require('fs');
  return function(s) {
    fs.write(1,s);
  };
})();

var i$systemInfo = function(index) {
  var os = require('os')
    switch(index) {
      case 0:
        return "node";
      case 1:
        return os.platform();
    }
  return "";
}
<|endoftext|>


<commit_before>var axios = require('axios');
var expect = require('chai').expect;
var createServer = require('http').createServer;

var MockAdapter = require('../src');

describe('MockAdapter(passThrough=true) tests (requires Node)', function() {
  var instance;
  var mock;
  var httpServer;
  var serverUrl;

  before('set up Node server', function() {
    return new Promise(function(resolve, reject) {
      httpServer = createServer(function(req, resp) {
        if (req.url === '/error') {
          resp.statusCode = 500;
          resp.end();
        } else {
          resp.statusCode = 200;
          // Reply with path minus leading /
          resp.end(req.url.slice(1), 'utf8');
        }
      })
      .listen(0, 'localhost', function() {
        serverUrl = 'http://localhost:' + httpServer.address().port;
        resolve();
      })
      .on('error', reject);
    });
  });

  beforeEach(function() {
    instance = axios.create({ baseURL: serverUrl });
    mock = new MockAdapter(instance, { passThrough: true });
  });

  it('allows normal mocking', function() {
    mock.onGet('/foo').reply(200, 'bar');

    return instance.get('/foo')
      .then(function(response) {
        expect(response.status).to.equal(200);
        expect(response.data).to.equal('bar');
      });
  });

  it('allows selective mocking', function() {
    mock.onGet('/foo').reply(200, 'bar');
    mock.onGet('/notFound').reply(200, 'found');

    return Promise.all([
      instance.get('/foo')
        .then(function(response) {
          expect(response.status).to.equal(200);
          expect(response.data).to.equal('bar');
        }),
      instance.get('/notFound')
        .then(function(response) {
          expect(response.status).to.equal(200);
          expect(response.data).to.equal('found');
        }),
      instance.get('/bar')
        .then(function(response) {
          expect(response.status).to.equal(200);
          expect(response.data).to.equal('bar');
        })
    ]);
  });

  it('handles errors correctly', function() {
    return instance.get('/error')
      .then(function() {
        throw new Error('ERROR');
      })
      .catch(function(error) {
        expect(error).to.have.deep.property('response.status', 500);
      });
  });
});
<commit_msg>Revert change to test<commit_after>var axios = require('axios');
var expect = require('chai').expect;
var createServer = require('http').createServer;

var MockAdapter = require('../src');

describe('MockAdapter(passThrough=true) tests (requires Node)', function() {
  var instance;
  var mock;
  var httpServer;
  var serverUrl;

  before('set up Node server', function() {
    return new Promise(function(resolve, reject) {
      httpServer = createServer(function(req, resp) {
        if (req.url === '/error') {
          resp.statusCode = 500;
          resp.end();
        } else {
          resp.statusCode = 200;
          // Reply with path minus leading /
          resp.end(req.url.slice(1), 'utf8');
        }
      })
      .listen(0, 'localhost', function() {
        serverUrl = 'http://localhost:' + httpServer.address().port;
        resolve();
      })
      .on('error', reject);
    });
  });

  beforeEach(function() {
    instance = axios.create({ baseURL: serverUrl });
    mock = new MockAdapter(instance, { passThrough: true });
  });

  it('allows normal mocking', function() {
    mock.onGet('/foo').reply(200, 'bar');

    return instance.get('/foo')
      .then(function(response) {
        expect(response.status).to.equal(200);
        expect(response.data).to.equal('bar');
      });
  });

  it('allows selective mocking', function() {
    mock.onGet('/foo').reply(200, 'bar');
    mock.onGet('/notFound').reply(200, 'found');

    return Promise.all([
      instance.get('/foo')
        .then(function(response) {
          expect(response.status).to.equal(200);
          expect(response.data).to.equal('bar');
        }),
      instance.get('/notFound')
        .then(function(response) {
          expect(response.status).to.equal(200);
          expect(response.data).to.equal('found');
        }),
      instance.get('/bar')
        .then(function(response) {
          expect(response.status).to.equal(200);
          expect(response.data).to.equal('bar');
        })
    ]);
  });

  it('handles errors correctly', function() {
    return instance.get('/error')
      .then(function() {
        // The server should've returned an error
        expect(false).to.equal(true);
      })
      .catch(function(error) {
        expect(error).to.have.deep.property('response.status', 500);
      });
  });
});
<|endoftext|>


<commit_before>var path = require('path'),
    fs = require('fs-extra'),
    async = require('async'),
    extend = require('extend'),
    multiGlob = require('multi-glob');

module.exports = {
    writeFiles: function(folder, files, locationMsg, doNotFreeMem, done) {
        if (typeof doNotFreeMem == 'function') {
            done = doNotFreeMem;
            doNotFreeMem = false;
        }
        var server = this;
        fs.mkdirs(folder, function(err) {
            if (err) {
                err = "error creating folder {0} on {1}\n{2}".format(folder, locationMsg, err);
                done(err);
            } else {
                files.length ? async.each(files, function(file, cb) {
                    var fileName = path.resolve(folder, path.basename(file.file));
                    file.file = fileName;
                    try {
                        var data = new Buffer(file.content.data, 'base64');
                        file.content ? fs.writeFile(fileName, data, {
                            encoding: 'binary'
                        }, function(err) {
                            !doNotFreeMem && delete file.content; //free server's memory with file's content
                            cb(err);
                        }) : cb(null);
                    } catch (e) {
                        cb(e);
                    }
                }, function(err) {
                    if (err) {
                        err = "error saving cordova build files to {0} on {1}\n{2}".format(folder, locationMsg, err);
                    }
                    done(err);
                }) : done(null);
            }
        });
    },
    freeMemFiles: function(files) {
        files.forEach(function(file) {
            delete file.content;
        });
    },
    readFiles: function(files, locationMsg, done) {
        files.length ? async.each(files, function(file, cb) {
            fs.readFile(file.file, {
                //encoding: 'binary',
            }, function(err, data) {
                if (!err) {
                    var buf = new Buffer(data);
                    file.content = {
                        data: buf.toString('base64')
                    };
                    var length = file.content.data.length;
                    global.bu = buf;
                }
                cb(err);
            });
        }, function(err) {
            if (err) {
                err = "error reading build input files on {0}\n{1}".format(locationMsg, err);
            }
            done(err);
        }) : done(null);
    },
    cleanLastFolders: function(keepLast, globsArray, done) {
        if (keepLast <= 0) {
            done();
        }
        multiGlob.glob(globsArray, function(err, paths) {
            if (err) {
                return done(err);
            }
            if (!paths.length) {
                return done();
            }

            async.map(paths, function(path, done) {
                fs.stat(path, function(err, stat) {
                    done(err, {path: path, stat: stat});
                });
            }, function(err, stats) {
                if (err) {
                    return done(err);
                }
                stats = stats.filter(function(stat) {
                    return stat.stat.isDirectory();
                });
                stats.sort(function(a, b) {
                    return b.stat.mtime - a.stat.mtime;
                });
                stats.splice(0, keepLast);
                async.each(stats, function(stat, cb) {
                    fs.remove(stat.path, cb);
                }, function(err) {
                    done(err, stats);
                });
            });
        });
    }
};<commit_msg>resolve basename conflict with windows server<commit_after>var path = require('path'),
    fs = require('fs-extra'),
    async = require('async'),
    extend = require('extend'),
    multiGlob = require('multi-glob');

module.exports = {
    writeFiles: function(folder, files, locationMsg, doNotFreeMem, done) {
        if (typeof doNotFreeMem == 'function') {
            done = doNotFreeMem;
            doNotFreeMem = false;
        }
        var server = this;
        fs.mkdirs(folder, function(err) {
            if (err) {
                err = "error creating folder {0} on {1}\n{2}".format(folder, locationMsg, err);
                done(err);
            } else {
                files.length ? async.each(files, function(file, cb) {
                    var basename = file.file.replace(/\\/g,'/').replace(/.*\//, '');
                    var fileName = path.resolve(folder, basename);
                    console.log(fileName);
                    file.file = fileName;
                    try {
                        var data = new Buffer(file.content.data, 'base64');
                        file.content ? fs.writeFile(fileName, data, {
                            encoding: 'binary'
                        }, function(err) {
                            !doNotFreeMem && delete file.content; //free server's memory with file's content
                            cb(err);
                        }) : cb(null);
                    } catch (e) {
                        cb(e);
                    }
                }, function(err) {
                    if (err) {
                        err = "error saving cordova build files to {0} on {1}\n{2}".format(folder, locationMsg, err);
                    }
                    done(err);
                }) : done(null);
            }
        });
    },
    freeMemFiles: function(files) {
        files.forEach(function(file) {
            delete file.content;
        });
    },
    readFiles: function(files, locationMsg, done) {
        files.length ? async.each(files, function(file, cb) {
            fs.readFile(file.file, {
                //encoding: 'binary',
            }, function(err, data) {
                if (!err) {
                    var buf = new Buffer(data);
                    file.content = {
                        data: buf.toString('base64')
                    };
                    var length = file.content.data.length;
                    global.bu = buf;
                }
                cb(err);
            });
        }, function(err) {
            if (err) {
                err = "error reading build input files on {0}\n{1}".format(locationMsg, err);
            }
            done(err);
        }) : done(null);
    },
    cleanLastFolders: function(keepLast, globsArray, done) {
        if (keepLast <= 0) {
            done();
        }
        multiGlob.glob(globsArray, function(err, paths) {
            if (err) {
                return done(err);
            }
            if (!paths.length) {
                return done();
            }

            async.map(paths, function(path, done) {
                fs.stat(path, function(err, stat) {
                    done(err, {path: path, stat: stat});
                });
            }, function(err, stats) {
                if (err) {
                    return done(err);
                }
                stats = stats.filter(function(stat) {
                    return stat.stat.isDirectory();
                });
                stats.sort(function(a, b) {
                    return b.stat.mtime - a.stat.mtime;
                });
                stats.splice(0, keepLast);
                async.each(stats, function(stat, cb) {
                    fs.remove(stat.path, cb);
                }, function(err) {
                    done(err, stats);
                });
            });
        });
    }
};<|endoftext|>