define(['format', 'expectation', 'obj-diff', 'is-equal', 'get-type'],
function (format, Expectation, diff, isEqual, getType) {
    "use strict";
    function Xcon () {

        // skins a console.log message to display the primitive type as well
        // as the expected output of a vanilla .log() command.  Accepts an
        // arbitrary number of arguments.
        // opts: {
        //     "color": "#f9f9f9", // specify a css color
        //     "background": "rgb(0, 0, 0)", // specify a css color
        //     "log": true // also calls native console.log, which is useful for large objects and arrays
        // }
        // sometimes this function is called from console.run() to output
        // function return values.  In that case,
        // opts: {
        //     "color": "darkgreen", // or red
        //     "fnName": "nameOfFunction",
        //     "fnArgs": "all passed arguments",
        //     "error": true // indicates a thrown error
        // }
        this.out = this.out || function (blob, opts) {
            var logMsg,
                noOptsHash,
                n;
            opts = arguments[arguments.length - 1] || {};
            noOptsHash = !(opts.color || opts.background || opts.log
                || opts.error || opts.test || opts.fnName || opts.fnArgs);
            opts = noOptsHash ? {} : opts;
            if (arguments.length > this.out.length) {
                blob = noOptsHash ? Array.prototype.slice.call(arguments) : Array.prototype.slice.call(arguments, 0, -1);
            }
            logMsg = format(blob, opts);
            this.log(logMsg[0], logMsg[1]);
            for (n in logMsg[2]) {
                this.log(logMsg[2][n]);
            }
        };

        // given a function, calls that function, returns the output,
        // and calls .out() to skin the output in green (success)
        // or red (failure).  Arguments, function name, and any error
        // messages are logged.
        this.run = this.run || function (fn, args, context) {
            if (typeof fn !== 'function') {
                this.out(arguments[0], arguments[1]);
                return arguments[0];
            }
            context = context || this;
            args = args || [];
            var result,
                opts = {
                    "fnName": fn.name || 'anonymous function',
                    "fnArgs": args.toString()
                };
            try {
                result = fn.apply(context, args);
                opts.color = 'darkgreen';
                this.out(result, opts);
                return result;
            } catch (e) {
                opts.color = 'red';
                opts.error = true;
                this.out(e.message, opts);
            }
        };

        // borrows heavily from jasmine.js syntax
        // console.expect instantiates an expectation object
        // with methods to test equality, truthiness,
        // falsiness, and whether or not data is defined.
        // Adding .not works the same way as jasmine.
        this.expect = this.expect || function (thing) {
            var expect = new Expectation(this, thing);
            expect.not = new Expectation(this, thing, {"not": true});
            return expect;
        };

        // given two objects or two arrays, returns two objects/arrays
        // containing only the unique data for the corresponding argument.
        // ex: console.diff({"a": 1}, {"a": 1, "b": 2});
        // will return one empty object (no unique data in first arg)
        // and one object: {"b": 2} (the only unique data in second arg)
        this.diff = this.diff || function (obj, compare) {
            if (typeof obj !== "object" || typeof compare !== "object") {
                this.out("both arguments must be objects or arrays", {
                    "test": true,
                    "color": "red"
                });
                return;
            }
            if (isEqual(obj, compare)) {
                this.out("both arguments are equal", {
                    "test": true,
                    "color": "darkgreen"
                });
                return;
            }
            var diffs = diff(obj, compare);
            if (!diffs.errorMessage) {
                this.out("first " + getType(obj) + " has unique data:" + diffs.firstObjectDiff, {
                    "test": true,
                    "color": "black",
                    "background": "lightblue"
                });
                this.out("second " + getType(compare) + " has unique data:" + diffs.secondObjectDiff, {
                    "test": true,
                    "color": "black",
                    "background": "khaki"
                });
            } else {
                this.out(diffs.errorMessage, {
                    "test": true,
                    "color": "black",
                    "background": "lightgray"
                });
                if (diffs.firstObjectDiff) {
                    this.log(obj);
                }
                if (diffs.secondObjectDiff) {
                    this.log(compare);
                }
            }
        };

        return this;

    }

    return Xcon.call(window.console);
});

@@ -1017,22 +1017,12 @@
 on (
-blob, opts
 ) %7B%0A
+
     
@@ -1086,18 +1086,44 @@
        n
-;%0A
+,%0A                blob,%0A    
         
@@ -1363,66 +1363,8 @@
 ts;%0A
-            if (arguments.length %3E this.out.length) %7B%0A    
     
@@ -1477,30 +1477,16 @@
 0, -1);%0A
-            %7D%0A
         

fix bug that looks for an opts hash in the second argument