<commit_before>var methodsArray = [save, selectLabel, panTool];

function save() {
    alert("Impement save");
}

function panTool() {
    alert("Implement pan tool");
}

function selectLabel() {
    alert("Implement select label");
}

function render(dom) {
    methodsArray.forEach(method => {
        console.log(method.name)
    dom
        .getElementsByClassName(method.name)[0]
        .addEventListener('click', method);
})
    ;
}

// Uncomment before the deployment in Yandex.Toloka
/*
 exports.Task = extend(TolokaHandlebarsTask, function (options) {
 TolokaHandlebarsTask.call(this, options);
 }, {

 // Add listener to each button based on its class on start
 // appropriate class for each button should be added in html
 onRender: function() { render(this.getDOMElement()); },
 onDestroy: function () {
 //

 }
 });
 */

function extend(ParentClass, constructorFunction, prototypeHash) {
    constructorFunction = constructorFunction || function () {
        };
    prototypeHash = prototypeHash || {};
    if (ParentClass) {
        constructorFunction.prototype = Object.create(ParentClass.prototype);
    }
    for (var i in prototypeHash) {
        constructorFunction.prototype[i] = prototypeHash[i];
    }
    return constructorFunction;
}

// request data from JSON file
function loadJSON(callback) {
    var xobj = new XMLHttpRequest();
    xobj.overrideMimeType("application/json");
    xobj.open('GET', 'https://rawgit.com/innosoft-pro/label-them/LT-116/front/json/classesandparameters.json', true);
    xobj.onreadystatechange = function () {
        if (xobj.readyState == 4 && xobj.status == "200") {

            // .open will NOT return a value but simply returns undefined in async mode so use a callback
            callback(xobj.responseText);

        }
    };
    xobj.send(null);
}

function generateHTMLCodeForClassesAndParameters(dom) {
    // Call to function with anonymous callback
    loadJSON(function (response) {
        jsonresponse = JSON.parse(response);

        var html = [];

        var generalClassesNameTemplate = [];
        var classes = [];

        generalClassesNameTemplate.push('
');
        generalClassesNameTemplate.push(jsonresponse.generalClassesName);
        generalClassesNameTemplate.push(' Type');
        generalClassesNameTemplate.push('
');
        generalClassesNameTemplate = generalClassesNameTemplate.join("");

        classes.push("
");
        classes.push("<button class=\"btn btn-default dropdown-toggle\" type=\"button\" ");
        classes.push("id=\"dropdownMenu-Classes\" ");
        classes.push("data-toggle=\"dropdown\" aria-haspopup=\"true\" aria-expanded=\"true\">");
        classes.push(jsonresponse.generalClassesName);
        classes.push(' Type');
        classes.push("");
        classes.push("</button>");
        classes.push("
");

        jsonresponse.classes.forEach(function (obj) {
            classes.push("
");
            classes.push(obj);
            classes.push("
");
        });

        classes.push("
");
        classes.push("
");
        classes = classes.join("");

        html.push(generalClassesNameTemplate);
        html.push(classes);

        html = html.join("");

        dom.getElementById('classes-and-parameters').innerHTML += html;
    });
}<commit_msg>LT-117 Implemented display of parameters defined in JSON on GUI<commit_after>var methodsArray = [save, selectLabel, panTool];

function save() {
    alert("Impement save");
}

function panTool() {
    alert("Implement pan tool");
}

function selectLabel() {
    alert("Implement select label");
}

function render(dom) {
    methodsArray.forEach(method => {
        console.log(method.name)
    dom
        .getElementsByClassName(method.name)[0]
        .addEventListener('click', method);
})
    ;
}

// Uncomment before the deployment in Yandex.Toloka
/*
 exports.Task = extend(TolokaHandlebarsTask, function (options) {
 TolokaHandlebarsTask.call(this, options);
 }, {

 // Add listener to each button based on its class on start
 // appropriate class for each button should be added in html
 onRender: function() { render(this.getDOMElement()); },
 onDestroy: function () {
 //

 }
 });
 */

function extend(ParentClass, constructorFunction, prototypeHash) {
    constructorFunction = constructorFunction || function () {
        };
    prototypeHash = prototypeHash || {};
    if (ParentClass) {
        constructorFunction.prototype = Object.create(ParentClass.prototype);
    }
    for (var i in prototypeHash) {
        constructorFunction.prototype[i] = prototypeHash[i];
    }
    return constructorFunction;
}

// request data from JSON file
function loadJSON(callback) {
    var xobj = new XMLHttpRequest();
    xobj.overrideMimeType("application/json");
    xobj.open('GET', 'https://rawgit.com/innosoft-pro/label-them/LT-116/front/json/classesandparameters.json', true);
    xobj.onreadystatechange = function () {
        if (xobj.readyState == 4 && xobj.status == "200") {

            // .open will NOT return a value but simply returns undefined in async mode so use a callback
            callback(xobj.responseText);

        }
    };
    xobj.send(null);
}

function generateHTMLCodeForClassesAndParameters(dom) {
    // Call to function with anonymous callback
    loadJSON(function (response) {
        jsonresponse = JSON.parse(response);

        var html = [];

        var generalClassesNameTemplate = [];
        var classes = [];
        var parameters = [];

        generalClassesNameTemplate.push('
');
        generalClassesNameTemplate.push(jsonresponse.generalClassesName);
        generalClassesNameTemplate.push(' Type');
        generalClassesNameTemplate.push('
');
        generalClassesNameTemplate = generalClassesNameTemplate.join("");

        classes.push("
");
        classes.push("<button class=\"btn btn-default dropdown-toggle\" type=\"button\" ");
        classes.push("id=\"dropdownMenu-Classes\" ");
        classes.push("data-toggle=\"dropdown\" aria-haspopup=\"true\" aria-expanded=\"true\">");
        classes.push(jsonresponse.generalClassesName);
        classes.push(' Type');
        classes.push("");
        classes.push("</button>");
        classes.push("
");

        jsonresponse.classes.forEach(function (obj) {
            classes.push("
");
            classes.push(obj);
            classes.push("
");
        });

        classes.push("
");
        classes.push("
");
        classes = classes.join("");

        if (jsonresponse.parameters !== null) {
            var dropdownMenusCount = 0;
            parameters.push('<form>');
            jsonresponse.parameters.forEach(function (obj) {
                if (obj.type === "checkbox") {
                    parameters.push("
");
                    parameters.push("<input type=\"checkbox\" value=\"\">");
                    parameters.push(obj.name);
                    parameters.push("");
                    parameters.push("
");
                } else if (obj.type === "input-group") {
                    parameters.push("
");
                    parameters.push("");
                    parameters.push(obj.placeholder);
                    parameters.push("");
                    parameters.push("<input type=\"text\" class=\"form-control\" placeholder=\"");
                    parameters.push(obj.name);
                    parameters.push("\" aria-describedby=\"basic-addon1\">");
                    parameters.push("
");
                } else if (obj.type === "dropdown-menu") {
                    dropdownMenusCount++;
                    parameters.push("
");
                    parameters.push("<button class=\"btn btn-default dropdown-toggle\" type=\"button\" ");
                    parameters.push("id=\"dropdownMenu-parameters");
                    parameters.push(dropdownMenusCount);
                    parameters.push("\" ");
                    parameters.push("data-toggle=\"dropdown\" aria-haspopup=\"true\" aria-expanded=\"true\">");
                    parameters.push(obj.name);
                    parameters.push("");
                    parameters.push("</button>");
                    parameters.push("
");

                    obj.menuItems.forEach(function (obj2) {
                        parameters.push("
");
                        parameters.push(obj2);
                        parameters.push("
");
                    });

                    parameters.push("
");
                    parameters.push("
");
                }
            });
            parameters.push('</form>');
            parameters = parameters.join("");
        }

        html.push(generalClassesNameTemplate);
        html.push(classes);
        html.push(parameters);

        html = html.join("");

        dom.getElementById('classes-and-parameters').innerHTML += html;
    });
}<|endoftext|>


<commit_before>/**
 * New Relic agent configuration.
 *
 * See lib/config.defaults.js in the agent distribution for a more complete
 * description of configuration variables and their potential values.
 */
exports.config = {
  /**
   * Array of application names.
   */
  app_name : ['Nitro Server'],
  /**
   * Your New Relic license key.
   */
  license_key : process.env.NEW_RELIC_LICENSE_KEY,
  logging : {
    /**
     * Level at which to log. 'trace' is most useful to New Relic when diagnosing
     * issues with the agent, 'info' and higher will impose the least overhead on
     * production applications.
     */
    level : 'trace'
  }
};
<commit_msg>Switch new relic to ‘info’ logging<commit_after>/**
 * New Relic agent configuration.
 *
 * See lib/config.defaults.js in the agent distribution for a more complete
 * description of configuration variables and their potential values.
 */
exports.config = {
  /**
   * Array of application names.
   */
  app_name : ['Nitro Server'],
  /**
   * Your New Relic license key.
   */
  license_key : process.env.NEW_RELIC_LICENSE_KEY,
  logging : {
    /**
     * Level at which to log. 'trace' is most useful to New Relic when diagnosing
     * issues with the agent, 'info' and higher will impose the least overhead on
     * production applications.
     */
    level : 'info'
  }
};
<|endoftext|>


<commit_before>/**
 * Created by Nicholas Hallahan <nhallahan@spatialdev.com>
 *     on Mon Mar 17 2014
 */

angular.module('GeoAngular').factory('Route', function ($rootScope, $location, Alias) {

  var init = true;

  // default route parameters. gets reset by AppCtrl.
  var params = {
    lat: '45',
    lng: '0',
    zoom: '4',
    layers: Alias.osm,
    stories: 'Route' //NH TODO take out, just for debugging...
  };

  function updateLocation() {
    var path = '/map@' + params.lat +
      ',' + params.lng +
      ',' + params.zoom +
      '(' + params.layers + ')';
    if (params.stories) path += '/stories/' + params.stories;
    if (params.landing) path += '/landing';

    $location.path(path);
  }

  /**
   * Simple object equality test. angular.equals is expensive.
   * @param obj1
   * @param obj2
   * @returns {boolean}
   */
  function equals(obj1, obj2) {
    if (Object.keys(obj1).length !== Object.keys(obj2).length)
      return false;
    for (var key in obj1) {
      if (obj1[key] !== obj2[key])
        return false;
    }
    return true;
  }

  return function(routeParams) {
    // only do this stuff if we have an arg in the fn call
    if (typeof routeParams !== 'undefined' && routeParams !== null) {
      if (init) {
        params = routeParams;
        $rootScope.$broadcast('route-init', params);
        console.log('route-init');
        console.log(JSON.stringify(params));
        init = false;
      } else {
        // Angular is trolling Route. We don't want to do 3 broadcasts of the same thing.
        if ( equals(params,routeParams) ) return params;
        angular.extend(params, routeParams);
        updateLocation();
        $rootScope.$broadcast('route-update', params);
        console.log('route-update');
        console.log(JSON.stringify(params));
      }
    }
    return params;
  };

});
<commit_msg>clicking initial landing link now working. NH TODO: see why param equality test in Route.js is true thus preventing map refresh<commit_after>/**
 * Created by Nicholas Hallahan <nhallahan@spatialdev.com>
 *     on Mon Mar 17 2014
 */

angular.module('GeoAngular').factory('Route', function ($rootScope, $location, Alias) {

  var init = true;

  // default route parameters. gets reset by AppCtrl.
  var params = {
    lat: '45',
    lng: '0',
    zoom: '4',
    layers: Alias.osm,
    stories: 'Route' //NH TODO take out, just for debugging...
  };

  function updateLocation() {
    var path = '/map@' + params.lat +
      ',' + params.lng +
      ',' + params.zoom +
      '(' + params.layers + ')';
    if (params.stories) path += '/stories/' + params.stories;
    if (params.landing) path += '/landing';

    $location.path(path);
  }

  /**
   * Simple object equality test. angular.equals is expensive.
   * @param obj1
   * @param obj2
   * @returns {boolean}
   */
  function equals(obj1, obj2) {
    if (Object.keys(obj1).length !== Object.keys(obj2).length)
      return false;
    for (var key in obj1) {
      if (obj1[key] !== obj2[key])
        return false;
    }
    return true;
  }

  return function(routeParams) {
    // only do this stuff if we have an arg in the fn call
    if (typeof routeParams !== 'undefined' && routeParams !== null) {
      if (init) {
        params = routeParams;
        $rootScope.$broadcast('route-init', params);
        console.log('route-init');
        console.log(JSON.stringify(params));
        init = false;
      } else {
        // Angular is trolling Route. We don't want to do 3 broadcasts of the same thing.
        //NH TODO: Figure out why this is true when initial landing link is clicked
//        if ( equals(params,routeParams) ) return params;
        angular.extend(params, routeParams);
        updateLocation();
        $rootScope.$broadcast('route-update', params);
        console.log('route-update');
        console.log(JSON.stringify(params));
      }
    }
    // NH good way to test if outsiders are messing with inside
//    return angular.extend({},params);
    return params;
  };

});
<|endoftext|>


<commit_before>var DeeToo = require('..')
  , d2 = DeeToo.init()

  , JOB_TIME = 5000

function _generateJobs() {
  function mkjob(i) {
    var id = 'demo'+j
    return {id:id, jobType:'demonstrate', jobData:{title: id}}
  }

  function showUpdates(err, job) {
    job.on('progress', function(prog) {
      console.log(['Job', job.id, '@', prog, '%'].join(' '))
    })
  }

  for (var j=0; j<1; j++) {
      console.log('creating #' + j)
      d2.jobs.push(mkjob(j), showUpdates)
  }
}

// An example process that takes 5 seconds to run
// and updates its progress every second.
function processDemonstration(job, $done) {
  function nextStep(){ job.progress(++step, 5) }

  function stop() {
    clearTimeout(ticker)
    $done()
  }

  var step = 0
    , ticker = setInterval(nextStep, JOB_TIME/5)

  setTimeout(stop, JOB_TIME)
}

// Launch the worker
d2
  .speaks('http')

  .can('demonstrate', 4, processDemonstration)

  .start(function(err) {
    console.log('Example worker has started!')
  })

setTimeout(_generateJobs, 1)

// Demonstrate graceful shutdown
setTimeout(function() {
  console.log('([ shutting down ])')

  d2.shutdown(function() {
    console.log('([ SHUT DOWN ])')
  })
}, JOB_TIME * 2.3)

<commit_msg>Update example file<commit_after>require('longjohn')

var DeeToo = require('..')
  , d2 = DeeToo.init()

  , JOB_TIME = 5000

function _generateJobs() {
  function mkjob(i) {
    var id = 'demo'+j
    return {id:id, jobType:'demonstrate', jobData:{title: id}}
  }

  function showUpdates(err, job) {
    job.on('progress', function(prog) {
      console.log(['Job', job.id, '@', prog, '%'].join(' '))
    })
  }

  for (var j=0; j<20; j++) {
    d2.jobs.push(mkjob(j), showUpdates)
  }
}

// An example process that takes 5 seconds to run
// and updates its progress every second.
function processDemonstration(job, $done) {
  function nextStep(){ job.progress(++step, 5) }

  function stop() {
    clearTimeout(ticker)
    console.log(['Job', job.id, 'finished!'].join(' '))
    $done()
  }

  var step = 0
    , ticker = setInterval(nextStep, JOB_TIME/5)

  setTimeout(stop, JOB_TIME)
}

// Launch the worker
d2
  .can('demonstrate', 4, processDemonstration)

  .start(function(err) {
    console.log('Example worker has started!')
  })

setTimeout(_generateJobs, 1)

// Demonstrate graceful shutdown
setTimeout(function() {
  console.log('\n([~ shutting down ~])\n')

  d2.shutdown(function() {
    console.log('\n([~ SHUT DOWN ~])\n')
    setTimeout(function(){ process.exit(0) }, 1000)
  })
}, JOB_TIME * 2.3)

<|endoftext|>


<commit_before>'use strict';

const Configstore = require('configstore');
const fsx = require('./fs-additions');
const path = require('path');
const root = require('find-root');
const _ = require('lodash');

// Information about LT itself
const pkg = require('../../package.json');
const majorVersion = pkg.version ? pkg.version.split('.')[0] : 'unknown';
const resourcePrefix = _.compact([pkg.name, majorVersion]).join('-');

const bucketPrefix = (new Configstore(pkg.name)).get('S3BucketPrefix');

/**
 *  Helper for loading config file of a project
 */

// Load configuration file from disk (if one exists)
// Default values
let result = {
    project: {},
    lambda: {
        runtime: 'nodejs'
    },
    aws: {
        region: 'us-east-1',
        stage: 'dev'
    },
    tools: {
        name: pkg.name,
        version: pkg.version,
        majorVersion: majorVersion,
        resources: {
            s3Bucket: _.compact([bucketPrefix, resourcePrefix, 'assets']).join('-'),
            iamRole: [resourcePrefix, 'resource'].join('-'),
            apiGateway: [resourcePrefix, 'api-gateway'].join('-'),
            lambdaVersion: [resourcePrefix, 'lambda-version'].join('-')
        }
    }
};

// Config file is assumed to be at "package root"
try {
    const rootPath = root(process.cwd());
    const configPath = path.resolve(rootPath, '.lambda-tools-rc.json');

    if (fsx.fileExists(configPath)) {
        result = _.merge(result, fsx.readJSONFileSync(configPath));
    }
} catch (err) {
    // Ignore
}

module.exports = result;
<commit_msg>Redo the prefix logic to expand to all resources<commit_after>'use strict';

const Configstore = require('configstore');
const fsx = require('./fs-additions');
const path = require('path');
const root = require('find-root');
const _ = require('lodash');

// Information about LT itself
const pkg = require('../../package.json');
const majorVersion = pkg.version ? pkg.version.split('.')[0] : 'unknown';
const resourcePrefix = _.compact([(new Configstore(pkg.name)).get('ResourcePrefix'), pkg.name, majorVersion]).join('-');

/**
 *  Helper for loading config file of a project
 */

// Load configuration file from disk (if one exists)
// Default values
let result = {
    project: {},
    lambda: {
        runtime: 'nodejs'
    },
    aws: {
        region: 'us-east-1',
        stage: 'dev'
    },
    tools: {
        name: pkg.name,
        version: pkg.version,
        majorVersion: majorVersion,
        resources: {
            s3Bucket: [resourcePrefix, 'assets'].join('-'),
            iamRole: [resourcePrefix, 'resource'].join('-'),
            apiGateway: [resourcePrefix, 'api-gateway'].join('-'),
            lambdaVersion: [resourcePrefix, 'lambda-version'].join('-')
        }
    }
};

// Config file is assumed to be at "package root"
try {
    const rootPath = root(process.cwd());
    const configPath = path.resolve(rootPath, '.lambda-tools-rc.json');

    if (fsx.fileExists(configPath)) {
        result = _.merge(result, fsx.readJSONFileSync(configPath));
    }
} catch (err) {
    // Ignore
}

module.exports = result;
<|endoftext|>


<commit_before>'use strict';

// Parse Init
Parse.initialize(CONFIG.PARSE_APP_ID, CONFIG.PARSE_JS_KEY);

// Angular Init
var app = angular.module('app', ['ng',
                                 'ngAnimate',
                                 'ui.router',
                                 'ui.bootstrap',
                                 'textareaNoreturn',
                                 'parse.user',
                                 'ngSanitize',
                                 'restangular',
                                 'ngHtmlCompile',
                                 'ngContent',
                                 'prismic.io',
                                 'slugifier',
                                 'disqusHere',
                                 'angular-data.DSCacheFactory',
                                 'templateInclude',
                                 'ngCsv'
                                ]);
console.log('starting app');

app.config(function($locationProvider, PrismicProvider, DSCacheFactoryProvider, $provide) {
	$locationProvider.html5Mode(true);
	$locationProvider.hashPrefix('!');

	if (CONFIG.PRISMIC) {
		PrismicProvider.setApiEndpoint(CONFIG.PRISMIC.API_ENDPOINT);
		if (CONFIG.PRISMIC.ACCESS_TOKEN)
			PrismicProvider.setAccessToken(CONFIG.PRISMIC.ACCESS_TOKEN);
		if(CONFIG.PRISMIC.CLIENT_ID)
			PrismicProvider.setClientId(CONFIG.PRISMIC.CLIENT_ID);
		if(CONFIG.PRISMIC.CLIENT_SECRET)
			PrismicProvider.setClientSecret(CONFIG.PRISMIC.CLIENT_SECRET);
	}
	PrismicProvider.setLinkResolver(function(ctx, doc) {
		return 'detail.html?id=' + doc.id + '&slug=' + doc.slug + ctx.maybeRefParam;
	});

	DSCacheFactoryProvider.setCacheDefaults({
		storageMode: 'localStorage',
		capacity: 100
	});

	$provide.decorator('$uiViewScroll', function ($delegate, $window) {
		return function (uiViewElement) {
			$window.scrollTo(0,0);
		};
	});
});

app.run(function($rootScope,
                 $state,
                 $stateParams,
                 parseUser,
                 $window,
                 $location,
                 $timeout
	) {
		// Default away value
		$rootScope.isAway = false;

		$rootScope.$state = $state;
		$rootScope.$stateParams = $stateParams;

		// loading animation
		$rootScope.setLoading = function() {
			$rootScope.isViewLoading = true;
		};
		$rootScope.unsetLoading = function() {
			$rootScope.isViewLoading = false;
		};

		$rootScope.isViewLoading = false;

		$rootScope.$on('$stateChangeStart', function(ev, to, toParams, from, fromParams) {
			$rootScope.setLoading();
			if(to.name === 'home')
				$rootScope.isAway = false;
			else
				$rootScope.isAway = true;
		});

		$rootScope.$on('$stateChangeSuccess', function (ev, to, toParams, from, fromParams) {
			$rootScope.unsetLoading();
			$rootScope.currentUrl = $location.absUrl();
		});

		$rootScope.$on('$stateChangeError', function (ev, to, toParams, from, fromParams, error) {
			$rootScope.unsetLoading();
			console.log('Error transitioning to state', to.controller, error.message);
			console.log(error.stack);
		});
	}
);<commit_msg>fixed injection issue<commit_after>'use strict';

// Parse Init
Parse.initialize(CONFIG.PARSE_APP_ID, CONFIG.PARSE_JS_KEY);

// Angular Init
var app = angular.module('app', ['ng',
                                 'ngAnimate',
                                 'ui.router',
                                 'ui.bootstrap',
                                 'textareaNoreturn',
                                 'parse.user',
                                 'ngSanitize',
                                 'restangular',
                                 'ngHtmlCompile',
                                 'ngContent',
                                 'prismic.io',
                                 'slugifier',
                                 'disqusHere',
                                 'angular-data.DSCacheFactory',
                                 'templateInclude',
                                 'ngCsv'
                                ]);
console.log('starting app');

app.config(function($locationProvider, PrismicProvider, DSCacheFactoryProvider, $provide) {
	$locationProvider.html5Mode(true);
	$locationProvider.hashPrefix('!');

	if (CONFIG.PRISMIC) {
		PrismicProvider.setApiEndpoint(CONFIG.PRISMIC.API_ENDPOINT);
		if (CONFIG.PRISMIC.ACCESS_TOKEN)
			PrismicProvider.setAccessToken(CONFIG.PRISMIC.ACCESS_TOKEN);
		if(CONFIG.PRISMIC.CLIENT_ID)
			PrismicProvider.setClientId(CONFIG.PRISMIC.CLIENT_ID);
		if(CONFIG.PRISMIC.CLIENT_SECRET)
			PrismicProvider.setClientSecret(CONFIG.PRISMIC.CLIENT_SECRET);
	}
	PrismicProvider.setLinkResolver(function(ctx, doc) {
		return 'detail.html?id=' + doc.id + '&slug=' + doc.slug + ctx.maybeRefParam;
	});

	DSCacheFactoryProvider.setCacheDefaults({
		storageMode: 'localStorage',
		capacity: 100
	});

	$provide.decorator('$uiViewScroll', ['$delegate', '$window', function ($delegate, $window) {
		return function (uiViewElement) {
			$window.scrollTo(0,0);
		};
	}]);
});

app.run(function($rootScope,
                 $state,
                 $stateParams,
                 parseUser,
                 $window,
                 $location,
                 $timeout
	) {
		// Default away value
		$rootScope.isAway = false;

		$rootScope.$state = $state;
		$rootScope.$stateParams = $stateParams;

		// loading animation
		$rootScope.setLoading = function() {
			$rootScope.isViewLoading = true;
		};
		$rootScope.unsetLoading = function() {
			$rootScope.isViewLoading = false;
		};

		$rootScope.isViewLoading = false;

		$rootScope.$on('$stateChangeStart', function(ev, to, toParams, from, fromParams) {
			$rootScope.setLoading();
			if(to.name === 'home')
				$rootScope.isAway = false;
			else
				$rootScope.isAway = true;
		});

		$rootScope.$on('$stateChangeSuccess', function (ev, to, toParams, from, fromParams) {
			$rootScope.unsetLoading();
			$rootScope.currentUrl = $location.absUrl();
		});

		$rootScope.$on('$stateChangeError', function (ev, to, toParams, from, fromParams, error) {
			$rootScope.unsetLoading();
			console.log('Error transitioning to state', to.controller, error.message);
			console.log(error.stack);
		});
	}
);<|endoftext|>


<commit_before>var vows = require('vows'),
    assert = require('assert'),
    fs = require('fs'),
    path = require('path')
    exec = require('child_process').exec;

function testExample(dir) {
  return {
    'Folder Init' : {
      topic: function() {
        fs.stat(dir, this.callback)
      },
      "exists" : function(err, stat) {
        assert.isTrue(stat.isDirectory())
      },
      "Build" : {
        topic: function() {
          if (!fs.accessSync(dir + "/node_modules")) {
            fs.symlinkSync(fs.realpathSync("node_modules"), dir + "/node_modules")
          }
          var cmd = "cd " + dir + "; rm -rf build; ./node_modules/broccoli-cli/bin/broccoli build build;"

          // Add some debug output
          cmd += " find build; "
          exec(cmd, this.callback)
        },
        "output" : function(err, stdout, stderr) {
          console.log(stdout);
          // console.log('stderr: ' + stderr);
          // if (err !== null) {
          //  console.log('exec error: ' + err);
          // }
        }
      }
    }
  }
}

vows.describe("Example build")
    .addBatch(testExample("example"))
    .export(module);<commit_msg>This also needs to be available as a module<commit_after>var vows = require('vows'),
    assert = require('assert'),
    fs = require('fs'),
    exec = require('child_process').exec;

function testExample(dir) {
  return {
    'Folder' : {
      topic: function() {
        fs.stat(dir, this.callback)
      },
      "exists" : function(err, stat) {
        assert.isTrue(stat.isDirectory())
      },
      "Build" : {
        topic: function() {
          if (!fs.statSync(dir + "/node_modules").isDirectory()) {
            fs.symlinkSync(fs.realpathSync("node_modules"), dir + "/node_modules")
          }
          if (!fs.statSync("node_modules/broccoli-steamer").isDirectory()) {
            console.log("symlink to " + fs.realpathSync("./"))
            fs.symlinkSync(fs.realpathSync("./"), "node_modules/broccoli-steamer")
          }
          var cmd = "cd " + dir + "; rm -rf build; mkdir build; ./node_modules/broccoli-cli/bin/broccoli build build;"

          // Add some debug output
          cmd += " find build; cd -; "
            console.log(cmd)
          exec(cmd, this.callback)
        },
        "output" : function(err, stdout, stderr) {
          console.log("stderr: " + stderr);
          console.log("stdout: " + stdout);
        }
      }
    }
  }
}

vows.describe("Example build")
    .addBatch(testExample("example"))
    .export(module);<|endoftext|>


<commit_before>/*global $:false, window:false, Highcharts:false, document:false, moment:false, Chart:false */
"use strict";
$(function () {
    // Configuration
    window.settings = {
        ajaxIntervalMillis: 2000,
        dateFormat: "DD.MM.YYYY",
        jsonDateFormat: "YYYY-MM-DD",
        chartDateFormat: "DD.MM",
        lastUpdateDateFormat: "DD.MM.YYYY HH:mm:ss",
        killColor: "#000000",
        saveColor: "#FAFAFA",
    };

    $('#toggle_last_update_panel').click(function () {
        $('#last_update_panel').toggle();
        return false;
    });

    // we'll keep data here
    window.stats = {};

    // callback func for ajax timer
    window.ajaxFunc = function () {
        console.log("updating data using AJAX");
        $.get("http://localhost:8000/gamestats.json", function (data) {
            console.log(data);
            window.stats = data;
        }).fail(function (xhr, err) {
            $('#last_error').text(String(err) + " (" + String(xhr.status) + ")");
        }).success(function () {
            $('#last_error').text("ok");
        }).always(function () {
            $('#last_update').text(moment().format(window.settings.lastUpdateDateFormat));
            window.setTimeout(window.ajaxFunc, window.settings.ajaxIntervalMillis);
        });
    };

    Highcharts.setOptions({
        colors: [window.settings.saveColor, window.settings.killColor]
    });

    // the chart currently being displayed,
    // since we start with empty page, the value is -1.
    window.currentChart = -1;

    // callback func chart rotating
    window.chartRotateFunc = function () {
        console.log("rotating charts");

        window.ensureData();

        window.displayDates();

        window.displayTotals();

        window.currentChart = window.currentChart + 1;
        if (window.currentChart > 3) {
            window.currentChart = 0;
        }

        // Hide visible chart(s)
        $('.stats').hide();

        // show the current chart
        var chart = $('#chart' + String(window.currentChart)),
            rotateIntervalSeconds = parseInt(chart.attr('data-interval-seconds'), 10);
        chart.show();

        // draw its internal contents.
        // (the indices respond to chart ID's in HTML)
        if (3 === window.currentChart) {
            window.displayBarChart();
        } else if (2 === window.currentChart) {
            window.displayPieChart();
        }

        // Rotate charts with N millis interval (see HTML)
        console.log("rotate interval seconds", rotateIntervalSeconds);
        if (rotateIntervalSeconds) {
            window.setTimeout(window.chartRotateFunc, rotateIntervalSeconds * 1000);
        } else {
            console.log("missing data-interval on chart! ");
        }
    };

    window.ensureData = function () {
        if (!window.stats.total) {
            window.stats.total = {};
        }
        if (!window.stats.history) {
            window.stats.history = {};
        }
    };

    window.displayBarChart = function () {
        var categories = [], saves = [], kills = [];
        $.each(window.stats.history, function (key, val) {
            categories.push(moment(key).format(window.settings.chartDateFormat));
            saves.push(val.saves);
            kills.push(val.kills);
        });

        $('#barchart').highcharts({
            chart: {
                type: 'column'
            },
            title: {
                text: ''
            },
            xAxis: {
                categories: categories,
                crosshair: true
            },
            yAxis: {
                min: 0,
                title: {
                    text: ''
                }
            },
            tooltip: {
                headerFormat: '{point.key}
',
                pointFormat: '
{series.name}: 	' +
                    '{point.y:.1f} mm
',
                footerFormat: '
',
                shared: true,
                useHTML: true
            },
            plotOptions: {
                column: {
                    pointPadding: 0.2,
                    borderColor: "#000000",
                    borderRadius: 1,
                    borderWidth: 1,
                },
            },
            series: [{
                name: 'Säästetud elud / Saves',
                data: saves,
            }, {
                name: 'Hukkamised / Kills',
                data: kills

            }]
        });
    };

    // Update the total numbers, which are included in multiple charts
    window.displayTotals = function () {
        window.ensureData();
        $(".total_saves").text(window.stats.total.saves);
        $(".total_kills").text(window.stats.total.kills);

        // find todays stats
        var today = moment().format(window.settings.jsonDateFormat),
            todaysResults = window.stats.history[today];
        if (todaysResults) {
            $(".today_saves").text(todaysResults.saves);
            $(".today_kills").text(todaysResults.kills);
        }
    };

    // Until we have real data from backend, use today's date
    window.startDate = moment();
    window.endDate = moment();

    // Update the dates, which are visible in multiple charts
    window.displayDates = function () {
        var today = moment();
        $(".today").text(today.format(window.settings.dateFormat));

        // find the start and end date range of available data
        $.each(window.stats.history, function (key) {
            var date = moment(key);
            if (date.isBefore(window.startDate)) {
                window.startDate = moment(date);
            }
            if (date.isAfter(window.endDate)) {
                window.endDate = moment(date);
            }
        });
        $(".start_date").text(window.startDate.format(window.settings.dateFormat));
        $(".end_date").text(window.endDate.format(window.settings.dateFormat));
    };

    window.displayPieChart = function () {
        window.ensureData();

        $('#piechart').highcharts({
            credits: false,
            chart: {
                type: 'pie',
                options3d: {
                    enabled: true,
                    alpha: 45,
                    beta: 0
                }
            },
            title: {
                text: ''
            },
            tooltip: {
                pointFormat: '{series.name}: {point.percentage:.1f}%'
            },
            plotOptions: {
                pie: {
                    allowPointSelect: true,
                    cursor: 'pointer',
                    depth: 35,
                    dataLabels: {
                        enabled: true,
                        format: '{point.name}'
                    },
                },
            },
            series: [{
                type: 'pie',
                name: 'HUMANITY vs CURIOSITY',
                data: [
                    ["HUMAANSUS / HUMANITY", window.stats.total.saves],
                    ["UUDISHIMU / CURIOSITY", window.stats.total.kills]
                ],
            }]
        });
    };

    console.log("initialized");

    window.chartRotateFunc();

    // Start by updating data
    window.ajaxFunc();
});

<commit_msg>border color change<commit_after>/*global $:false, window:false, Highcharts:false, document:false, moment:false, Chart:false */
"use strict";
$(function () {
    // Configuration
    window.settings = {
        ajaxIntervalMillis: 2000,
        dateFormat: "DD.MM.YYYY",
        jsonDateFormat: "YYYY-MM-DD",
        chartDateFormat: "DD.MM",
        lastUpdateDateFormat: "DD.MM.YYYY HH:mm:ss",
        killColor: "#000000",
        saveColor: "#FAFAFA",
        borderColor: "#F9F9F9",
    };

    $('#toggle_last_update_panel').click(function () {
        $('#last_update_panel').toggle();
        return false;
    });

    // we'll keep data here
    window.stats = {};

    // callback func for ajax timer
    window.ajaxFunc = function () {
        console.log("updating data using AJAX");
        $.get("http://localhost:8000/gamestats.json", function (data) {
            console.log(data);
            window.stats = data;
        }).fail(function (xhr, err) {
            $('#last_error').text(String(err) + " (" + String(xhr.status) + ")");
        }).success(function () {
            $('#last_error').text("ok");
        }).always(function () {
            $('#last_update').text(moment().format(window.settings.lastUpdateDateFormat));
            window.setTimeout(window.ajaxFunc, window.settings.ajaxIntervalMillis);
        });
    };

    Highcharts.setOptions({
        colors: [window.settings.saveColor, window.settings.killColor]
    });

    // the chart currently being displayed,
    // since we start with empty page, the value is -1.
    window.currentChart = -1;

    // callback func chart rotating
    window.chartRotateFunc = function () {
        console.log("rotating charts");

        window.ensureData();

        window.displayDates();

        window.displayTotals();

        window.currentChart = window.currentChart + 1;
        if (window.currentChart > 3) {
            window.currentChart = 0;
        }

        // Hide visible chart(s)
        $('.stats').hide();

        // show the current chart
        var chart = $('#chart' + String(window.currentChart)),
            rotateIntervalSeconds = parseInt(chart.attr('data-interval-seconds'), 10);
        chart.show();

        // draw its internal contents.
        // (the indices respond to chart ID's in HTML)
        if (3 === window.currentChart) {
            window.displayBarChart();
        } else if (2 === window.currentChart) {
            window.displayPieChart();
        }

        // Rotate charts with N millis interval (see HTML)
        console.log("rotate interval seconds", rotateIntervalSeconds);
        if (rotateIntervalSeconds) {
            window.setTimeout(window.chartRotateFunc, rotateIntervalSeconds * 1000);
        } else {
            console.log("missing data-interval on chart! ");
        }
    };

    window.ensureData = function () {
        if (!window.stats.total) {
            window.stats.total = {};
        }
        if (!window.stats.history) {
            window.stats.history = {};
        }
    };

    window.displayBarChart = function () {
        var categories = [], saves = [], kills = [];
        $.each(window.stats.history, function (key, val) {
            categories.push(moment(key).format(window.settings.chartDateFormat));
            saves.push(val.saves);
            kills.push(val.kills);
        });

        $('#barchart').highcharts({
            chart: {
                type: 'column'
            },
            title: {
                text: ''
            },
            xAxis: {
                categories: categories,
                crosshair: true
            },
            yAxis: {
                min: 0,
                title: {
                    text: ''
                }
            },
            tooltip: {
                headerFormat: '{point.key}
',
                pointFormat: '
{series.name}: 	' +
                    '{point.y:.1f} mm
',
                footerFormat: '
',
                shared: true,
                useHTML: true
            },
            plotOptions: {
                column: {
                    pointPadding: 0.2,
                    borderColor: window.settings.borderColor,
                    borderRadius: 1,
                    borderWidth: 1,
                },
            },
            series: [{
                name: 'Säästetud elud / Saves',
                data: saves,
            }, {
                name: 'Hukkamised / Kills',
                data: kills

            }]
        });
    };

    // Update the total numbers, which are included in multiple charts
    window.displayTotals = function () {
        window.ensureData();
        $(".total_saves").text(window.stats.total.saves);
        $(".total_kills").text(window.stats.total.kills);

        // find todays stats
        var today = moment().format(window.settings.jsonDateFormat),
            todaysResults = window.stats.history[today];
        if (todaysResults) {
            $(".today_saves").text(todaysResults.saves);
            $(".today_kills").text(todaysResults.kills);
        }
    };

    // Until we have real data from backend, use today's date
    window.startDate = moment();
    window.endDate = moment();

    // Update the dates, which are visible in multiple charts
    window.displayDates = function () {
        var today = moment();
        $(".today").text(today.format(window.settings.dateFormat));

        // find the start and end date range of available data
        $.each(window.stats.history, function (key) {
            var date = moment(key);
            if (date.isBefore(window.startDate)) {
                window.startDate = moment(date);
            }
            if (date.isAfter(window.endDate)) {
                window.endDate = moment(date);
            }
        });
        $(".start_date").text(window.startDate.format(window.settings.dateFormat));
        $(".end_date").text(window.endDate.format(window.settings.dateFormat));
    };

    window.displayPieChart = function () {
        window.ensureData();

        $('#piechart').highcharts({
            credits: false,
            chart: {
                type: 'pie',
                options3d: {
                    enabled: true,
                    alpha: 45,
                    beta: 0
                }
            },
            title: {
                text: ''
            },
            tooltip: {
                pointFormat: '{series.name}: {point.percentage:.1f}%'
            },
            plotOptions: {
                pie: {
                    allowPointSelect: true,
                    cursor: 'pointer',
                    depth: 35,
                    dataLabels: {
                        enabled: true,
                        format: '{point.name}'
                    },
                },
            },
            series: [{
                type: 'pie',
                name: 'HUMANITY vs CURIOSITY',
                data: [
                    ["HUMAANSUS / HUMANITY", window.stats.total.saves],
                    ["UUDISHIMU / CURIOSITY", window.stats.total.kills]
                ],
            }]
        });
    };

    console.log("initialized");

    window.chartRotateFunc();

    // Start by updating data
    window.ajaxFunc();
});

<|endoftext|>


<commit_before>var expect = require('expect.js');
var seeds = require('../seeds');
var Feature = require('../feature');

describe('Feature', function () {
  before(function (done) {
    seeds(done);
  });

  describe('schema', function () {
    it('successfully creates a valid document');
    it('fails at creating an invalid document');
  });

  describe('.search()', function () {
    it('performs an empty search, returning all commands', function (done) {
      Feature.search('', function (docs) {
        expect(docs.length).to.be(7);
        done();
      });
    });

    it('performs a case-insensitive search for a command', function (done) {
      Feature.search('git ADD', function (docs) {
        expect(docs).to.eql([{
          name: 'add files',
          examples: [
            { technology: 'Git', snippets: ['git add'] },
            { technology: 'Mercurial', snippets: ['hg add'] },
            { technology: 'Subversion', snippets: ['svn add'] }
          ]
        }]);

        done();
      });
    });

    it('discards extra hidden fields created by MongoDB');

    it('performs a search for a command that does not exist', function (done) {
      Feature.search('git yolo', function (docs) {
        expect(docs.length).to.be(0);
        done();
      });
    });
  });
});
<commit_msg>Remove an extra anonymous function<commit_after>var expect = require('expect.js');
var seeds = require('../seeds');
var Feature = require('../feature');

describe('Feature', function () {
  before(seeds);

  describe('schema', function () {
    it('successfully creates a valid document');
    it('fails at creating an invalid document');
  });

  describe('.search()', function () {
    it('performs an empty search, returning all commands', function (done) {
      Feature.search('', function (docs) {
        expect(docs.length).to.be(7);
        done();
      });
    });

    it('performs a case-insensitive search for a command', function (done) {
      Feature.search('git ADD', function (docs) {
        expect(docs).to.eql([{
          name: 'add files',
          examples: [
            { technology: 'Git', snippets: ['git add'] },
            { technology: 'Mercurial', snippets: ['hg add'] },
            { technology: 'Subversion', snippets: ['svn add'] }
          ]
        }]);

        done();
      });
    });

    it('discards extra hidden fields created by MongoDB');

    it('performs a search for a command that does not exist', function (done) {
      Feature.search('git yolo', function (docs) {
        expect(docs.length).to.be(0);
        done();
      });
    });
  });
});
<|endoftext|>


<commit_before>var assert = require('assert');
var seeds = require('../seeds');
var Feature = require('../feature');

describe('Feature', function () {
  before(function (done) {
    seeds(done);
  });

  describe('schema', function () {
    it('successfully creates a valid document');
    it('fails at creating an invalid document');
  });

  describe('.search()', function () {
    it('performs an empty search, returning all commands', function (done) {
      Feature.search('', function (docs) {
        assert.equal(7, docs.length);
        done();
      });
    });

    it('performs a case-insensitive search for a command', function (done) {
      Feature.search('git ADD', function (docs) {
        assert.equal(1, docs.length);

        var doc = docs[0];
        assert.equal('add files', doc.name);
        assert.deepEqual({
          Git: 'git add',
          Mercurial: 'hg add',
          Subversion: 'svn add'
        }, doc.examples);

        done();
      });
    });

    it('discards extra hidden fields created by MongoDB');

    it('performs a search for a command that does not exist', function (done) {
      Feature.search('git yolo', function (docs) {
        assert.equal(0, docs.length);
        done();
      });
    });
  });
});
<commit_msg>Fix the order of parameters for assert.equals()<commit_after>var assert = require('assert');
var seeds = require('../seeds');
var Feature = require('../feature');

describe('Feature', function () {
  before(function (done) {
    seeds(done);
  });

  describe('schema', function () {
    it('successfully creates a valid document');
    it('fails at creating an invalid document');
  });

  describe('.search()', function () {
    it('performs an empty search, returning all commands', function (done) {
      Feature.search('', function (docs) {
        assert.equal(docs.length, 7);
        done();
      });
    });

    it('performs a case-insensitive search for a command', function (done) {
      Feature.search('git ADD', function (docs) {
        assert.equal(docs.length, 1);

        var doc = docs[0];
        assert.equal(doc.name, 'add files');
        assert.deepEqual(doc.examples, {
          Git: 'git add',
          Mercurial: 'hg add',
          Subversion: 'svn add'
        });

        done();
      });
    });

    it('discards extra hidden fields created by MongoDB');

    it('performs a search for a command that does not exist', function (done) {
      Feature.search('git yolo', function (docs) {
        assert.equal(docs.length, 0);
        done();
      });
    });
  });
});
<|endoftext|>


<commit_before>var expect = require('chai').expect;
var asyncChainable = require('../index');

describe('async-chainable.forEach() - array style', function(){
	var output;

	before(function(done) {
		output = [];

		asyncChainable()
			.forEach(['foo', 'bar', 'baz'], function(next, item) { output.push(item); next(); })
			.end(function(err) {
				expect(err).to.be.undefined();
				done();
			});
	});

	it('should have the correct number of output elements', function() {
		expect(output).to.have.length(3);
	});

	it('contain the expected output', function() {
		expect(output).to.contain('foo');
		expect(output).to.contain('bar');
		expect(output).to.contain('baz');
	});
});

describe('async-chainable.forEach() - array style, unlimited', function(){
	var output, running = 0, maxRunning = 0;
	this.timeout(5000);

	before(function(done) {
		output = [];

		asyncChainable()
			.limit(null)
			.forEach(['foo', 'bar', 'baz', 'quz', 'quuz', 'quuuz'], function(next, item) {
				running++;
				if (running > maxRunning) maxRunning = running;
				setTimeout(function() {
					running--;
					output.push(item);
					next();
				}, Math.random() * 500)
			})
			.end(function(err) {
				expect(err).to.be.undefined();
				done();
			});
	});

	it('should have the correct number of output elements', function() {
		expect(output).to.have.length(6);
	});

	it('contain the expected output', function() {
		expect(output).to.contain('foo');
		expect(output).to.contain('bar');
		expect(output).to.contain('baz');
		expect(output).to.contain('quz');
		expect(output).to.contain('quuz');
		expect(output).to.contain('quuuz');
	});

	it('should have no threads left over', function() {
		expect(running).to.equal(0);
	});

	it('upper limit of 6 running threads', function() {
		expect(maxRunning).to.equal(6);
	});
});

describe('async-chainable.forEach() - array style, limited', function(){
	var output, running = 0, maxRunning = 0;
	this.timeout(5000);

	before(function(done) {
		output = [];

		asyncChainable()
			.limit(2)
			.forEach(['foo', 'bar', 'baz', 'quz', 'quuz', 'quuuz'], function(next, item) {
				running++;
				if (running > maxRunning) maxRunning = running;
				setTimeout(function() {
					running--;
					output.push(item);
					next();
				}, Math.random() * 500)
			})
			.end(function(err) {
				expect(err).to.be.undefined();
				done();
			});
	});

	it('should have the correct number of output elements', function() {
		expect(output).to.have.length(6);
	});

	it('contain the expected output', function() {
		expect(output).to.contain('foo');
		expect(output).to.contain('bar');
		expect(output).to.contain('baz');
		expect(output).to.contain('quz');
		expect(output).to.contain('quuz');
		expect(output).to.contain('quuuz');
	});

	it('should have no threads left over', function() {
		expect(running).to.equal(0);
	});

	it('limit to 2 running threads', function() {
		expect(maxRunning).to.equal(2);
	});
});

describe('async-chainable.forEach() - object style', function(){
	var context;
	var output;

	before(function(done) {
		context = {};
		output = [];

		asyncChainable()
			.forEach({fooKey: 'fooValue', barKey: 'barValue', bazKey: 'bazValue'}, function(next, item, key) { output.push(item, key); next(null, item); })
			.end(function(err) {
				expect(err).to.be.undefined();
				context = this;
				done();
			});
	});

	it('should have the correct number of output elements', function() {
		expect(output).to.have.length(6);
	});

	it('contain the expected output', function() {
		expect(output).to.contain('fooKey');
		expect(output).to.contain('fooValue');
		expect(output).to.contain('barKey');
		expect(output).to.contain('barValue');
		expect(output).to.contain('bazKey');
		expect(output).to.contain('bazValue');
	});

	it('should set the context', function() {
		expect(context).to.have.property('fooKey');
		expect(context.fooKey).to.equal('fooValue');

		expect(context).to.have.property('barKey');
		expect(context.barKey).to.equal('barValue');

		expect(context).to.have.property('bazKey');
		expect(context.bazKey).to.equal('bazValue');
	});
});

describe('async-chainable.forEach() - collection style', function(){
	var output;

	before(function(done) {
		context = {};
		output = [];

		asyncChainable()
			.forEach([
				{foo: 'Foo!', crash: 'Crash!'},
				{bar: 'Bar!', bang: 'Bang!'},
				{baz: 'Baz!', wallop: 'Wallop!'},
			], function(next, item) { output.push(item); next(null, item); })
			.end(function(err) {
				expect(err).to.be.undefined();
				done();
			});
	});

	it('should have the correct number of output elements', function() {
		expect(output).to.have.length(3);
	});

	it('contain the expected output', function() {
		expect(output).to.contain({foo: 'Foo!', crash: 'Crash!'});
		expect(output).to.contain({bar: 'Bar!', bang: 'Bang!'});
		expect(output).to.contain({baz: 'Baz!', wallop: 'Wallop!'});
	});
});

describe('async-chainable.forEach() - this._key + this._item', function(){
	var output;

	before(function(done) {
		output = [];

		asyncChainable()
			.forEach({
				fooKey: 'fooValue',
				barKey: 'barValue',
				bazKey: 'bazValue',
			}, function(next, item, key) { output.push(this._item, this._key); next(); })
			.end(function(err) {
				expect(err).to.be.undefined();
				done();
			});
	});

	it('should have the correct number of output elements', function() {
		expect(output).to.have.length(6);
	});

	it('contain the expected output', function() {
		expect(output).to.contain('fooKey');
		expect(output).to.contain('fooValue');
		expect(output).to.contain('barKey');
		expect(output).to.contain('barValue');
		expect(output).to.contain('bazKey');
		expect(output).to.contain('bazValue');
	});
});

describe('async-chainable.forEach() - named set', function(){
	var outputArray, outputObject, outputCollection;

	before(function(done) {
		outputArray = [];
		outputObject = [];
		outputCollection = [];

		asyncChainable()
			.set({
				items: ['foo', 'bar', 'baz'],
				hitchhikers: {
					arthur: 'british',
					ford: 'froody',
					zaphod: 'president'
				},
				numbers: [
					{one: 'Number 1'},
					{two: 'Number 2'},
					{three: 'Number 3'},
				],
			})
			.forEach('items', function(next, item) { // Array form
				outputArray.push(item);
				next();
			})
			.forEach('hitchhikers', function(next, item, key) { // Object form
				outputObject.push(item, key);
				next();
			})
			.forEach('numbers', function(next, item) { // Collection form
				outputCollection.push(item);
				next();
			})

			// Finish
			.end(function(err) {
				expect(err).to.be.undefined();
				done();
			});
	});

	it('array method should have the correct number of output elements', function() {
		expect(outputArray).to.have.length(3);
	});

	it('array method should contain the expected output', function() {
		expect(outputArray).to.contain('foo');
		expect(outputArray).to.contain('bar');
		expect(outputArray).to.contain('baz');
	});

	it('object method should have the correct number of output elements', function() {
		expect(outputObject).to.have.length(6);
	});

	it('object method should contain the expected output', function() {
		expect(outputObject).to.contain('arthur');
		expect(outputObject).to.contain('british');
		expect(outputObject).to.contain('ford');
		expect(outputObject).to.contain('froody');
		expect(outputObject).to.contain('zaphod');
		expect(outputObject).to.contain('president');
	});

	it('collection method should have the correct number of output elements', function() {
		expect(outputCollection).to.have.length(3);
	});

	it('collection method should contain the expected output', function() {
		expect(outputCollection).to.contain({one: 'Number 1'});
		expect(outputCollection).to.contain({two: 'Number 2'});
		expect(outputCollection).to.contain({three: 'Number 3'});
	});
});
<commit_msg>Added test for out-of-order forEach completion<commit_after>var expect = require('chai').expect;
var asyncChainable = require('../index');

describe('async-chainable.forEach() - array style', function(){
	var output;

	before(function(done) {
		output = [];

		asyncChainable()
			.forEach(['foo', 'bar', 'baz'], function(next, item) { output.push(item); next(); })
			.end(function(err) {
				expect(err).to.be.undefined();
				done();
			});
	});

	it('should have the correct number of output elements', function() {
		expect(output).to.have.length(3);
	});

	it('contain the expected output', function() {
		expect(output).to.contain('foo');
		expect(output).to.contain('bar');
		expect(output).to.contain('baz');
	});
});

describe('async-chainable.forEach() - out-of-order style', function(){
	var output;

	before(function(done) {
		output = [];

		asyncChainable()
			.forEach([500, 300, 200, 100, 400], function(next, value) {
				setTimeout(function() {
					output.push(value);
					next();
				}, value);
			})
			.end(function(err) {
				expect(err).to.be.undefined();
				done();
			});
	});

	it('should have the correct number of output elements', function() {
		expect(output).to.have.length(5);
	});

	it('contain the expected output', function() {
		expect(output[0]).to.equal(100);
		expect(output[1]).to.equal(200);
		expect(output[2]).to.equal(300);
		expect(output[3]).to.equal(400);
		expect(output[4]).to.equal(500);
	});
});

describe('async-chainable.forEach() - array style, unlimited', function(){
	var output, running = 0, maxRunning = 0;
	this.timeout(5000);

	before(function(done) {
		output = [];

		asyncChainable()
			.limit(null)
			.forEach(['foo', 'bar', 'baz', 'quz', 'quuz', 'quuuz'], function(next, item) {
				running++;
				if (running > maxRunning) maxRunning = running;
				setTimeout(function() {
					running--;
					output.push(item);
					next();
				}, Math.random() * 500)
			})
			.end(function(err) {
				expect(err).to.be.undefined();
				done();
			});
	});

	it('should have the correct number of output elements', function() {
		expect(output).to.have.length(6);
	});

	it('contain the expected output', function() {
		expect(output).to.contain('foo');
		expect(output).to.contain('bar');
		expect(output).to.contain('baz');
		expect(output).to.contain('quz');
		expect(output).to.contain('quuz');
		expect(output).to.contain('quuuz');
	});

	it('should have no threads left over', function() {
		expect(running).to.equal(0);
	});

	it('upper limit of 6 running threads', function() {
		expect(maxRunning).to.equal(6);
	});
});

describe('async-chainable.forEach() - array style, limited', function(){
	var output, running = 0, maxRunning = 0;
	this.timeout(5000);

	before(function(done) {
		output = [];

		asyncChainable()
			.limit(2)
			.forEach(['foo', 'bar', 'baz', 'quz', 'quuz', 'quuuz'], function(next, item) {
				running++;
				if (running > maxRunning) maxRunning = running;
				setTimeout(function() {
					running--;
					output.push(item);
					next();
				}, Math.random() * 500)
			})
			.end(function(err) {
				expect(err).to.be.undefined();
				done();
			});
	});

	it('should have the correct number of output elements', function() {
		expect(output).to.have.length(6);
	});

	it('contain the expected output', function() {
		expect(output).to.contain('foo');
		expect(output).to.contain('bar');
		expect(output).to.contain('baz');
		expect(output).to.contain('quz');
		expect(output).to.contain('quuz');
		expect(output).to.contain('quuuz');
	});

	it('should have no threads left over', function() {
		expect(running).to.equal(0);
	});

	it('limit to 2 running threads', function() {
		expect(maxRunning).to.equal(2);
	});
});

describe('async-chainable.forEach() - object style', function(){
	var context;
	var output;

	before(function(done) {
		context = {};
		output = [];

		asyncChainable()
			.forEach({fooKey: 'fooValue', barKey: 'barValue', bazKey: 'bazValue'}, function(next, item, key) { output.push(item, key); next(null, item); })
			.end(function(err) {
				expect(err).to.be.undefined();
				context = this;
				done();
			});
	});

	it('should have the correct number of output elements', function() {
		expect(output).to.have.length(6);
	});

	it('contain the expected output', function() {
		expect(output).to.contain('fooKey');
		expect(output).to.contain('fooValue');
		expect(output).to.contain('barKey');
		expect(output).to.contain('barValue');
		expect(output).to.contain('bazKey');
		expect(output).to.contain('bazValue');
	});

	it('should set the context', function() {
		expect(context).to.have.property('fooKey');
		expect(context.fooKey).to.equal('fooValue');

		expect(context).to.have.property('barKey');
		expect(context.barKey).to.equal('barValue');

		expect(context).to.have.property('bazKey');
		expect(context.bazKey).to.equal('bazValue');
	});
});

describe('async-chainable.forEach() - collection style', function(){
	var output;

	before(function(done) {
		context = {};
		output = [];

		asyncChainable()
			.forEach([
				{foo: 'Foo!', crash: 'Crash!'},
				{bar: 'Bar!', bang: 'Bang!'},
				{baz: 'Baz!', wallop: 'Wallop!'},
			], function(next, item) { output.push(item); next(null, item); })
			.end(function(err) {
				expect(err).to.be.undefined();
				done();
			});
	});

	it('should have the correct number of output elements', function() {
		expect(output).to.have.length(3);
	});

	it('contain the expected output', function() {
		expect(output).to.contain({foo: 'Foo!', crash: 'Crash!'});
		expect(output).to.contain({bar: 'Bar!', bang: 'Bang!'});
		expect(output).to.contain({baz: 'Baz!', wallop: 'Wallop!'});
	});
});

describe('async-chainable.forEach() - this._key + this._item', function(){
	var output;

	before(function(done) {
		output = [];

		asyncChainable()
			.forEach({
				fooKey: 'fooValue',
				barKey: 'barValue',
				bazKey: 'bazValue',
			}, function(next, item, key) { output.push(this._item, this._key); next(); })
			.end(function(err) {
				expect(err).to.be.undefined();
				done();
			});
	});

	it('should have the correct number of output elements', function() {
		expect(output).to.have.length(6);
	});

	it('contain the expected output', function() {
		expect(output).to.contain('fooKey');
		expect(output).to.contain('fooValue');
		expect(output).to.contain('barKey');
		expect(output).to.contain('barValue');
		expect(output).to.contain('bazKey');
		expect(output).to.contain('bazValue');
	});
});

describe('async-chainable.forEach() - named set', function(){
	var outputArray, outputObject, outputCollection;

	before(function(done) {
		outputArray = [];
		outputObject = [];
		outputCollection = [];

		asyncChainable()
			.set({
				items: ['foo', 'bar', 'baz'],
				hitchhikers: {
					arthur: 'british',
					ford: 'froody',
					zaphod: 'president'
				},
				numbers: [
					{one: 'Number 1'},
					{two: 'Number 2'},
					{three: 'Number 3'},
				],
			})
			.forEach('items', function(next, item) { // Array form
				outputArray.push(item);
				next();
			})
			.forEach('hitchhikers', function(next, item, key) { // Object form
				outputObject.push(item, key);
				next();
			})
			.forEach('numbers', function(next, item) { // Collection form
				outputCollection.push(item);
				next();
			})

			// Finish
			.end(function(err) {
				expect(err).to.be.undefined();
				done();
			});
	});

	it('array method should have the correct number of output elements', function() {
		expect(outputArray).to.have.length(3);
	});

	it('array method should contain the expected output', function() {
		expect(outputArray).to.contain('foo');
		expect(outputArray).to.contain('bar');
		expect(outputArray).to.contain('baz');
	});

	it('object method should have the correct number of output elements', function() {
		expect(outputObject).to.have.length(6);
	});

	it('object method should contain the expected output', function() {
		expect(outputObject).to.contain('arthur');
		expect(outputObject).to.contain('british');
		expect(outputObject).to.contain('ford');
		expect(outputObject).to.contain('froody');
		expect(outputObject).to.contain('zaphod');
		expect(outputObject).to.contain('president');
	});

	it('collection method should have the correct number of output elements', function() {
		expect(outputCollection).to.have.length(3);
	});

	it('collection method should contain the expected output', function() {
		expect(outputCollection).to.contain({one: 'Number 1'});
		expect(outputCollection).to.contain({two: 'Number 2'});
		expect(outputCollection).to.contain({three: 'Number 3'});
	});
});
<|endoftext|>


<commit_before>const assert = require('assert')
const jsonApiTestServer = require('../example/server')

const Lokka = require('lokka').Lokka
const Transport = require('lokka-transport-http').Transport
const client = new Lokka({
  transport: new Transport('http://localhost:16006/rest/')
})

describe('Testing jsonapi-server graphql', () => {
  describe('read operations', () => {
    it('filter with primary join and filter', () => client.query(`
      {
        photos(width: "<1000") {
          url
          width
          photographer(firstname: "Rahul") {
            firstname
          }
        }
      }
    `).then(result => {
      assert.deepEqual(result, {
        'photos': [
          {
            'url': 'http://www.example.com/penguins',
            'width': 60,
            'photographer': null
          },
          {
            'url': 'http://www.example.com/treat',
            'width': 350,
            'photographer': {
              'firstname': 'Rahul'
            }
          }
        ]
      })
    }))

    it('filter with foreign join and filter', () => client.query(`
      {
        people(firstname: "Rahul") {
          firstname
          photos(width: "<1000") {
            url
            width
          }
        }
      }
    `).then(result => {
      assert.deepEqual(result, {
        'people': [
          {
            'firstname': 'Rahul',
            'photos': [
              {
                'url': 'http://www.example.com/treat',
                'width': 350
              }
            ]
          }
        ]
      })
    }))
  })

  describe('write operations', () => {
    let tagId = null

    it('create a tag', () => client.mutate(`
      {
        createTags(tags: {
          name: "test1"
          parent: {
            id: "7541a4de-4986-4597-81b9-cf31b6762486"
          }
        }) {
          id
          name
          parent {
            id
            name
          }
        }
      }
    `).then(result => {
      assert.equal(result.createTags.name, 'test1')
      assert.equal(result.createTags.parent.id, '7541a4de-4986-4597-81b9-cf31b6762486')
      assert.equal(result.createTags.parent.name, 'live')
      tagId = result.createTags.id
    }))

    it('update the new tag', () => client.mutate(`
      {
        updateTags(tags: {
          id: "${tagId}"
          name: "test2"
          parent: {
            id: "68538177-7a62-4752-bc4e-8f971d253b42"
          }
        }) {
          id
          name
          parent {
            id
            name
          }
        }
      }
    `).then(result => {
      assert.deepEqual(result, {
        updateTags: {
          id: tagId,
          name: 'test2',
          parent: {
            id: '68538177-7a62-4752-bc4e-8f971d253b42',
            name: 'development'
          }
        }
      })
    }))

    it('deletes the tag', () => client.mutate(`
      {
        deleteTags(id: "${tagId}") {
          name
        }
      }
    `).then(result => {
      assert.deepEqual(result, {
        'deleteTags': {
          'name': 'test2'
        }
      })
    }))

    it('really is gone', () => client.query(`
      {
        tags(id: "${tagId}") {
          name
        }
      }
    `).then(result => {
      assert.deepEqual(result, {
        'tags': [ ]
      })
    }))
  })

  before(() => {
    jsonApiTestServer.start()
  })
  after(() => {
    jsonApiTestServer.close()
  })
})
<commit_msg>Fix linting whitespace<commit_after>const assert = require('assert')
const jsonApiTestServer = require('../example/server')

const Lokka = require('lokka').Lokka
const Transport = require('lokka-transport-http').Transport
const client = new Lokka({
  transport: new Transport('http://localhost:16006/rest/')
})

describe('Testing jsonapi-server graphql', () => {
  describe('read operations', () => {
    it('filter with primary join and filter', () => client.query(`
      {
        photos(width: "<1000") {
          url
          width
          photographer(firstname: "Rahul") {
            firstname
          }
        }
      }
    `).then(result => {
      assert.deepEqual(result, {
        'photos': [
          {
            'url': 'http://www.example.com/penguins',
            'width': 60,
            'photographer': null
          },
          {
            'url': 'http://www.example.com/treat',
            'width': 350,
            'photographer': {
              'firstname': 'Rahul'
            }
          }
        ]
      })
    }))

    it('filter with foreign join and filter', () => client.query(`
      {
        people(firstname: "Rahul") {
          firstname
          photos(width: "<1000") {
            url
            width
          }
        }
      }
    `).then(result => {
      assert.deepEqual(result, {
        'people': [
          {
            'firstname': 'Rahul',
            'photos': [
              {
                'url': 'http://www.example.com/treat',
                'width': 350
              }
            ]
          }
        ]
      })
    }))
  })

  describe('write operations', () => {
    let tagId = null

    it('create a tag', () => client.mutate(`
      {
        createTags(tags: {
          name: "test1"
          parent: {
            id: "7541a4de-4986-4597-81b9-cf31b6762486"
          }
        }) {
          id
          name
          parent {
            id
            name
          }
        }
      }
    `).then(result => {
      assert.equal(result.createTags.name, 'test1')
      assert.equal(result.createTags.parent.id, '7541a4de-4986-4597-81b9-cf31b6762486')
      assert.equal(result.createTags.parent.name, 'live')
      tagId = result.createTags.id
    }))

    it('update the new tag', () => client.mutate(`
      {
        updateTags(tags: {
          id: "${tagId}"
          name: "test2"
          parent: {
            id: "68538177-7a62-4752-bc4e-8f971d253b42"
          }
        }) {
          id
          name
          parent {
            id
            name
          }
        }
      }
    `).then(result => {
      assert.deepEqual(result, {
        updateTags: {
          id: tagId,
          name: 'test2',
          parent: {
            id: '68538177-7a62-4752-bc4e-8f971d253b42',
            name: 'development'
          }
        }
      })
    }))

    it('deletes the tag', () => client.mutate(`
      {
        deleteTags(id: "${tagId}") {
          name
        }
      }
    `).then(result => {
      assert.deepEqual(result, {
        'deleteTags': {
          'name': 'test2'
        }
      })
    }))

    it('really is gone', () => client.query(`
      {
        tags(id: "${tagId}") {
          name
        }
      }
    `).then(result => {
      assert.deepEqual(result, {
        'tags': [ ]
      })
    }))
  })

  before(() => {
    jsonApiTestServer.start()
  })
  after(() => {
    jsonApiTestServer.close()
  })
})
<|endoftext|>


<commit_before>'use strict';

var jetUtils = require('../utils');
var fetchCommon = require('../fetch-common');
var Elements = require('../element').Elements;
var Bluebird = require('bluebird');
var isDef = jetUtils.isDefined;

var globalFetchId = 1;

var createFetchDispatcher = function (params, f, ref) {
	if (isDef(params.sort)) {
		if (params.sort.asArray) {
			delete params.sort.asArray; // peer internal param
			var arr = [];
			var from = params.sort.from;
			return function (message) {
				arr.length = message.params.n;
				message.params.changes.forEach(function (change) {
					arr[change.index - from] = change;
				});
				f.call(ref, arr, ref);
			};
		} else {
			return function (message) {
				f.call(ref, message.params.changes, message.params.n);
			};
		}
	} else {
		return function (message) {
			f.call(ref, message.params);
		};
	}
};

var FakePeer = function () {
	this.fetchers = {};
	this.id = 'fakePeer';
	var eachFetcherIterator = jetUtils.eachKeyValue(this.fetchers);
	this.eachFetcher = function (element, f) {
		eachFetcherIterator(f);
	};
};

FakePeer.prototype.addFetcher = function (fetchId, fetcher) {
	this.fetchers[fetchId] = fetcher;
};

FakePeer.prototype.removeFetcher = function (fetchId) {
	delete this.fetchers[fetchId];
};

FakePeer.prototype.hasFetcher = function (fetchId) {
	return this.fetchers[fetchId] && true || false;
};

/**
 * FakeFetcher
 *
 * Mimiks normal "fetch" API when the Daemon runs
 * fetch = 'simple' mode. In this case, the Daemon supports
 * only one "fetch all" per Peer.
 * Filtering (value and/or path based) and sorting are handled
 * by the peer.
 *
 * Normally only embedded systems with very limited resources
 * run the fetch = 'simple' mode.
 */
var FakeFetcher = function (jsonrpc, fetchParams, fetchCb) {

	var id = '__f__' + globalFetchId;
	++globalFetchId;

	fetchParams.id = id;

	var fetchDispatcher;

	var wrappedFetchDispatcher = function (nparams) {
		fetchDispatcher = fetchDispatcher || createFetchDispatcher(fetchParams, fetchCb, this);
		fetchDispatcher({
			params: nparams
		});
	};

	if (FakeFetcher.elements === undefined) {
		FakeFetcher.elements = new Elements();
		FakeFetcher.peer = new FakePeer();

		var fetchSimpleDispatcher = function (message) {
			var params = message.params;
			var event = params.event;

			if (event === 'remove') {
				fetchCommon.removeCore(FakeFetcher.peer, FakeFetcher.elements, params);
			} else if (event === 'add') {
				fetchCommon.addCore(FakeFetcher.peer, FakeFetcher.peer.eachFetcher, FakeFetcher.elements, params);
			} else {
				fetchCommon.changeCore(FakeFetcher.peer, FakeFetcher.elements, params);
			}
		};

		FakeFetcher.fetchAllPromise = new Bluebird(function (resolve, reject) {
			jsonrpc.service('fetch', {}, function (ok, fetchSimpleId) {
				jsonrpc.addRequestDispatcher(fetchSimpleId, fetchSimpleDispatcher);
			}).then(function () {
				setTimeout(resolve, 50); // wait some time to let the FakeFetcher.elements get filled
			}).catch(reject);
		});
	}

	this.fetch = function () {
		return FakeFetcher.fetchAllPromise.then(function () {
			return fetchCommon.fetchCore(FakeFetcher.peer, FakeFetcher.elements, fetchParams, wrappedFetchDispatcher);
		});
	};

	this.unfetch = function () {
		return FakeFetcher.fetchAllPromise.then(function () {
			return fetchCommon.unfetchCore(FakeFetcher.peer, FakeFetcher.elements, fetchParams);
		});
	};

	this.isFetching = function () {
		return FakeFetcher.peer.hasFetcher(fetchParams.id);
	};

};

/**
 * Fetcher
 *
 * Sets up a new fetcher. Fetching is very similiar to pub-sub.
 * You can optionally define path- and/or value-based filters
 * and sorting criteria.
 *
 * All options are available at http://jetbus.io.
 */
var Fetcher = function (jsonrpc, params, fetchCb) {
	var id = '__f__' + globalFetchId;
	params.id = id;
	++globalFetchId;

	var fetchDispatcher = createFetchDispatcher(params, fetchCb, this);

	var addFetchDispatcher = function () {
		jsonrpc.addRequestDispatcher(id, fetchDispatcher);
	};

	var removeFetchDispatcher = function () {
		jsonrpc.removeRequestDispatcher(id);
	};

	this.unfetch = function () {
		return jsonrpc.service('unfetch', {
			id: id
		}, removeFetchDispatcher);
	};

	this.isFetching = function () {
		return jsonrpc.hasRequestDispatcher(id);
	};

	this.fetch = function () {
		return jsonrpc.service('fetch', params, addFetchDispatcher);
	};

};

module.exports = {
	FakeFetcher: FakeFetcher,
	Fetcher: Fetcher
};<commit_msg>setup fetch-all once per jsonrpc<commit_after>'use strict';

var jetUtils = require('../utils');
var fetchCommon = require('../fetch-common');
var Elements = require('../element').Elements;
var Bluebird = require('bluebird');
var isDef = jetUtils.isDefined;

var globalFetchId = 1;

var createFetchDispatcher = function (params, f, ref) {
	if (isDef(params.sort)) {
		if (params.sort.asArray) {
			delete params.sort.asArray; // peer internal param
			var arr = [];
			var from = params.sort.from;
			return function (message) {
				arr.length = message.params.n;
				message.params.changes.forEach(function (change) {
					arr[change.index - from] = change;
				});
				f.call(ref, arr, ref);
			};
		} else {
			return function (message) {
				f.call(ref, message.params.changes, message.params.n);
			};
		}
	} else {
		return function (message) {
			f.call(ref, message.params);
		};
	}
};

var FakePeer = function () {
	this.fetchers = {};
	this.id = 'fakePeer';
	var eachFetcherIterator = jetUtils.eachKeyValue(this.fetchers);
	this.eachFetcher = function (element, f) {
		eachFetcherIterator(f);
	};
};

FakePeer.prototype.addFetcher = function (fetchId, fetcher) {
	this.fetchers[fetchId] = fetcher;
};

FakePeer.prototype.removeFetcher = function (fetchId) {
	delete this.fetchers[fetchId];
};

FakePeer.prototype.hasFetcher = function (fetchId) {
	return this.fetchers[fetchId] && true || false;
};

/**
 * FakeFetcher
 *
 * Mimiks normal "fetch" API when the Daemon runs
 * fetch = 'simple' mode. In this case, the Daemon supports
 * only one "fetch all" per Peer.
 * Filtering (value and/or path based) and sorting are handled
 * by the peer.
 *
 * Normally only embedded systems with very limited resources
 * run the fetch = 'simple' mode.
 */
var FakeFetcher = function (jsonrpc, fetchParams, fetchCb) {

	var id = '__f__' + globalFetchId;
	++globalFetchId;

	fetchParams.id = id;

	var fetchDispatcher;

	var wrappedFetchDispatcher = function (nparams) {
		fetchDispatcher = fetchDispatcher || createFetchDispatcher(fetchParams, fetchCb, this);
		fetchDispatcher({
			params: nparams
		});
	};

	if (jsonrpc.fakeContext === undefined) {
		var context = jsonrpc.fakeContext = {};
		context.elements = new Elements();
		context.peer = new FakePeer();

		var fetchSimpleDispatcher = function (message) {
			var params = message.params;
			var event = params.event;

			if (event === 'remove') {
				fetchCommon.removeCore(context.peer, context.elements, params);
			} else if (event === 'add') {
				fetchCommon.addCore(context.peer, context.peer.eachFetcher, context.elements, params);
			} else {
				fetchCommon.changeCore(context.peer, context.elements, params);
			}
		};

		context.fetchAllPromise = new Bluebird(function (resolve, reject) {
			jsonrpc.service('fetch', {}, function (ok, fetchSimpleId) {
				jsonrpc.addRequestDispatcher(fetchSimpleId, fetchSimpleDispatcher);
			}).then(function () {
				setTimeout(resolve, 50); // wait some time to let the FakeFetcher.elements get filled
			}).catch(reject);
		});
	}

	this.fetch = function () {
		var context = jsonrpc.fakeContext;
		return context.fetchAllPromise.then(function () {
			return fetchCommon.fetchCore(context.peer, context.elements, fetchParams, wrappedFetchDispatcher);
		});
	};

	this.unfetch = function () {
		var context = jsonrpc.fakeContext;
		return context.fetchAllPromise.then(function () {
			return fetchCommon.unfetchCore(context.peer, context.elements, fetchParams);
		});
	};

	this.isFetching = function () {
		var context = jsonrpc.fakeContext;
		return context.peer.hasFetcher(fetchParams.id);
	};

};

/**
 * Fetcher
 *
 * Sets up a new fetcher. Fetching is very similiar to pub-sub.
 * You can optionally define path- and/or value-based filters
 * and sorting criteria.
 *
 * All options are available at http://jetbus.io.
 */
var Fetcher = function (jsonrpc, params, fetchCb) {
	var id = '__f__' + globalFetchId;
	params.id = id;
	++globalFetchId;

	var fetchDispatcher = createFetchDispatcher(params, fetchCb, this);

	var addFetchDispatcher = function () {
		jsonrpc.addRequestDispatcher(id, fetchDispatcher);
	};

	var removeFetchDispatcher = function () {
		jsonrpc.removeRequestDispatcher(id);
	};

	this.unfetch = function () {
		return jsonrpc.service('unfetch', {
			id: id
		}, removeFetchDispatcher);
	};

	this.isFetching = function () {
		return jsonrpc.hasRequestDispatcher(id);
	};

	this.fetch = function () {
		return jsonrpc.service('fetch', params, addFetchDispatcher);
	};

};

module.exports = {
	FakeFetcher: FakeFetcher,
	Fetcher: Fetcher
};<|endoftext|>


<commit_before>'use strict';

var $$ = module.exports = {};

// UTILITY METHODS
////////////////////////////////////////////////////////////////////////////////

// <object> $$.extend(receiver, *sources)
//
// Copy all of the properties in the source objects over to the target object.
// It's in-order, so the last source will override properties of the same name
// in previous arguments.
//
// Example: var o = $$.extend({}, a, b, c);
$$.extend = function extend(receiver) {
  var i, l, key, skip = [];

  receiver = receiver || {};
  l = arguments.length;

  if (!!arguments[l - 1] && !!arguments[l - 1].except) {
    skip = arguments[l - 1].except;
    l -= 1;
  }

  for (i = 1; i < l; i++) {
    if ('object' === typeof arguments[i]) {
      for (key in arguments[i]) {
        if (arguments[i].hasOwnProperty(key) && -1 === skip.indexOf(key)) {
          receiver[key] = arguments[i][key];
        }
      }
    }
  }

  return receiver;
};

// simple inheritance algorithm
$$.inherits = function inherits(child, parent) {
  var InheritanceGlue = function(){};

  InheritanceGlue.prototype = parent.prototype;
  child.prototype = new InheritanceGlue();

  // copy parent prototype' methods into child, so mixing made possible
  // think of it as of caching of parent's prototype methods in child
  $$.extend(child.prototype, parent.prototype, {except: [
    'arguments', 'length', 'name', 'prototype', 'caller'
  ]});

  // restore constructor
  $$.extend(child.prototype, {constructor: child});

  child.__parent__ = parent;
};

// wrapper for instanceof that allows to check inheritance after $$.inherits
$$.isInstanceOf = function isInstanceOf(obj, klass) {
  var parent;

  if (obj instanceof klass) {
    return true;
  }

  if (!!obj && !!obj.constructor) {
    parent = obj.constructor.__parent__;
    return (parent === klass || $$.isInstanceOf(parent, klass));
  }

  return false;
};

// iterates through all object keys-value pairs calling iterator on each one
// example: $$.each(objOrArr, function (val, key) { /* ... */ });
$$.each = function each(obj, iterator, context) {
  var keys, i, l;

  if (null === obj || undefined === obj) {
    return;
  }

  context = context || iterator;

  if (obj.forEach === Array.prototype.forEach) {
    obj.forEach(iterator, context);
  } else {
    keys = Object.getOwnPropertyNames(obj);
    for (i = 0, l = keys.length; i < l; i++) {
      iterator.call(context, obj[keys[i]], keys[i], obj);
    }
  }
};

// returns reversed copy of array
$$.reverse = function reverse(arr) {
  var result = [], i, l;
  for (i = 0, l = arr.length; i < l; i++) {
    result.unshift(arr[i]);
  }
  return result;
};

// Modified from:
// https://raw.github.com/kanaka/noVNC/d890e8640f20fba3215ba7be8e0ff145aeb8c17c/include/base64.js
$$.decodeBase64 = (function () {
  var padding = '=', binTable = [
    -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
    -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
    -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,62, -1,-1,-1,63,
    52,53,54,55, 56,57,58,59, 60,61,-1,-1, -1, 0,-1,-1,
    -1, 0, 1, 2,  3, 4, 5, 6,  7, 8, 9,10, 11,12,13,14,
    15,16,17,18, 19,20,21,22, 23,24,25,-1, -1,-1,-1,-1,
    -1,26,27,28, 29,30,31,32, 33,34,35,36, 37,38,39,40,
    41,42,43,44, 45,46,47,48, 49,50,51,-1, -1,-1,-1,-1
  ];

  return function decode(data) {
    var value, code, idx = 0, result = [],
        leftbits = 0, // number of bits decoded, but yet to be appended
        leftdata = 0; // bits decoded, but yet to be appended

    // Convert one by one.
    for (idx = 0; idx < data.length; idx++) {
      code = data.charCodeAt(idx);
      value = binTable[code & 0x7F];

      // Skip LF(NL) || CR
      if (0x0A !== code && 0x0D !== code) {
        // Fail on illegal characters
        if (-1 === value) {
          throw new Error("Illegal characters (code=" + code + ") in position " +
                          idx + ": ordinal not in range(0..128)");
        }

        // Collect data into leftdata, update bitcount
        leftdata = (leftdata << 6) | value;
        leftbits += 6;

        // If we have 8 or more bits, append 8 bits to the result
        if (leftbits >= 8) {
          leftbits -= 8;
          // Append if not padding.
          if (padding !== data.charAt(idx)) {
            result.push((leftdata >> leftbits) & 0xFF);
          }
          leftdata &= (1 << leftbits) - 1;
        }
      }
    }

    // If there are any bits left, the base64 string was corrupted
    if (leftbits) {
      throw new Error("Corrupted base64 string");
    }

    return new Buffer(result);
  };
}());

// CLASSES
////////////////////////////////////////////////////////////////////////////////

// Dummy alternative of delayed population based on generators in PyYAML
$$.Populator = function Populator(data, callback, context) {
  if (!(this instanceof $$.Populator)) {
    return new $$.Populator(data, callback, context);
  }

  this.data = data;
  this.execute = function () {
    callback.call(context || callback);
  };
};

// Simple implementation of hashtable
$$.Hash = function Hash(defaultValue) {
  var keys, values, index;

  if (!(this instanceof $$.Hash)) {
    return new $$.Hash(defaultValue);
  }

  index = 0;
  keys = [];
  values = [];

  this.store = function store(key, value) {
    var i = keys.indexOf(key);

    if (0 <= i) {
      values[i] = value;
      return;
    }

    i = index;
    index += 1;

    keys[i] = key;
    values[i] = value;
  };

  this.remove = function remove(key) {
    var i = keys.indexOf(key);

    if (0 <= i) {
      delete keys[i];
      delete values[i];
    }
  };

  this.hasKey = function hasKey(key) {
    return 0 <= keys.indexOf(key);
  };

  this.get = function get(key) {
    var i = keys.indexOf(key);
    return (0 <= i) ? values[i] : defaultValue;
  };
};

////////////////////////////////////////////////////////////////////////////////
// vim:ts=2:sw=2
////////////////////////////////////////////////////////////////////////////////
<commit_msg>Adds $$.bind() helper<commit_after>'use strict';

var $$ = module.exports = {};

// UTILITY METHODS
////////////////////////////////////////////////////////////////////////////////

// returns new function bound to given context
var nativeBind = Function.prototype.bind;
$$.bind = function bind(func, context) {
  if (nativeBind && func.bind === nativeBind) {
    return func.bind(context);
  }

  if ('function' !== typeof func) {
    throw new TypeError;
  }

  return function bound() {
    func.apply(context, arguments);
  };
};

// <object> $$.extend(receiver, *sources)
//
// Copy all of the properties in the source objects over to the target object.
// It's in-order, so the last source will override properties of the same name
// in previous arguments.
//
// Example: var o = $$.extend({}, a, b, c);
$$.extend = function extend(receiver) {
  var i, l, key, skip = [];

  receiver = receiver || {};
  l = arguments.length;

  if (!!arguments[l - 1] && !!arguments[l - 1].except) {
    skip = arguments[l - 1].except;
    l -= 1;
  }

  for (i = 1; i < l; i++) {
    if ('object' === typeof arguments[i]) {
      for (key in arguments[i]) {
        if (arguments[i].hasOwnProperty(key) && -1 === skip.indexOf(key)) {
          receiver[key] = arguments[i][key];
        }
      }
    }
  }

  return receiver;
};

// simple inheritance algorithm
$$.inherits = function inherits(child, parent) {
  var InheritanceGlue = function(){};

  InheritanceGlue.prototype = parent.prototype;
  child.prototype = new InheritanceGlue();

  // copy parent prototype' methods into child, so mixing made possible
  // think of it as of caching of parent's prototype methods in child
  $$.extend(child.prototype, parent.prototype, {except: [
    'arguments', 'length', 'name', 'prototype', 'caller'
  ]});

  // restore constructor
  $$.extend(child.prototype, {constructor: child});

  child.__parent__ = parent;
};

// wrapper for instanceof that allows to check inheritance after $$.inherits
$$.isInstanceOf = function isInstanceOf(obj, klass) {
  var parent;

  if (obj instanceof klass) {
    return true;
  }

  if (!!obj && !!obj.constructor) {
    parent = obj.constructor.__parent__;
    return (parent === klass || $$.isInstanceOf(parent, klass));
  }

  return false;
};

// iterates through all object keys-value pairs calling iterator on each one
// example: $$.each(objOrArr, function (val, key) { /* ... */ });
$$.each = function each(obj, iterator, context) {
  var keys, i, l;

  if (null === obj || undefined === obj) {
    return;
  }

  context = context || iterator;

  if (obj.forEach === Array.prototype.forEach) {
    obj.forEach(iterator, context);
  } else {
    keys = Object.getOwnPropertyNames(obj);
    for (i = 0, l = keys.length; i < l; i++) {
      iterator.call(context, obj[keys[i]], keys[i], obj);
    }
  }
};

// returns reversed copy of array
$$.reverse = function reverse(arr) {
  var result = [], i, l;
  for (i = 0, l = arr.length; i < l; i++) {
    result.unshift(arr[i]);
  }
  return result;
};

// Modified from:
// https://raw.github.com/kanaka/noVNC/d890e8640f20fba3215ba7be8e0ff145aeb8c17c/include/base64.js
$$.decodeBase64 = (function () {
  var padding = '=', binTable = [
    -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
    -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
    -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,62, -1,-1,-1,63,
    52,53,54,55, 56,57,58,59, 60,61,-1,-1, -1, 0,-1,-1,
    -1, 0, 1, 2,  3, 4, 5, 6,  7, 8, 9,10, 11,12,13,14,
    15,16,17,18, 19,20,21,22, 23,24,25,-1, -1,-1,-1,-1,
    -1,26,27,28, 29,30,31,32, 33,34,35,36, 37,38,39,40,
    41,42,43,44, 45,46,47,48, 49,50,51,-1, -1,-1,-1,-1
  ];

  return function decode(data) {
    var value, code, idx = 0, result = [],
        leftbits = 0, // number of bits decoded, but yet to be appended
        leftdata = 0; // bits decoded, but yet to be appended

    // Convert one by one.
    for (idx = 0; idx < data.length; idx++) {
      code = data.charCodeAt(idx);
      value = binTable[code & 0x7F];

      // Skip LF(NL) || CR
      if (0x0A !== code && 0x0D !== code) {
        // Fail on illegal characters
        if (-1 === value) {
          throw new Error("Illegal characters (code=" + code + ") in position " +
                          idx + ": ordinal not in range(0..128)");
        }

        // Collect data into leftdata, update bitcount
        leftdata = (leftdata << 6) | value;
        leftbits += 6;

        // If we have 8 or more bits, append 8 bits to the result
        if (leftbits >= 8) {
          leftbits -= 8;
          // Append if not padding.
          if (padding !== data.charAt(idx)) {
            result.push((leftdata >> leftbits) & 0xFF);
          }
          leftdata &= (1 << leftbits) - 1;
        }
      }
    }

    // If there are any bits left, the base64 string was corrupted
    if (leftbits) {
      throw new Error("Corrupted base64 string");
    }

    return new Buffer(result);
  };
}());

// CLASSES
////////////////////////////////////////////////////////////////////////////////

// Dummy alternative of delayed population based on generators in PyYAML
$$.Populator = function Populator(data, callback, context) {
  if (!(this instanceof $$.Populator)) {
    return new $$.Populator(data, callback, context);
  }

  this.data = data;
  this.execute = function () {
    callback.call(context || callback);
  };
};

// Simple implementation of hashtable
$$.Hash = function Hash(defaultValue) {
  var keys, values, index;

  if (!(this instanceof $$.Hash)) {
    return new $$.Hash(defaultValue);
  }

  index = 0;
  keys = [];
  values = [];

  this.store = function store(key, value) {
    var i = keys.indexOf(key);

    if (0 <= i) {
      values[i] = value;
      return;
    }

    i = index;
    index += 1;

    keys[i] = key;
    values[i] = value;
  };

  this.remove = function remove(key) {
    var i = keys.indexOf(key);

    if (0 <= i) {
      delete keys[i];
      delete values[i];
    }
  };

  this.hasKey = function hasKey(key) {
    return 0 <= keys.indexOf(key);
  };

  this.get = function get(key) {
    var i = keys.indexOf(key);
    return (0 <= i) ? values[i] : defaultValue;
  };
};

////////////////////////////////////////////////////////////////////////////////
// vim:ts=2:sw=2
////////////////////////////////////////////////////////////////////////////////
<|endoftext|>