<commit_before>(function () {
'use strict';

angular.module('alAngularHeroRamjet', ['ngAnimate'])
    .animation('.hero-ramjet-transition', [function () {

        var _fromScreen, _toScreen, _doneList, _startTimer, _movingList;

        // Capture the screen that is transitioning in
        var enter = function enter(screen, done) {
            _toScreen = screen;
            _doneList.push(done);
            return tryStart();
        };

        // Capture the screen that is transitioning out
        var leave = function leave(screen, done) {
            _fromScreen = screen;
            _doneList.push(done);

            screen.addClass('hero-leave');
            return tryStart();
        };

        // If we have both screens then trigger the transition
        var tryStart = function tryStart() {
            if (!_fromScreen || !_toScreen) {
                // Allow time to get a second screen, or else cancel
                _startTimer = setTimeout(function () { finish(true); });
                return null;
            } else {
                if (_startTimer) clearTimeout(_startTimer);

                // Both screens, so start now
                setTimeout(start);

                // Return a cancel function, which should only call clear once
                var cancelled = false;
                return function () {
                    if (!cancelled) {
                        cancelled = true;
                        clear();
                    }
                };
            }
        };

        // Start the hero transitions
        var start = function start() {
            // Get hero elements from both screens
            var fromHeros = _fromScreen[0].getElementsByClassName("hero-ramjet");
            var toHeros = _toScreen[0].getElementsByClassName("hero-ramjet");

            // Find all the matching pairs
            var pairs = [];
            for (var n = 0; n < fromHeros.length; n++) {
                for (var m = 0; m < toHeros.length; m++) {
                    if (fromHeros[n].getAttribute('hero-id') === toHeros[m].getAttribute('hero-id')) {
                        pairs.push({ from: fromHeros[n], to: toHeros[m] });
                    }
                }
            }

            // Trigger the animation for each pair
            pairs.forEach(function (pair) {
                animateHero(pair.from, pair.to);
            });

            finish();
        };

        // Animate a hero element from one position to another
        var animateHero = function animateHero(fromHero, toHero) {
          ramjet.hide(fromHero);
          ramjet.hide(toHero);
          var handler = {
            complete: false,
            onComplete: function() {
              handler.complete = true;
              finish();
            },
            remove: function() {
              ramjet.show(fromHero);
              ramjet.show(toHero);
            }
          };
          _movingList.push(handler);
          ramjet.transform(fromHero, toHero, {
            done: handler.onComplete
          });
        };

        // Finish up if all elements have finished animating
        var finish = function finish(cancelled) {
            // Check that all the moving elements are complete
            var allComplete = true;
            if (!cancelled) {
                _movingList.forEach(function (m) { allComplete = allComplete && m.complete; });
            }

            if (allComplete) {
                // Call "done" on both screens (which may call "clear" so clone the array)
                var doneCallbacks = _doneList.slice(0);
                doneCallbacks.forEach(function (done) { done(); });
                // Make sure we've cleared for the next time
                clear();
            }
        };

        // Clear everything down and initialise for next time
        var clear = function clear() {
            _fromScreen = null;
            _toScreen = null;
            _doneList = [];

            // Call remove for each animating hero element
            if (_movingList) _movingList.forEach(function (m) { m.remove(); });
            _movingList = [];
        };
        clear();

        // Definition of the AngularJS animation
        return {
            enter: function (element, done) {
                return enter(element, done);
            },
            leave: function (element, done) {
                return leave(element, done);
            }
        };
    }]);
})();
<commit_msg>Add classes during animiation.<commit_after>(function () {
'use strict';

angular.module('alAngularHeroRamjet', ['ngAnimate'])
    .animation('.hero-ramjet-transition', [function () {

        var _fromScreen, _toScreen, _doneList, _startTimer, _movingList;

        // Capture the screen that is transitioning in
        var enter = function enter(screen, done) {
            _toScreen = screen;
            _doneList.push(done);
            return tryStart();
        };

        // Capture the screen that is transitioning out
        var leave = function leave(screen, done) {
            _fromScreen = screen;
            _doneList.push(done);

            screen.addClass('hero-leave');
            return tryStart();
        };

        // If we have both screens then trigger the transition
        var tryStart = function tryStart() {
            if (!_fromScreen || !_toScreen) {
                // Allow time to get a second screen, or else cancel
                _startTimer = setTimeout(function () { finish(true); });
                return null;
            } else {
                if (_startTimer) clearTimeout(_startTimer);

                // Both screens, so start now
                setTimeout(start);

                // Return a cancel function, which should only call clear once
                var cancelled = false;
                return function () {
                    if (!cancelled) {
                        cancelled = true;
                        clear();
                    }
                };
            }
        };

        // Start the hero transitions
        var start = function start() {
            _fromScreen.addClass('hero-ramjet-leave');
            _toScreen.addClass('hero-ramjet-enter');

            // Get hero elements from both screens
            var fromHeros = _fromScreen[0].getElementsByClassName("hero-ramjet");
            var toHeros = _toScreen[0].getElementsByClassName("hero-ramjet");

            for (var m = 0; m < toHeros.length; m++) {
                angular.element(toHeros[m]).addClass('hero-ramjet-inactive');
            }

            // Find all the matching pairs
            var pairs = [];
            for (var n = 0; n < fromHeros.length; n++) {
                for (var m = 0; m < toHeros.length; m++) {
                    if (fromHeros[n].getAttribute('hero-id') === toHeros[m].getAttribute('hero-id')) {
                        angular.element(toHeros[m]).removeClass('hero-ramjet-inactive');
                        pairs.push({ from: fromHeros[n], to: toHeros[m] });
                    }
                }
            }

            // Trigger the animation for each pair
            pairs.forEach(function (pair) {
                animateHero(pair.from, pair.to);
            });

            finish();
        };

        // Animate a hero element from one position to another
        var animateHero = function animateHero(fromHero, toHero) {
          ramjet.hide(fromHero);
          ramjet.hide(toHero);
          var handler = {
            complete: false,
            onComplete: function() {
              handler.complete = true;
              finish();
            },
            remove: function() {
              ramjet.show(fromHero);
              ramjet.show(toHero);
            }
          };
          _movingList.push(handler);
          ramjet.transform(fromHero, toHero, {
            done: handler.onComplete
          });
        };

        // Finish up if all elements have finished animating
        var finish = function finish(cancelled) {
            // Check that all the moving elements are complete
            var allComplete = true;
            if (!cancelled) {
                _movingList.forEach(function (m) { allComplete = allComplete && m.complete; });
            }

            if (allComplete) {
                // Call "done" on both screens (which may call "clear" so clone the array)
                var doneCallbacks = _doneList.slice(0);
                doneCallbacks.forEach(function (done) { done(); });
                // Make sure we've cleared for the next time
                clear();
            }
        };

        // Clear everything down and initialise for next time
        var clear = function clear() {
            if (_fromScreen) {
                _fromScreen.removeClass('hero-ramjet-leave');
            }
            if (_toScreen) {
                _toScreen.removeClass('hero-ramjet-enter');
            }

            // TODO(timgreen): remove class 'hero-ramjet-inactive'

            _fromScreen = null;
            _toScreen = null;
            _doneList = [];

            // Call remove for each animating hero element
            if (_movingList) _movingList.forEach(function (m) { m.remove(); });
            _movingList = [];
        };
        clear();

        // Definition of the AngularJS animation
        return {
            enter: function (element, done) {
                return enter(element, done);
            },
            leave: function (element, done) {
                return leave(element, done);
            }
        };
    }]);
})();
<|endoftext|>


<commit_before>// When used as a Meteor package, package-version-parser detects
// Package and believes SemVer410 and _ are available globally.
global.SemVer410 = require('semver');
global._ = require('underscore');

/*
   This code is taken from commands-packages.js file with everything
   except the package building/publishing code removed.
 */

var loadModule = function (Npm) {
  var Fiber = Npm.require('fibers');
  var Future = Npm.require('fibers/future');
  var proxyquire = require('proxyquire').noCallThru();

  // Configure proxyquire to globally override fibers.
  Fiber['@global'] = true;
  Future['@global'] = true;

  var _ = proxyquire('underscore', { fibers: Fiber, 'fibers/future': Future });
  var files = proxyquire('./meteor/tools/files.js', { fibers: Fiber, 'fibers/future': Future });
  var buildmessage = proxyquire('./meteor/tools/buildmessage.js', { fibers: Fiber, 'fibers/future': Future });
  var release = proxyquire('./meteor/tools/release.js', { fibers: Fiber, 'fibers/future': Future });
  var utils = proxyquire('./meteor/tools/utils.js', { fibers: Fiber, 'fibers/future': Future });
  var projectContextModule = proxyquire('./meteor/tools/project-context.js', { fibers: Fiber, 'fibers/future': Future });

  var captureAndExit = function (header, title, f) {
    var messages;
    if (f) {
      messages = buildmessage.capture({ title: title }, f);
    } else {
      messages = buildmessage.capture(title);  // title is really f
    }
    if (messages.hasMessages()) {
      throw new Error(header + "\n" + messages.formatMessages());
    }
  };

  var buildPackage = function (options) {
    if (options.release) {
      options.releaseForConstraints = release.load(options.release);
    }

    var projectContext;
    // We're not in an app? OK, make a temporary app directory, and make sure
    // that the current package directory is found by its local catalog.
    var tempProjectDir = files.mkdtemp('meteor-package-build');
    projectContext = new projectContextModule.ProjectContext(_.extend({
      projectDir: tempProjectDir,  // won't have a packages dir, that's OK
      explicitlyAddedLocalPackageDirs: [options.packageDir],
      packageMapFilename: files.pathJoin(options.packageDir, '.versions'),
      // We always want to write our '.versions' package map, overriding a
      // comparison against the value of a release file that doesn't exist.
      alwaysWritePackageMap: true,
      // When we publish, we should always include web.cordova unibuilds, even
      // though this temporary directory does not have any cordova platforms
      forceIncludeCordovaUnibuild: true
    }, options));

    captureAndExit("=> Errors while initializing project:", function () {
      // Just get up to initializing the catalog. We're going to mutate the
      // constraints file a bit before we prepare the build.
      projectContext.initializeCatalog();
    });

    var localVersionRecord = projectContext.localCatalog.getVersionBySourceRoot(
      options.packageDir);
    if (! localVersionRecord) {
      // OK, we're inside a package (ie, a directory with a package.js) and we're
      // inside an app (ie, a directory with a file named .meteor/packages) but
      // the package is not on the app's search path (ie, it's probably not
      // directly inside the app's packages directory).  That's kind of
      // weird. Let's not allow this.
      throw new Error(
        "The package you are in appears to be inside a Meteor app but is not " +
         "in its packages directory. You may only publish packages that are " +
         "entirely outside of a project or that are loaded by the project " +
         "that they are inside.");
    }
    var packageName = localVersionRecord.packageName;
    var packageSource = projectContext.localCatalog.getPackageSource(packageName);
    if (! packageSource)
      throw Error("no PackageSource for " + packageName);

    // Anything published to the server must explicitly set a version.
    if (! packageSource.versionExplicitlyProvided) {
      throw new Error("A version must be specified for the package. Set it with " +
                    "Package.describe.");
    }

    // Make sure that both the package and its test (if any) are actually built.
    _.each([packageName, packageSource.testName], function (name) {
      if (! name)  // for testName
        return;
      // If we're already using this package, that's OK; no need to override.
      if (projectContext.projectConstraintsFile.getConstraint(name))
        return;
      projectContext.projectConstraintsFile.addConstraints(
        [utils.parsePackageConstraint(name)]);
    });

    // Now resolve constraints and build packages.
    captureAndExit("=> Errors while initializing project:", function () {
      projectContext.prepareProjectForBuild();
    });
    // We don't display the package map delta here, because it includes adding the
    // package's test and all the test's dependencies.

    var isopack = projectContext.isopackCache.getIsopack(packageName);
    if (! isopack) {
      // This shouldn't happen; we already threw a different error if the package
      // wasn't even in the local catalog, and we explicitly added this package to
      // the project's constraints file, so it should have been built.
      throw Error("package not built even though added to constraints?");
    }

    // We have initialized everything, so perform the publish operation.
    var binary = isopack.platformSpecific();

    return {
      projectContext: projectContext,
      packageSource: packageSource,
      binary: binary
    }
  };

  return buildPackage;
};

module.exports = loadModule;
<commit_msg>We have to initialize the catalog.<commit_after>// When used as a Meteor package, package-version-parser detects
// Package and believes SemVer410 and _ are available globally.
global.SemVer410 = require('semver');
global._ = require('underscore');

/*
   This code is taken from commands-packages.js file with everything
   except the package building/publishing code removed.
 */

var loadModule = function (Npm) {
  var Fiber = Npm.require('fibers');
  var Future = Npm.require('fibers/future');
  var proxyquire = require('proxyquire').noCallThru();

  // Configure proxyquire to globally override fibers.
  Fiber['@global'] = true;
  Future['@global'] = true;

  var _ = proxyquire('underscore', { fibers: Fiber, 'fibers/future': Future });
  var files = proxyquire('./meteor/tools/files.js', { fibers: Fiber, 'fibers/future': Future });
  var buildmessage = proxyquire('./meteor/tools/buildmessage.js', { fibers: Fiber, 'fibers/future': Future });
  var release = proxyquire('./meteor/tools/release.js', { fibers: Fiber, 'fibers/future': Future });
  var utils = proxyquire('./meteor/tools/utils.js', { fibers: Fiber, 'fibers/future': Future });
  var catalog = proxyquire('./catalog.js', { fibers: Fiber, 'fibers/future': Future });
  var projectContextModule = proxyquire('./meteor/tools/project-context.js', { fibers: Fiber, 'fibers/future': Future });

  proxyquire('./isopackets.js', { fibers: Fiber, 'fibers/future': Future }).ensureIsopacketsLoadable();

  // Initialize the server catalog.
  catalog.official.initialize({
    offline: !!process.env.METEOR_OFFLINE_CATALOG
  });

  var captureAndExit = function (header, title, f) {
    var messages;
    if (f) {
      messages = buildmessage.capture({ title: title }, f);
    } else {
      messages = buildmessage.capture(title);  // title is really f
    }
    if (messages.hasMessages()) {
      throw new Error(header + "\n" + messages.formatMessages());
    }
  };

  var buildPackage = function (options) {
    if (options.release) {
      options.releaseForConstraints = release.load(options.release);
    }

    var projectContext;
    // We're not in an app? OK, make a temporary app directory, and make sure
    // that the current package directory is found by its local catalog.
    var tempProjectDir = files.mkdtemp('meteor-package-build');
    projectContext = new projectContextModule.ProjectContext(_.extend({
      projectDir: tempProjectDir,  // won't have a packages dir, that's OK
      explicitlyAddedLocalPackageDirs: [options.packageDir],
      packageMapFilename: files.pathJoin(options.packageDir, '.versions'),
      // We always want to write our '.versions' package map, overriding a
      // comparison against the value of a release file that doesn't exist.
      alwaysWritePackageMap: true,
      // When we publish, we should always include web.cordova unibuilds, even
      // though this temporary directory does not have any cordova platforms
      forceIncludeCordovaUnibuild: true
    }, options));

    captureAndExit("=> Errors while initializing project:", function () {
      // Just get up to initializing the catalog. We're going to mutate the
      // constraints file a bit before we prepare the build.
      projectContext.initializeCatalog();
    });

    var localVersionRecord = projectContext.localCatalog.getVersionBySourceRoot(
      options.packageDir);
    if (! localVersionRecord) {
      // OK, we're inside a package (ie, a directory with a package.js) and we're
      // inside an app (ie, a directory with a file named .meteor/packages) but
      // the package is not on the app's search path (ie, it's probably not
      // directly inside the app's packages directory).  That's kind of
      // weird. Let's not allow this.
      throw new Error(
        "The package you are in appears to be inside a Meteor app but is not " +
         "in its packages directory. You may only publish packages that are " +
         "entirely outside of a project or that are loaded by the project " +
         "that they are inside.");
    }
    var packageName = localVersionRecord.packageName;
    var packageSource = projectContext.localCatalog.getPackageSource(packageName);
    if (! packageSource)
      throw Error("no PackageSource for " + packageName);

    // Anything published to the server must explicitly set a version.
    if (! packageSource.versionExplicitlyProvided) {
      throw new Error("A version must be specified for the package. Set it with " +
                    "Package.describe.");
    }

    // Make sure that both the package and its test (if any) are actually built.
    _.each([packageName, packageSource.testName], function (name) {
      if (! name)  // for testName
        return;
      // If we're already using this package, that's OK; no need to override.
      if (projectContext.projectConstraintsFile.getConstraint(name))
        return;
      projectContext.projectConstraintsFile.addConstraints(
        [utils.parsePackageConstraint(name)]);
    });

    // Now resolve constraints and build packages.
    captureAndExit("=> Errors while initializing project:", function () {
      projectContext.prepareProjectForBuild();
    });
    // We don't display the package map delta here, because it includes adding the
    // package's test and all the test's dependencies.

    var isopack = projectContext.isopackCache.getIsopack(packageName);
    if (! isopack) {
      // This shouldn't happen; we already threw a different error if the package
      // wasn't even in the local catalog, and we explicitly added this package to
      // the project's constraints file, so it should have been built.
      throw Error("package not built even though added to constraints?");
    }

    // We have initialized everything, so perform the publish operation.
    var binary = isopack.platformSpecific();

    return {
      projectContext: projectContext,
      packageSource: packageSource,
      binary: binary
    }
  };

  return buildPackage;
};

module.exports = loadModule;
<|endoftext|>


<commit_before>ENDPOINT.Views.SearchResult = Backbone.View.extend({
  template: _.template($("#search-template").html()),

  render: function(){
    var filledTemplate = this.template(this.model.attributes);
    this.$el.html(filledTemplate)
    return this;
  }
})

ENDPOINT.Views.SearchResults = Backbone.View.extend({
  render: function(){
    $("#app-body").append('

');
    //search model is a place holder like in pipes
    this.collection.each(function(searchModel){
      var searchView = new ENDPOINT.Views.SearchResult({model: searchModel});
      $("#search-list").append(searchView.render().$el);
    })
    return this;
  }
})<commit_msg>refactored navigation to API profile page<commit_after>ENDPOINT.Views.SearchResult = Backbone.View.extend({
  template: _.template($("#search-template").html()),

  render: function(){
    var filledTemplate = this.template(this.model.attributes);
    this.$el.html(filledTemplate)
    return this;
  }
})

ENDPOINT.Views.SearchResults = Backbone.View.extend({
  render: function(){
    $("#app-body").append('

');
    //search model is a place holder like in pipes
    this.collection.each(function(searchModel){
      var searchView = new ENDPOINT.Views.SearchResult({model: searchModel});
      $("#search-list").append(searchView.render().$el);
    })
    $(".result").on('click', this.navigateToProfile)
    return this;
  },

  navigateToProfile: function(){
    event.preventDefault();
    var id = this.dataset.id
    ENDPOINT.router.navigate("api/"+id, true)
  }
})<|endoftext|>


<commit_before>"use strict"

var fs = require("fs")
var path = require("path")
var proc = require("child_process")

function read(filepath) {
	try {return fs.readFileSync(filepath, "utf8")} catch (e) {throw new Error("File does not exist: " + filepath)}
}
function isFile(filepath) {
	try {return fs.statSync(filepath).isFile()} catch (e) {return false}
}
function parse(file) {
	var json = read(file)
	try {return JSON.parse(json)} catch (e) {throw new Error("invalid JSON: " + json)}
}

function run(input, output) {
	try {
		var modules = {}
		var bindings = {}
		var declaration = /^\s*(?:var|let|const|function)[\t ]+([\w_$]+)/gm
		var include = /(?:((?:var|let|const|,|)[\t ]*)([\w_$\.\[\]"'`]+)(\s*=\s*))?require\(([^\)]+)\)(\s*[`\.\(\[])?/gm
		var uuid = 0
		var process = function(filepath, data) {
			data.replace(declaration, function(match, binding) {bindings[binding] = 0})

			return data.replace(include, function(match, def, variable, eq, dep, rest) {
				var filename = new Function("return " + dep).call(), pre = ""

				def = def || "", variable = variable || "", eq = eq || "", rest = rest || ""
				if (def[0] === ",") def = "\nvar ", pre = "\n"
				var dependency = resolve(filepath, filename)
				var code = process(dependency, pre + (modules[dependency] == null ? exportCode(filename, dependency, def, variable, eq, rest, uuid) : def + variable + eq + modules[dependency]))
				modules[dependency] = rest ? "_" + uuid : variable
				uuid++
				return code + rest
			})
		}

		var resolve = function(filepath, filename) {
			if (filename[0] !== ".") {
				// resolve as npm dependency
				var packagePath = "./node_modules/" + filename + "/package.json"
				var meta = isFile(packagePath) ? parse(packagePath) : {}
				var main = "./node_modules/" + filename + "/" + (meta.main || filename + ".js")
				return path.resolve(isFile(main) ? main : "./node_modules/" + filename + "/index.js")
			}
			else {
				// resolve as local dependency
				return path.resolve(path.dirname(filepath), filename + ".js")
			}
		}

		var exportCode = function(filename, filepath, def, variable, eq, rest, uuid) {
			var code = read(filepath)
			// if there's a syntax error, report w/ proper stack trace
			try {new Function(code)} catch (e) {
				proc.exec("node " + filename, function(error) {
					if (error !== null) console.log("\x1b[31m" + error.message)
				})
			}

			// disambiguate collisions
			var ignored = {}
			code.replace(include, function(match, def, variable, eq, dep) {
				var filename = new Function("return " + dep).call()
				var binding = modules[resolve(filepath, filename)]
				if (binding != null) ignored[binding] = true
			})
			if (code.match(new RegExp("module\\.exports\\s*=\\s*" + variable + "\s*$", "m"))) ignored[variable] = true
			for (var binding in bindings) {
				if (!ignored[binding]) {
					var before = code
					code = code.replace(new RegExp("(\\b)" + binding + "\\b", "g"), binding + bindings[binding])
					if (before !== code) bindings[binding]++
				}
			}

			// fix strings that got mangled by collision disambiguation
			var string = /(["'])((?:\\\1|.)*?)(\1)/g
			var candidates = Object.keys(bindings).map(function(binding) {return binding + (bindings[binding] - 1)}).join("|")
			code = code.replace(string, function(match, open, data, close) {
				var variables = new RegExp(Object.keys(bindings).map(function(binding) {return binding + (bindings[binding] - 1)}).join("|"), "g")
				var fixed = data.replace(variables, function(match) {
					return match.replace(/\d+$/, "")
				})
				return open + fixed + close
			})

			//fix props
			var props = new RegExp("(\\.\\s*)(" + candidates + ")|([\\{,]\\s*)(" + candidates + ")(\\s*:)", "gm")
			code = code.replace(props, function(match, dot, a, pre, b, post) {
				if (dot) return dot + a.replace(/\d+$/, "")
				else return pre + b.replace(/\d+$/, "") + post
			})

			return code
				.replace(/("|')use strict\1;?/gm, "") // remove extraneous "use strict"
				.replace(/module\.exports\s*=\s*/gm, rest ? "var _" + uuid + eq : def + (rest ? "_" : "") + variable + eq) // export
				+ (rest ? "\n" + def + variable + eq + "_" + uuid : "") // if `rest` is truthy, it means the expression is fluent or higher-order (e.g. require(path).foo or require(path)(foo)
		}

		var versionTag = "bleeding-edge"
		var packageFile = __dirname + "/../package.json"
		var code = process(path.resolve(input), read(input))
			.replace(/^\s*((?:var|let|const|)[\t ]*)([\w_$\.]+)(\s*=\s*)(\2)(?=[\s]+(\w)|;|$)/gm, "") // remove assignments to self
			.replace(/;+(\r|\n|$)/g, ";$1") // remove redundant semicolons
			.replace(/(\r|\n)+/g, "\n").replace(/(\r|\n)$/, "") // remove multiline breaks
			.replace(versionTag, isFile(packageFile) ? parse(packageFile).version : versionTag) // set version

		code = "new function() {\n" + code + "\n}"

		if (!isFile(output) || code !== read(output)) fs.writeFileSync(output, code, "utf8")
	}
	catch (e) {
		console.error(e.message)
	}
}

module.exports = function(input, output, options) {
	run(input, output)
	if (options && options.watch) {
		fs.watch(process.cwd(), {recursive: true}, function(file) {
			if (typeof file === "string" && path.resolve(output) !== path.resolve(file)) run(input, output)
		})
	}
}
<commit_msg>bundler: throw error correctly when there's syntax error<commit_after>"use strict"

var fs = require("fs")
var path = require("path")
var proc = require("child_process")

function read(filepath) {
	try {return fs.readFileSync(filepath, "utf8")} catch (e) {throw new Error("File does not exist: " + filepath)}
}
function isFile(filepath) {
	try {return fs.statSync(filepath).isFile()} catch (e) {return false}
}
function parse(file) {
	var json = read(file)
	try {return JSON.parse(json)} catch (e) {throw new Error("invalid JSON: " + json)}
}

var error
function run(input, output) {
	try {
		var modules = {}
		var bindings = {}
		var declaration = /^\s*(?:var|let|const|function)[\t ]+([\w_$]+)/gm
		var include = /(?:((?:var|let|const|,|)[\t ]*)([\w_$\.\[\]"'`]+)(\s*=\s*))?require\(([^\)]+)\)(\s*[`\.\(\[])?/gm
		var uuid = 0
		var process = function(filepath, data) {
			data.replace(declaration, function(match, binding) {bindings[binding] = 0})

			return data.replace(include, function(match, def, variable, eq, dep, rest) {
				var filename = new Function("return " + dep).call(), pre = ""

				def = def || "", variable = variable || "", eq = eq || "", rest = rest || ""
				if (def[0] === ",") def = "\nvar ", pre = "\n"
				var dependency = resolve(filepath, filename)
				var code = process(dependency, pre + (modules[dependency] == null ? exportCode(filename, dependency, def, variable, eq, rest, uuid) : def + variable + eq + modules[dependency]))
				modules[dependency] = rest ? "_" + uuid : variable
				uuid++
				return code + rest
			})
		}

		var resolve = function(filepath, filename) {
			if (filename[0] !== ".") {
				// resolve as npm dependency
				var packagePath = "./node_modules/" + filename + "/package.json"
				var meta = isFile(packagePath) ? parse(packagePath) : {}
				var main = "./node_modules/" + filename + "/" + (meta.main || filename + ".js")
				return path.resolve(isFile(main) ? main : "./node_modules/" + filename + "/index.js")
			}
			else {
				// resolve as local dependency
				return path.resolve(path.dirname(filepath), filename + ".js")
			}
		}

		var exportCode = function(filename, filepath, def, variable, eq, rest, uuid) {
			var code = read(filepath)
			// if there's a syntax error, report w/ proper stack trace
			try {new Function(code)} catch (e) {
				proc.exec("node " + filepath, function(e) {
					if (e !== null && e.message !== error) {
						error = e.message
						console.log("\x1b[31m" + e.message + "\x1b[0m")
					}
				})
			}

			// disambiguate collisions
			var ignored = {}
			code.replace(include, function(match, def, variable, eq, dep) {
				var filename = new Function("return " + dep).call()
				var binding = modules[resolve(filepath, filename)]
				if (binding != null) ignored[binding] = true
			})
			if (code.match(new RegExp("module\\.exports\\s*=\\s*" + variable + "\s*$", "m"))) ignored[variable] = true
			for (var binding in bindings) {
				if (!ignored[binding]) {
					var before = code
					code = code.replace(new RegExp("(\\b)" + binding + "\\b", "g"), binding + bindings[binding])
					if (before !== code) bindings[binding]++
				}
			}

			// fix strings that got mangled by collision disambiguation
			var string = /(["'])((?:\\\1|.)*?)(\1)/g
			var candidates = Object.keys(bindings).map(function(binding) {return binding + (bindings[binding] - 1)}).join("|")
			code = code.replace(string, function(match, open, data, close) {
				var variables = new RegExp(Object.keys(bindings).map(function(binding) {return binding + (bindings[binding] - 1)}).join("|"), "g")
				var fixed = data.replace(variables, function(match) {
					return match.replace(/\d+$/, "")
				})
				return open + fixed + close
			})

			//fix props
			var props = new RegExp("(\\.\\s*)(" + candidates + ")|([\\{,]\\s*)(" + candidates + ")(\\s*:)", "gm")
			code = code.replace(props, function(match, dot, a, pre, b, post) {
				if (dot) return dot + a.replace(/\d+$/, "")
				else return pre + b.replace(/\d+$/, "") + post
			})

			return code
				.replace(/("|')use strict\1;?/gm, "") // remove extraneous "use strict"
				.replace(/module\.exports\s*=\s*/gm, rest ? "var _" + uuid + eq : def + (rest ? "_" : "") + variable + eq) // export
				+ (rest ? "\n" + def + variable + eq + "_" + uuid : "") // if `rest` is truthy, it means the expression is fluent or higher-order (e.g. require(path).foo or require(path)(foo)
		}

		var versionTag = "bleeding-edge"
		var packageFile = __dirname + "/../package.json"
		var code = process(path.resolve(input), read(input))
			.replace(/^\s*((?:var|let|const|)[\t ]*)([\w_$\.]+)(\s*=\s*)(\2)(?=[\s]+(\w)|;|$)/gm, "") // remove assignments to self
			.replace(/;+(\r|\n|$)/g, ";$1") // remove redundant semicolons
			.replace(/(\r|\n)+/g, "\n").replace(/(\r|\n)$/, "") // remove multiline breaks
			.replace(versionTag, isFile(packageFile) ? parse(packageFile).version : versionTag) // set version

		code = "new function() {\n" + code + "\n}"

		if (!isFile(output) || code !== read(output)) {
			try {new Function(code); console.log("build completed at " + new Date())} catch (e) {}
			error = null
			fs.writeFileSync(output, code, "utf8")
		}
	}
	catch (e) {
		console.error(e.message)
	}
}

module.exports = function(input, output, options) {
	run(input, output)
	if (options && options.watch) {
		fs.watch(process.cwd(), {recursive: true}, function(file) {
			if (typeof file === "string" && path.resolve(output) !== path.resolve(file)) run(input, output)
		})
	}
}
<|endoftext|>


<commit_before>// modify version of django resumable bundled script to allow to work wit
// a dynamic uploading interface

var DjangoResumable = function (options) {
    "use strict";
    var defaults, els;
    options = options || {};
    defaults = {
        csrfInputName: 'csrfmiddlewaretoken',
        urlAttribute: 'data-upload-url',
        progressDisplay: '',
        errorListClass: 'errorlist',
        onFileError: this.onFileError,
        onFileAdded: this.onFileAdded,
        onFileSuccess: this.onFileSuccess,
        onProgress: this.onProgress,
        angularReference: {},
        resumableOptions: {}
    };
    this.previousProgressNumber = 0;
    this.options = this.extend(defaults, options);
    this.csrfToken = document.querySelector('input[name=' + this.options.csrfInputName + ']').value;
};

DjangoResumable.prototype.each = function (elements, fn) {
    "use strict";
    var i, l;
    for (i = 0, l = elements.length; i < l; i += 1) {
        fn.apply(this, [elements[i]]);
    }
};

DjangoResumable.prototype.extend = function (target, source) {
    "use strict";
    var property;
    for (property in source) {
        if (source.hasOwnProperty(property)) {
            target[property] = source[property];
        }
    }
    return target;
};

DjangoResumable.prototype.getErrorList = function (el, create) {
    "use strict";
    var errorList = el.parentNode.previousSibling;
    while (errorList && errorList.tagName === undefined) {
        errorList = errorList.previousSibling;
    }
    if (errorList && !errorList.classList.contains(this.options.errorListClass)) {
        if (create === true) {
            errorList = document.createElement('ul');
            errorList.classList.add(this.options.errorListClass);
            el.parentNode.parentNode.insertBefore(errorList, el.parentNode);
        } else {
            errorList = null;
        }
    }
    return errorList;
};

DjangoResumable.prototype.getForm = function (el) {
    "use strict";
    var parent = el;
    while (parent.tagName !== 'FORM') {
        parent = parent.parentNode;
    }
    return parent;
};

DjangoResumable.prototype.initField = function (el) {
    "use strict";
    var progress, fileName, filePath, filePathName;

    progress = this.initProgressBar();
    el.parentNode.parentNode.insertBefore(progress, el.parentNode.nextSibling);

    filePathName = el.getAttribute('name') + '-path';
    filePath = el.parentNode.querySelector('[name=' + filePathName + ']');

    this.initResumable(el, progress, filePath, fileName);

    this.getForm(el).addEventListener('submit', function () {
        el.parentNode.removeChild(el);
    });

    this.el = el;
};

DjangoResumable.prototype.initProgressBar = function () {
    "use strict";
    var progress = document.createElement('div');
    progress.className = "progress";
    progress.innerHTML = '
0%
';
    progress.style.display = 'none';
    return progress;
};

DjangoResumable.prototype.initResumable = function (el, progress, filePath, fileName) {
    "use strict";
    var elements = Array.prototype.slice.call(arguments),
        self = this,
        opts = {
            target: el.getAttribute(this.options.urlAttribute),
            query: {
                'csrfmiddlewaretoken': this.csrfToken
            }
        };

    opts = this.extend(this.options.resumableOptions, opts);
    var r = new Resumable(opts);
    r.assignBrowse(el);
    this.each(['fileAdded', 'progress', 'fileSuccess', 'fileError'], function (eventType) {
        var callback = this.options['on' + eventType.substring(0, 1).toUpperCase() + eventType.substring(1)];
        r.on(eventType, function () {
            var args = arguments.length > 0 ? Array.prototype.slice.call(arguments) : [];
            callback.apply(self, [r].concat(args).concat(elements));
        });
    });
    return r;
};

DjangoResumable.prototype.onFileError = function (r, file, message, el) {
    "use strict";
    console.log(message);
    var errorList = this.getErrorList(el, true),
        error = document.createElement('li');
    error.innerHTML = message;
    if (errorList) {
        errorList.appendChild(error);
    }
};

DjangoResumable.prototype.onFileAdded = function (r, file, event, el, progress, filePath, fileName) {
    "use strict";
    var errorList = this.getErrorList(el);
    if (errorList) {
        errorList.parentNode.removeChild(errorList);
    }
    r.upload();
    progress.style.display = this.options.progressDisplay;
};

DjangoResumable.prototype.onFileSuccess = function (r, file, message, el, progress, filePath, fileName) {
    "use strict";
    filePath.setAttribute('value', file.size + '_' + file.fileName);
    progress.firstChild.className += ' progress-bar-success';
    progress.firstChild.innerHTML = 'Upload terminé'
};

DjangoResumable.prototype.onProgress = function (r, el, progress, filePath, fileName) {
    "use strict";
    number = Math.floor(r.progress() * 100);
    if (number == this.previousProgressNumber) {
        return;
    }
    this.previousProgressNumber = number;
    progress.firstChild.style.width = number + "%";
    progress.firstChild.setAttribute("aria-valuenow", number);
    progress.firstChild.innerHTML = number + "%";
};

DjangoResumable.prototype.startUpload = function (r, progress) {
    r.upload();
    progress.style.display = this.options.progressDisplay;
    this.options.angularReference.state = "running";
    this.el.style.display = "none";
}
<commit_msg>[mod] don't let django-resumable handle submit of form<commit_after>// modify version of django resumable bundled script to allow to work wit
// a dynamic uploading interface

var DjangoResumable = function (options) {
    "use strict";
    var defaults, els;
    options = options || {};
    defaults = {
        csrfInputName: 'csrfmiddlewaretoken',
        urlAttribute: 'data-upload-url',
        progressDisplay: '',
        errorListClass: 'errorlist',
        onFileError: this.onFileError,
        onFileAdded: this.onFileAdded,
        onFileSuccess: this.onFileSuccess,
        onProgress: this.onProgress,
        angularReference: {},
        resumableOptions: {}
    };
    this.previousProgressNumber = 0;
    this.options = this.extend(defaults, options);
    this.csrfToken = document.querySelector('input[name=' + this.options.csrfInputName + ']').value;
};

DjangoResumable.prototype.each = function (elements, fn) {
    "use strict";
    var i, l;
    for (i = 0, l = elements.length; i < l; i += 1) {
        fn.apply(this, [elements[i]]);
    }
};

DjangoResumable.prototype.extend = function (target, source) {
    "use strict";
    var property;
    for (property in source) {
        if (source.hasOwnProperty(property)) {
            target[property] = source[property];
        }
    }
    return target;
};

DjangoResumable.prototype.getErrorList = function (el, create) {
    "use strict";
    var errorList = el.parentNode.previousSibling;
    while (errorList && errorList.tagName === undefined) {
        errorList = errorList.previousSibling;
    }
    if (errorList && !errorList.classList.contains(this.options.errorListClass)) {
        if (create === true) {
            errorList = document.createElement('ul');
            errorList.classList.add(this.options.errorListClass);
            el.parentNode.parentNode.insertBefore(errorList, el.parentNode);
        } else {
            errorList = null;
        }
    }
    return errorList;
};

DjangoResumable.prototype.getForm = function (el) {
    "use strict";
    var parent = el;
    while (parent.tagName !== 'FORM') {
        parent = parent.parentNode;
    }
    return parent;
};

DjangoResumable.prototype.initField = function (el) {
    "use strict";
    var progress, fileName, filePath, filePathName;

    progress = this.initProgressBar();
    el.parentNode.parentNode.insertBefore(progress, el.parentNode.nextSibling);

    filePathName = el.getAttribute('name') + '-path';
    filePath = el.parentNode.querySelector('[name=' + filePathName + ']');

    this.initResumable(el, progress, filePath, fileName);

    this.el = el;
};

DjangoResumable.prototype.initProgressBar = function () {
    "use strict";
    var progress = document.createElement('div');
    progress.className = "progress";
    progress.innerHTML = '
0%
';
    progress.style.display = 'none';
    return progress;
};

DjangoResumable.prototype.initResumable = function (el, progress, filePath, fileName) {
    "use strict";
    var elements = Array.prototype.slice.call(arguments),
        self = this,
        opts = {
            target: el.getAttribute(this.options.urlAttribute),
            query: {
                'csrfmiddlewaretoken': this.csrfToken
            }
        };

    opts = this.extend(this.options.resumableOptions, opts);
    var r = new Resumable(opts);
    r.assignBrowse(el);
    this.each(['fileAdded', 'progress', 'fileSuccess', 'fileError'], function (eventType) {
        var callback = this.options['on' + eventType.substring(0, 1).toUpperCase() + eventType.substring(1)];
        r.on(eventType, function () {
            var args = arguments.length > 0 ? Array.prototype.slice.call(arguments) : [];
            callback.apply(self, [r].concat(args).concat(elements));
        });
    });
    return r;
};

DjangoResumable.prototype.onFileError = function (r, file, message, el) {
    "use strict";
    console.log(message);
    var errorList = this.getErrorList(el, true),
        error = document.createElement('li');
    error.innerHTML = message;
    if (errorList) {
        errorList.appendChild(error);
    }
};

DjangoResumable.prototype.onFileAdded = function (r, file, event, el, progress, filePath, fileName) {
    "use strict";
    var errorList = this.getErrorList(el);
    if (errorList) {
        errorList.parentNode.removeChild(errorList);
    }
    r.upload();
    progress.style.display = this.options.progressDisplay;
};

DjangoResumable.prototype.onFileSuccess = function (r, file, message, el, progress, filePath, fileName) {
    "use strict";
    filePath.setAttribute('value', file.size + '_' + file.fileName);
    progress.firstChild.className += ' progress-bar-success';
    progress.firstChild.innerHTML = 'Upload terminé'
};

DjangoResumable.prototype.onProgress = function (r, el, progress, filePath, fileName) {
    "use strict";
    number = Math.floor(r.progress() * 100);
    if (number == this.previousProgressNumber) {
        return;
    }
    this.previousProgressNumber = number;
    progress.firstChild.style.width = number + "%";
    progress.firstChild.setAttribute("aria-valuenow", number);
    progress.firstChild.innerHTML = number + "%";
};

DjangoResumable.prototype.startUpload = function (r, progress) {
    r.upload();
    progress.style.display = this.options.progressDisplay;
    this.options.angularReference.state = "running";
    this.el.style.display = "none";
}
<|endoftext|>


<commit_before>// -----------------------------------------------------------------
// @author:  Mark McCann (www.markmccann.me)
// @license: None, Public Domain
// -----------------------------------------------------------------

var Modality = (function () {

    /**
     * combines javascript objects
     * @return {object}
     */
    var extend = function () {
        var a = arguments;
        for(var i in a) {
            for(var key in a[i]) {
                if(a[i].hasOwnProperty(key)) {
                    a[0][key] = a[i][key];
                }
            }
        }
        return a[0];
    },

    // -----------------------------------------------------------------

    /**
     * returns the value of a given attribute of a given dom object
     * @param  {dom object} node
     * @param  {string}     attr
     * @return {string}
     */
    attr = function (node, attr) {
        if (node.hasAttribute(attr)) return node.getAttribute(attr);
    },

    // -----------------------------------------------------------------

    /**
     * removes duplicates from an array
     * @param  {array} array
     * @return {array}
     */
    uniqueArray = function (array) {
        var a = array.concat();
        for(var i=0; i < a.length; ++i) {
            for(var j=i+1; j<a.length; ++j) {
                if(a[i] === a[j]) {
                    a.splice(j--, 1);
                }
            }
        }
        return a;
    },

    // -----------------------------------------------------------------

    /**
     * binds an event listener to a given dom object
     * @param  {dom object} node
     * @param  {string}     event
     * @param  {function}   callback
     */
    bind = function( target, event, fn ) {
        if ( target.attachEvent ) {
            target['e'+event+fn] = fn;
            target[event+fn] = function(){ target['e'+event+fn]( window.event ); }
            target.attachEvent( 'on'+event, target[event+fn] );
        } else {
           target.addEventListener( event, fn, false );
        }
    },

    // -----------------------------------------------------------------

    /**
     * inserts a new dom element after a given target element
     * @param  {dom object} newElement - the object you want to add
     * @param  {dom object} target - the object you want it added after
     */
    insertAfter = function (newElement,target) {
        var parent = target.parentNode;
        if(parent.lastchild == target) {
            parent.appendChild(newElement);
        } else {
            parent.insertBefore(newElement, target.nextSibling);
        }
    },

    // -----------------------------------------------------------------

    /**
     * determine if a given node has a particular class
     * @param {object} target - the node you are adding a class to
     * @param {string} className - the class you are checking for
     * @return {boolean}
     */
    hasClass = function( target, className ) {
        return target.className.match(new RegExp('(\\s|^)'+className+'(\\s|$)'));
    },

    /**
     * add class to a given node
     * @param {object} target - the node you are adding a class to
     * @param {string} className - the class you are adding
     */
    addClass = function( target, className ) {
        if( ! hasClass(target, className) ) {
            target.className += " " + className;
        }
    },

    /**
     * remove class from a given node
     * @param {object} target - the node you are removing a class from
     * @param {string} className - the class you are removing
     */
    removeClass = function( target, className ) {
        if( hasClass(target, className) ) {
            var re = new RegExp("(\\s|^)" + className + "(\\s|$)", "g");
            target.className = target.className.replace(re , '');
        }
    };

    // -----------------------------------------------------------------

    /**
     * sets up the modal by wrapping markup in appropriate classes
     * @param  {object} modal
     * @return {object}
     */
    var wrap = function ( modal ) {
        // create the new container
        var wrapper = document.createElement('div');
        wrapper.setAttribute('class', modal.options.modalClass);

        // if ie, do a couple things
        var ie = '';
        if (/MSIE (\d+\.\d+);/.test(navigator.userAgent)) {
            var ieVersion = new Number(RegExp.$1);
            if(ieVersion <= 8) ie = '

';
            if(ieVersion == 9) wrapper.setAttribute('style', "filter:none;");
        }

        // insert modal content into the new container
        wrapper.innerHTML = ie + '
' + modal.modal.outerHTML + '
';
        insertAfter(wrapper, modal.modal);

        // remove the old modal from the dom
        modal.modal.parentNode.removeChild( modal.modal );

        // add css3 effect class
        addClass( wrapper, modal.options.effect );

        // bind click event to close the modal on wrapper
        if( modal.options.clickOffClose ) {
            bind( wrapper, 'click', function(e) {
                e.preventDefault();
                if( e.target == wrapper ) modal.close();
            });
        }

        return wrapper;
    }

    // -----------------------------------------------------------------

    /**
     * collects array of anchors whose 'href' mathces the 'id' of the target
     * @param  {string} targetID
     * @return {array}
     */
    anchors = function (targetID) {

        // get all the anchor tags in document
        var anchors = document.getElementsByTagName('a');

        // loop through anchors and collect any that match criteria
        var triggers = [];
        for (var i = 0; i < anchors.length; i++) {
            if (anchors[i].getAttribute("href") == '#'+targetID) {
                triggers.push(anchors[i]);
            }
        }

        return triggers;
    },

    // -----------------------------------------------------------------

    /**
     * collects all triggers and adds click events to each of them
     * @param  {object} modal
     * @return {array}
     */
    triggers = function (modal) {

        // create new array
        var triggers = [];

        // if auto bind set true, include in trigger array
        if(modal.options.autoBind) {
            triggers = modal.anchors;
        }

        // loop through passed-in triggers and add to array
        for (var i in modal.options.triggers) {
            triggers.push(modal.options.triggers[i]);
        }

        // remove any duplicate triggers
        triggers = uniqueArray(triggers);

        // bind click action for all triggers
        for(var i in triggers) {
            bind(triggers[i],"click",function (e) {
                e.preventDefault();
                modal.toggle();
            });
        }

        return triggers;

    };

    // -----------------------------------------------------------------

    /**
     * the modality object
     * @param {dom object} modal
     * @param {object}     options
     * @param {function}   callback
     */
    var Modality = function (modal, options, callback) {

        // create local var to avoid scopr issues
        var base = this;

        // set initial attributes
        base.modal = modal;
        base.id = attr(base.modal, 'id');
        base.options = extend( {}, Modality.defaults, options);
        base.body = document.getElementsByTagName( 'body' )[0];

        // set up the modal in the dom
        base.wrapper = wrap(base);

        // set remaining attributes
        base.modal = document.getElementById(base.id);
        base.anchors = anchors(base.id);
        base.triggers = triggers(base);

        // open modal if auto open is set
        if(base.options.autoOpen) base.open();

        // run the callback function
        if (typeof callback == 'function') { callback(); }

        // add this modal to list of modals on page
        Modality.modals[base.id] = base;

        return base;

    };

    // -----------------------------------------------------------------

    Modality.prototype = {

        /**
         * closes the modal
         * @param  {function} callback
         * @return {instance}
         */
        close: function (callback) {

            // remove classes to open the modal
            removeClass(this.wrapper,this.options.openClass);
            removeClass(this.body,this.options.openClass);

            // run the callbacks
            if ( typeof this.options.onClose == 'function' ) { this.options.onClose(); }
            if ( typeof callback == 'function' ) { callback(); }

            return this;

        },

        /**
         * opens the modal
         * @param  {function} callback
         * @return {instance}
         */
        open: function (callback) {

            // add classes to open the modal
            addClass(this.wrapper,this.options.openClass);
            addClass(this.body,this.options.openClass);

            // bind keyup event to close modal
            if(this.options.closeOnEscape) {
                var modal = this;
                bind(document.body,"keyup",function (e) {
                    if(e.keyCode == 27){ modal.close(); }
                });
            }

            // run the callback
            if ( typeof this.options.onOpen == 'function' ) { this.options.onOpen(); }
            if ( typeof callback == 'function' ) { callback(); }

            return this;

        },

        /**
         * opens modal if closed and vice versa
         * @param  {function} callback
         * @return {instance}
         */
        toggle: function (callback) {
            (this.isOpen()) ? this.close(callback) : this.open(callback);
            return this;
        },

        /**
         * determines if the modal is open or not
         * @return {Boolean}
         */
        isOpen: function () {
            return (hasClass(this.wrapper, this.options.openClass)) ? true : false;
        }
    };

    // -----------------------------------------------------------------

    Modality.init = function ( query, options, fn ) {
        var modals = document.querySelectorAll(query);
        for( var i = 0; i < modals.length; i++ ) {
            new Modality(modals[i], options, fn);
        }
        return Modality.modals;
    }

    // -----------------------------------------------------------------

    Modality.defaults = {
        modalClass: "modality-modal",
        innerClass: "mm-wrap",
        openClass: "mm-show",
        ieClass: "mm-ghost",
        clickOffClose: true,
        closeOnEscape: true,
        autoOpen: false,
        autoBind: true,
        triggers: [],
        effect: "effect-1",
        onOpen: function(){},
        onClose: function(){}
    }

    Modality.modals = {};

    // -----------------------------------------------------------------

    return Modality;

})();<commit_msg>Update<commit_after>// -----------------------------------------------------------------
// @author:  Mark McCann (www.markmccann.me)
// @license: None, Public Domain
// -----------------------------------------------------------------

var Modality = (function () {

    /**
     * combines javascript objects
     * @return {object}
     */
    var extend = function () {
        var a = arguments;
        for( var i in a ) {
            for( var key in a[i] ) {
                if( a[i].hasOwnProperty(key) ) {
                    a[0][key] = a[i][key];
                }
            }
        }
        return a[0];
    };

    // -----------------------------------------------------------------

    /**
     * the modality object
     * @param {object} modal
     * @param {object} options
     * @param {function} callback
     */
    var Modality = function ( modal, options, callback ) {

        // create local var to avoid scope issues
        var base = this;

        // set initial attributes
        base.id       = modal.getAttribute( 'id' );
        base.options  = extend( {}, Modality.defaults, options );
        base.body     = document.getElementsByTagName( 'body' )[0];
        base.triggers = document.querySelectorAll( 'a[href="#'+base.id+'"], [data-modality="#'+base.id+'"]' );

        // build and set modal wrapper
        base.wrapper = document.createElement('div');
        base.wrapper.setAttribute( 'class', base.options.modalClass + ' ' + base.options.effect );
        base.wrapper.innerHTML = '
' + modal.outerHTML + '
';
        modal.parentNode.replaceChild( base.wrapper, modal );

        // set the original modal
        base.modal = document.getElementById( base.id );

        // --------------------------------------------

        // toggle modal on all triggers
        if( base.options.autoBind ) {
            for( var i = 0; i < base.triggers.length; i++ ) {
                base.setTrigger(base.triggers[i]);
            }
        }

        // close modal if users clicks anywhere off of it
        if( base.options.clickOffClose ) {
            base.wrapper.addEventListener( "click", function(e) {
                e.preventDefault(); if(e.target == base.wrapper) base.close();
            }, false );
        }

        // close modal with 'esc' key
        if( this.options.closeOnEscape ) {
            base.body.addEventListener( "keyup", function (e) {
                if(e.keyCode == 27){ base.close(); }
            }, false);
        }

        if( base.options.autoOpen ) base.open();

        // --------------------------------------------

        if( typeof callback == 'function' ) callback();

        return Modality.modals[base.id] = base;

    };

    // -----------------------------------------------------------------

    /**
     * class methods for the modality object
     */
    Modality.prototype = {

        /**
         * closes the modal
         * @param  {function} callback
         * @return {instance}
         */
        close: function ( callback ) {

            // remove classes to close the modal
            this.wrapper.classList.remove( this.options.openClass );
            this.body.classList.remove( this.options.openClass );

            // run the callback(s)
            if ( typeof this.options.onClose == 'function' ) this.options.onClose();
            if ( typeof callback == 'function' ) callback();

            return this;

        },

        /**
         * opens the modal
         * @param  {function} callback
         * @return {instance}
         */
        open: function ( callback ) {

            // add classes to open the modal
            this.wrapper.classList.add( this.options.openClass );
            this.body.classList.add( this.options.openClass );

            // run the callback(s)
            if ( typeof this.options.onOpen == 'function' ) this.options.onOpen();
            if ( typeof callback == 'function' ) callback();

            return this;

        },

        /**
         * toggles the modal
         * @param  {function} callback
         * @return {instance}
         */
        toggle: function ( callback ) {
            return ( this.isOpen() ) ? this.close(callback) : this.open(callback);
        },

        /**
         * determines if the modal is open or not
         * @return {Boolean}
         */
        isOpen: function () {
            return ( this.wrapper.classList.contains(this.options.openClass) ) ? true : false;
        },

        /**
         * manually set trigger for a modal
         * @param  {object} - the element you want to be the trigger
         * @return {instance}
         */
        setTrigger: function ( trigger ) {

            // set local var for instance
            var base = this;

            // set click event for new trigger
            trigger.addEventListener( "click", function (e) {
                e.preventDefault(); base.toggle();
            }, false );

            return this;
        }

    };

    // -----------------------------------------------------------------

    /**
     * initalizes modal(s)
     * @param  {string} query
     * @param  {object} options
     * @param  {function} fn
     * @return {object,array}
     */
    Modality.init = function ( query, options, fn ) {

        // collect the modals from the DOM
        var modals = document.querySelectorAll(query);

        // loop through the modals and initialize each one
        for( var i = 0; i < modals.length; i++ ) {

            // Initialize the modal
            var modal = new Modality(modals[i], options, fn);

            // return only this modal if only one
            if(modals.length == 1) { return modal; }
        }

        // return array of modals
        return Modality.modals;
    }

    // -----------------------------------------------------------------

    /**
     * list of Modality defaults
     */
    Modality.defaults = {
        modalClass: "modality-modal", // outer-most container
        innerClass: "mm-wrap", // inner wrapper
        openClass: "mm-show", // when modal is visible
        clickOffClose: true, // click anywhere off of modal to close it
        closeOnEscape: true, // close modal with 'esc' key
        autoOpen: false, // open on page load
        autoBind: true, // automatically bind triggers to modal
        effect: "effect-1", // animation style
        onOpen: function(){}, // function to run when modal opens
        onClose: function(){} // function to run when modal closes
    }

    /**
     * an empty object to collect all modals on page
     */
    Modality.modals = {};

    // -----------------------------------------------------------------

    return Modality;

})();
<|endoftext|>


<commit_before>/*jshint node: true */
'use strict';

/*
* Name :  LineChartViewSpec.js
* Module : UnitTest
* Location : /frontend/test/unit/View
*
* History :
* Version       Date        Programmer                  Description
* =================================================================================================
* 0.1.1         2015-06-25  Maria Giovanna Chinellato   Fix test
*
* 0.1.0         2015-06-13  Maria Giovanna Chinellato   Add all attributes and all methods
*
* 0.0.1         2015-06-13  Maria Giovanna Chinellato   Initial code
* =================================================================================================
*
*/

describe('LineChartView', function(){

	beforeEach(angular.mock.module('norris-nrti'));

	var html, element, scope, line, LineChartFactory, controller;
	var json = {
		'properties' : {
			'title' : 'prova1',
			'viewFinder' : true,
			'enableLegend' : true,
			'legendOnPoint' : false
		}
	};

	beforeEach(inject(function($rootScope, $compile, $injector, $controller) {
		LineChartFactory = $injector.get('LineChartFactory');
		line = LineChartFactory.build();
    	scope = $rootScope.$new();
    	controller = $controller('LineChartController', { $scope : scope });
    	html = angular.element('<line-chart url="http://example/line.com"></line-chart>');

    	scope.lineChart = line;

    	element = $compile(html)(scope);
    	scope.$digest();

  	}));

  	describe('#init', function() {

  		var info = {
			'title' : 'graficonuovo',
			'height' : 400,
			'width' : 400,
			'enableLegend' : false,
			'socketURL' : 'http://example.com',
			'xAxis' : { name: 'asseX' },
			'yAxis' : { name: 'asseY' },
			'viewFinder' : true,
			'headers' : ['colonna1'],
			'backgroundColor' : '#F0F',
			'legendOnPoint' : false,
			'grid' : false
		};

  		var json = {
			'title' : 'graficonuovo',
			'height' : 400,
			'width' : 400,
			'enableLegend' : true,
			'legend' : {position: 'E'},
			'socketURL' : 'http://example.com',
			'xAxis' : { name: 'asseX' },
			'yAxis' : { name: 'asseY' },
			'viewFinder' : false,
			'headers' : ['colonna1'],
			'backgroundColor' : '#F0F',
			'legendOnPoint' : true,
			'grid' : false,
			'flows' : [{'ID' : 'f1', 'flowColor' : '#000000'},{ 'ID' : 'f2'},{'ID' : 'f3'}]
		};

		beforeEach(function(){
			scope.lineChart = lineChartFactory.build();
		});

		afterEach(function(){
			scope.lineChart = null;
		});

		it('default works fine', function() {
			scope.lineChart.updateParameters(info);
			scope.changedP = !scope.changedP;
    		scope.$digest();
			var lineChart = element.find('line-chart');
			expect(lineChart).toBeDefined();
			var nvd3H = element.find('nvd3-line-with-focus-chart');
			expect(nvd3H).toBeDefined();
			var svgH = element.find('svg');
			expect(svgH).toBeDefined();
		});

		it('works fine', function(){
			scope.lineChart.updateParameters(json);
			scope.changedP = !scope.changedP;
    		scope.$digest();
			var nvd3V = element.find('nvd3-line-chart');
			expect(nvd3V).toBeDefined();
			var svgV = element.find('svg');
			expect(svgV).toBeDefined();
		});

	});

	describe('#setData', function() {

  		var json = {
  			'title' : 'json',
			'enableLegend' : true,
			'legend' : {position: 'N'},
			'flows' : [{'ID' : 'f1', 'flowColor' : '#000000'},{ 'ID' : 'f2', 'flowColor' : '#BAAAEE'},{'ID' : 'f3', 'flowColor' : '#B9D3EE'}]
		};

		var data = [
			{
				'ID':'f1',
				'records':[
					{'norrisRecordID':'flow1_1435482609499_1','value':[1,3]},
					{'norrisRecordID':'flow1_1435482609499_2','value':[2,2]},
					{'norrisRecordID':'flow1_1435482609499_3','value':[3,1]}
				]
			}
		];

		it('works fine', function() {
			scope.lineChart.updateParameters(json);
			scope.lineChart.initializeData(data);
			scope.changedD = !scope.changedD;
    		scope.$digest();
		});

		/*it('set the correct flow color', function() {
			var colorArray = scope.colorFunction();
			expect(colorArray[0]).toEqual('#000000');
			expect(colorArray[0]).toEqual('#BAAAEE');
			expect(colorArray[0]).toEqual('#B9D3EE');
		});*/

	});

	describe('#setLegend', function() {

  		var json1 = {
  			'title' : 'json1',
			'enableLegend' : true,
			'legend' : {position: 'S'},
			'flows' : [{'ID' : 'f1'},{ 'ID' : 'f2'},{'ID' : 'f3'}]
		};

		var json2 = {
			'title' : 'json2',
			'enableLegend' : true,
			'legend' : {position: 'SE'},
			'flows' : [{'ID' : 'f1'},{ 'ID' : 'f2'},{'ID' : 'f3'}]
		};

		var json3 = {
			'title' : 'json3',
			'enableLegend' : true,
			'legend' : {position: 'SW'},
			'flows' : [{'ID' : 'f1'},{ 'ID' : 'f2'},{'ID' : 'f3'}]
		};

		var json4 = {
			'title' : 'json4',
			'enableLegend' : true,
			'legend' : {position: 'NW'},
			'flows' : [{'ID' : 'f1'},{ 'ID' : 'f2'},{'ID' : 'f3'}]
		};
		var json5 = {
			'title' : 'json5',
			'enableLegend' : true,
			'legend' : {position: 'W'},
			'flows' : [{'ID' : 'f1'},{ 'ID' : 'f2'},{'ID' : 'f3'}]
		};

		var json6 = {
			'title' : 'json6',
			'enableLegend' : true,
			'legend' : {position: 'NE'},
			'flows' : [{'ID' : 'f1'},{ 'ID' : 'f2'},{'ID' : 'f3'}]
		};

		var json7 = {
			'title' : 'json7',
			'enableLegend' : true,
			'legend' : {position: 'E'},
			'flows' : [{'ID' : 'f1'},{ 'ID' : 'f2'},{'ID' : 'f3'}]
		};

		beforeEach(function(){
			scope.lineChart = lineChartFactory.build();
		});

		afterEach(function(){
			scope.lineChart = null;
		});

		it('to S works fine', function() {
			scope.lineChart.updateParameters(json1);
			scope.changedD = !scope.changedD;
    		scope.$digest();
    		//var legend1 = element.find('div.lineChartLegend');
    		//console.dir(legend1);
			//expect(legend1).toBeDefined();
			//expect(legend1.getAttribute('style')).toBe('float: left; position: relative; right: -' + (scope.lineChart.getWidth()/2) + 'px; background-color: ' + scope.getLegend().getBackgroundColor() + ';');
    	});

    	it('to SE works fine', function(){
			scope.lineChart.updateParameters(json2);
			scope.changedD = !scope.changedD;
    		scope.$digest();
    		//var legend2 = element.children()[2];
			//expect(legend2).toBeDefined();
			//expect(legend2.getAttribute('style')).toBe('float: left; position: relative; right: -' + scope.lineChart.getWidth() + 'px; background-color: ' + scope.lineChart.getLegend().getBackgroundColor() + ';');
    	});

    	it('to SW works fine', function(){
    		scope.lineChart.updateParameters(json3);
			scope.changedD = !scope.changedD;
    		scope.$digest();
    		//var legend3 = element.children()[2];
			//expect(legend3).toBeDefined();
			//expect(legend3.getAttribute('style')).toBe('float: left; position: relative; background-color: ' + scope.lineChart.getLegend().getBackgroundColor() + ';');
    	});

    	it('to NW works fine', function(){
    		scope.lineChart.updateParameters(json4);
			scope.changedD = !scope.changedD;
    		scope.$digest();
    		//var legend4 = element.children()[2];
			//expect(legend4).toBeDefined();
			//expect(legend4.getAttribute('style')).toBe('float: left; position: relative; top: -' + scope.lineChart.getHeight() + 'px; background-color: ' + scope.lineChart.getLegend().getBackgroundColor() + ';');
		});

		it('to W works fine', function(){
    		scope.lineChart.updateParameters(json5);
			scope.changedD = !scope.changedD;
    		scope.$digest();
    		//var legend5 = element.children()[2];
			//expect(legend5).toBeDefined();
			//expect(legend5.getAttribute('style')).toBe('float: left; position: relative; top: -' + (scope.lineChart.getHeight()/2) + 'px; background-color: ' + scope.lineChart.getLegend().getBackgroundColor() + ';');
		});

		it('to NE works fine', function(){
    		scope.lineChart.updateParameters(json6);
			scope.changedD = !scope.changedD;
    		scope.$digest();
    		//var legend6 = element.children()[2];
			//expect(legend6).toBeDefined();
			//expect(legend6.getAttribute('style')).toBe('float: left; position: relative; top: -' + scope.lineChart.getHeight() + 'px; right: -' + scope.lineChart.getWidth() + 'px; background-color: ' + scope.lineChart.getLegend().getBackgroundColor() + ';');*/
		});

		it('to E works fine', function(){
    		scope.lineChart.updateParameters(json7);
			scope.changedD = !scope.changedD;
    		scope.$digest();
    		//var legend7 = element.find('div.lineChartLegend');
			//expect(legend7).toBeDefined();
			//expect(legend7.getAttribute('style')).toBe('float: left; position: relative; top: -' + (scope.lineChart.getHeight()/2) + 'px; right: -' + scope.lineChart.getWidth() + 'px;  background-color: ' + scope.$parent.getLegend().getBackgroundColor() + ';');
		});

	});

});<commit_msg>some fixes<commit_after>/*jshint node: true */
'use strict';

/*
* Name :  LineChartViewSpec.js
* Module : UnitTest
* Location : /frontend/test/unit/View
*
* History :
* Version       Date        Programmer                  Description
* =================================================================================================
* 0.1.1         2015-06-25  Maria Giovanna Chinellato   Fix test
*
* 0.1.0         2015-06-13  Maria Giovanna Chinellato   Add all attributes and all methods
*
* 0.0.1         2015-06-13  Maria Giovanna Chinellato   Initial code
* =================================================================================================
*
*/

describe('LineChartView', function(){

	beforeEach(angular.mock.module('norris-nrti'));

	var html, element, scope, line, LineChartFactory, controller;
	var json = {
		'properties' : {
			'title' : 'prova1',
			'viewFinder' : true,
			'enableLegend' : true,
			'legendOnPoint' : false
		}
	};

	beforeEach(inject(function($rootScope, $compile, $injector, $controller) {
		LineChartFactory = $injector.get('LineChartFactory');
		line = LineChartFactory.build();
    	scope = $rootScope.$new();
    	controller = $controller('LineChartController', { $scope : scope });
    	html = angular.element('<line-chart url="http://example/line.com"></line-chart>');

    	scope.lineChart = line;

    	element = $compile(html)(scope);
    	scope.$digest();

  	}));

  	describe('#init', function() {

  		var info = {
			'title' : 'graficonuovo',
			'height' : 400,
			'width' : 400,
			'enableLegend' : false,
			'socketURL' : 'http://example.com',
			'xAxis' : { name: 'asseX' },
			'yAxis' : { name: 'asseY' },
			'viewFinder' : true,
			'headers' : ['colonna1'],
			'backgroundColor' : '#F0F',
			'legendOnPoint' : false,
			'grid' : false
		};

  		var json = {
			'title' : 'graficonuovo',
			'height' : 400,
			'width' : 400,
			'enableLegend' : true,
			'legend' : {position: 'E'},
			'socketURL' : 'http://example.com',
			'xAxis' : { name: 'asseX' },
			'yAxis' : { name: 'asseY' },
			'viewFinder' : false,
			'headers' : ['colonna1'],
			'backgroundColor' : '#F0F',
			'legendOnPoint' : true,
			'grid' : false,
			'flows' : [{'ID' : 'f1', 'flowColor' : '#000000'},{ 'ID' : 'f2'},{'ID' : 'f3'}]
		};

		beforeEach(function(){
			scope.lineChart = LineChartFactory.build();
		});

		afterEach(function(){
			scope.lineChart = null;
		});

		it('default works fine', function() {
			scope.lineChart.updateParameters(info);
			scope.changedP = !scope.changedP;
    		scope.$digest();
			var lineChart = element.find('line-chart');
			expect(lineChart).toBeDefined();
			var nvd3H = element.find('nvd3-line-with-focus-chart');
			expect(nvd3H).toBeDefined();
			var svgH = element.find('svg');
			expect(svgH).toBeDefined();
		});

		it('works fine', function(){
			scope.lineChart.updateParameters(json);
			scope.changedP = !scope.changedP;
    		scope.$digest();
			var nvd3V = element.find('nvd3-line-chart');
			expect(nvd3V).toBeDefined();
			var svgV = element.find('svg');
			expect(svgV).toBeDefined();
		});

	});

	describe('#setData', function() {

  		var json = {
  			'title' : 'json',
			'enableLegend' : true,
			'legend' : {position: 'N'},
			'flows' : [{'ID' : 'f1', 'flowColor' : '#000000'},{ 'ID' : 'f2', 'flowColor' : '#BAAAEE'},{'ID' : 'f3', 'flowColor' : '#B9D3EE'}]
		};

		var data = [
			{
				'ID':'f1',
				'records':[
					{'norrisRecordID':'flow1_1435482609499_1','value':[1,3]},
					{'norrisRecordID':'flow1_1435482609499_2','value':[2,2]},
					{'norrisRecordID':'flow1_1435482609499_3','value':[3,1]}
				]
			}
		];

		it('works fine', function() {
			scope.lineChart.updateParameters(json);
			scope.lineChart.initializeData(data);
			scope.changedD = !scope.changedD;
    		scope.$digest();
		});

		/*it('set the correct flow color', function() {
			var colorArray = scope.colorFunction();
			expect(colorArray[0]).toEqual('#000000');
			expect(colorArray[0]).toEqual('#BAAAEE');
			expect(colorArray[0]).toEqual('#B9D3EE');
		});*/

	});

	describe('#setLegend', function() {

  		var json1 = {
  			'title' : 'json1',
			'enableLegend' : true,
			'legend' : {position: 'S'},
			'flows' : [{'ID' : 'f1'},{ 'ID' : 'f2'},{'ID' : 'f3'}]
		};

		var json2 = {
			'title' : 'json2',
			'enableLegend' : true,
			'legend' : {position: 'SE'},
			'flows' : [{'ID' : 'f1'},{ 'ID' : 'f2'},{'ID' : 'f3'}]
		};

		var json3 = {
			'title' : 'json3',
			'enableLegend' : true,
			'legend' : {position: 'SW'},
			'flows' : [{'ID' : 'f1'},{ 'ID' : 'f2'},{'ID' : 'f3'}]
		};

		var json4 = {
			'title' : 'json4',
			'enableLegend' : true,
			'legend' : {position: 'NW'},
			'flows' : [{'ID' : 'f1'},{ 'ID' : 'f2'},{'ID' : 'f3'}]
		};
		var json5 = {
			'title' : 'json5',
			'enableLegend' : true,
			'legend' : {position: 'W'},
			'flows' : [{'ID' : 'f1'},{ 'ID' : 'f2'},{'ID' : 'f3'}]
		};

		var json6 = {
			'title' : 'json6',
			'enableLegend' : true,
			'legend' : {position: 'NE'},
			'flows' : [{'ID' : 'f1'},{ 'ID' : 'f2'},{'ID' : 'f3'}]
		};

		var json7 = {
			'title' : 'json7',
			'enableLegend' : true,
			'legend' : {position: 'E'},
			'flows' : [{'ID' : 'f1'},{ 'ID' : 'f2'},{'ID' : 'f3'}]
		};

		beforeEach(function(){
			scope.lineChart = LineChartFactory.build();
		});

		afterEach(function(){
			scope.lineChart = null;
		});

		it('to S works fine', function() {
			scope.lineChart.updateParameters(json1);
			scope.changedD = !scope.changedD;
    		scope.$digest();
    		//var legend1 = element.find('div.lineChartLegend');
    		//console.dir(legend1);
			//expect(legend1).toBeDefined();
			//expect(legend1.getAttribute('style')).toBe('float: left; position: relative; right: -' + (scope.lineChart.getWidth()/2) + 'px; background-color: ' + scope.getLegend().getBackgroundColor() + ';');
    	});

    	it('to SE works fine', function(){
			scope.lineChart.updateParameters(json2);
			scope.changedD = !scope.changedD;
    		scope.$digest();
    		//var legend2 = element.children()[2];
			//expect(legend2).toBeDefined();
			//expect(legend2.getAttribute('style')).toBe('float: left; position: relative; right: -' + scope.lineChart.getWidth() + 'px; background-color: ' + scope.lineChart.getLegend().getBackgroundColor() + ';');
    	});

    	it('to SW works fine', function(){
    		scope.lineChart.updateParameters(json3);
			scope.changedD = !scope.changedD;
    		scope.$digest();
    		//var legend3 = element.children()[2];
			//expect(legend3).toBeDefined();
			//expect(legend3.getAttribute('style')).toBe('float: left; position: relative; background-color: ' + scope.lineChart.getLegend().getBackgroundColor() + ';');
    	});

    	it('to NW works fine', function(){
    		scope.lineChart.updateParameters(json4);
			scope.changedD = !scope.changedD;
    		scope.$digest();
    		//var legend4 = element.children()[2];
			//expect(legend4).toBeDefined();
			//expect(legend4.getAttribute('style')).toBe('float: left; position: relative; top: -' + scope.lineChart.getHeight() + 'px; background-color: ' + scope.lineChart.getLegend().getBackgroundColor() + ';');
		});

		it('to W works fine', function(){
    		scope.lineChart.updateParameters(json5);
			scope.changedD = !scope.changedD;
    		scope.$digest();
    		//var legend5 = element.children()[2];
			//expect(legend5).toBeDefined();
			//expect(legend5.getAttribute('style')).toBe('float: left; position: relative; top: -' + (scope.lineChart.getHeight()/2) + 'px; background-color: ' + scope.lineChart.getLegend().getBackgroundColor() + ';');
		});

		it('to NE works fine', function(){
    		scope.lineChart.updateParameters(json6);
			scope.changedD = !scope.changedD;
    		scope.$digest();
    		//var legend6 = element.children()[2];
			//expect(legend6).toBeDefined();
			//expect(legend6.getAttribute('style')).toBe('float: left; position: relative; top: -' + scope.lineChart.getHeight() + 'px; right: -' + scope.lineChart.getWidth() + 'px; background-color: ' + scope.lineChart.getLegend().getBackgroundColor() + ';');*/
		});

		it('to E works fine', function(){
    		scope.lineChart.updateParameters(json7);
			scope.changedD = !scope.changedD;
    		scope.$digest();
    		//var legend7 = element.find('div.lineChartLegend');
			//expect(legend7).toBeDefined();
			//expect(legend7.getAttribute('style')).toBe('float: left; position: relative; top: -' + (scope.lineChart.getHeight()/2) + 'px; right: -' + scope.lineChart.getWidth() + 'px;  background-color: ' + scope.$parent.getLegend().getBackgroundColor() + ';');
		});

	});

});<|endoftext|>


<commit_before>'use strict';

var Level3MediaPortalAPI = require('../lib/Level3MediaPortalAPI.js');

/*
  ======== A Handy Little Nodeunit Reference ========
  https://github.com/caolan/nodeunit

  Test methods:
    test.expect(numAssertions)
    test.done()
  Test assertions:
    test.ok(value, [message])
    test.equal(actual, expected, [message])
    test.notEqual(actual, expected, [message])
    test.deepEqual(actual, expected, [message])
    test.notDeepEqual(actual, expected, [message])
    test.strictEqual(actual, expected, [message])
    test.notStrictEqual(actual, expected, [message])
    test.throws(block, [error], [message])
    test.doesNotThrow(block, [error], [message])
    test.ifError(value)
*/

exports['awesome'] = {
  setUp: function(done) {
    // setup here
    done();
  },
  'no args': function(test) {
    test.expect(1);
    // tests here
    test.equal(Level3MediaPortalAPI.awesome('awesome'), 'awesome', 'should be awesome.');
    test.done();
  },
};
<commit_msg>fix test<commit_after>'use strict';

var api = require('../lib/Level3MediaPortalAPI.js');

/*
  ======== A Handy Little Nodeunit Reference ========
  https://github.com/caolan/nodeunit

  Test methods:
    test.expect(numAssertions)
    test.done()
  Test assertions:
    test.ok(value, [message])
    test.equal(actual, expected, [message])
    test.notEqual(actual, expected, [message])
    test.deepEqual(actual, expected, [message])
    test.notDeepEqual(actual, expected, [message])
    test.strictEqual(actual, expected, [message])
    test.notStrictEqual(actual, expected, [message])
    test.throws(block, [error], [message])
    test.doesNotThrow(block, [error], [message])
    test.ifError(value)
*/

exports['awesome'] = {
  setUp: function(done) {
    // setup here
    done();
  },
  'no args': function(test) {
    test.expect(1);
    // tests here
    test.equal(api.config.key, '', 'should be empty.');
    test.done();
  },
};
<|endoftext|>