<commit_before>// FIXME: https://github.com/mozilla/task.js/issues/17

/* task.js v{{version}} taskjs.org | taskjs.org/license */
(function(global) {

// local name for this module
var exports;

var hasPrevious = "task" in global;
var previous = global.task;

function uninstall() {
    if (hasPrevious)
        global.task = previous;
    else
        delete global.task;
    return exports;
}

function enqueue_setTimeout() {
    function enqueue(thunk) {
        global.setTimeout(thunk, 0);
    }
    return enqueue;
}

function enqueue_nextTick() {
    function enqueue(thunk) {
        global.process.nextTick(thunk);
    }
    return enqueue;
}

// http://ajaxian.com/archives/settimeout-delay
function enqueue_postMessage() {
    var timeouts = [];
    var messageName = "zero-timeout-message";

    function enqueue(thunk) {
        timeouts.push(thunk);
        global.postMessage(messageName, "*");
    }

    global.addEventListener("message", function(event) {
        if (event.source === global && event.data === messageName) {
            event.stopPropagation();
            if (timeouts.length > 0) {
                var thunk = timeouts.shift();
                thunk();
            }
        }
    }, true);

    return enqueue;
}

// FIXME: https://github.com/mozilla/task.js/issues/17

// {{#browser}}
// var enqueue = (typeof global.postMessage === "function")
//             ? enqueue_postMessage()
//             : enqueue_setTimeout();
// {{/browser}}

// {{#node}}
// var enqueue = enqueue_nextTick();
// {{/node}}

// Inspired by:
// https://github.com/kriszyp/node-promise/blob/master/promise.js

// Differences:
// - does not flatten promises on `then`
// - currently no enforcement of throwing
// - uses task.js's `enqueue`
// - null out deferred's waiting queue

function Promise() {
    if (!(this instanceof Promise))
        return new Promise();
}

Promise.prototype = {
    get: function(key) {
        return this.then(function(obj) {
            return obj[key];
        });
    },
    put: function(key, val) {
        return this.then(function(obj) {
            return obj[key] = val;
        });
    },
    call: function(key) {
        return this.then(function(obj) {
            return obj[key].apply(obj, Array.prototype.slice.call(arguments, 1));
        });
    },
    addCallback: function(callback) {
        return this.then(callback);
    },
    addErrback: function(errback) {
        return this.then(function(){}, errback);
    },
    addBoth: function(callback) {
        return this.then(callback, callback);
    },
    addCallbacks: function(callback, errback) {
        return this.then(callback, errback);
    },
    timeout: function(delay, compensate) {
        return choose(this, sleep(delay, compensate).then(function() {
            throw new Error("timeout (" + delay + ")")
        }));
    }
};

const P_UNRESOLVED = 0;
const P_RESOLVED = 1;
const P_REJECTED = 2;
const P_CANCELLED = 3;

function Deferred(cancel) {
    if (!(this instanceof Deferred))
        return new Deferred(cancel);

    // FIXME: could do the "nobody ever saw this error, throw it somewhere!" that node-promise does
    var result, state = P_UNRESOLVED, waiting = [];
    var promise = this.promise = new Promise();

    function notifyAll(value, rejected) {
        switch (state) {
          case P_CANCELLED:
            return;
          case P_UNRESOLVED:
            break;
          default:
            throw new TypeError("deferred is already resolved (state is " + state + ")");
        }
        state = rejected ? P_REJECTED : P_RESOLVED;
        result = value;
        for (var i = 0, n = waiting.length; i < n; i++)
            notify(waiting[i]);
        waiting = null;
    }

    function notify(listener) {
        var func = state === P_REJECTED ? listener.onError : listener.onResolve;
        if (func) {
            exports.enqueue(function() {
                try {
                    listener.next.resolve(func(result));
                } catch (e) {
                    listener.next.reject(e);
                }
            });
        } else if (state === P_REJECTED) {
            listener.next.reject(result);
        } else {
            listener.next.resolve(result);
        }
    }

    this.resolve = this.callback = this.emitSuccess = function(value) {
        notifyAll(value, false);
    };

    var reject = this.reject = this.errback = this.emitError = function(error) {
        notifyAll(error, true);
    };

    this.progress = function(update) {
        for (var i = 0, n = waiting.length; i < n; i++) {
            var progress = waiting[i].progress;
            progress && progress(update);
        }
    };

    this.then = promise.then = function(onResolve, onError, onProgress) {
        var next = new Deferred(cancel);
        var listener = {
            onResolve: onResolve,
            onError: onError,
            onProgress: onProgress,
            next: next
        };
        if (state !== P_UNRESOLVED)
            notify(listener);
        else
            waiting.push(listener);
        return next.promise;
    };

    this.cancel = promise.cancel = function() {
        this.state = P_CANCELLED;
        this.waiting = null;
        cancel();
    };
}

Deferred.prototype = Promise.prototype;

function now(value) {
    var deferred = new Deferred(function(){});
    deferred.resolve(value);
    return deferred.promise;
}

function never() {
    return (new Deferred(function(){})).promise;
}

function join() {
    var promises = arguments, n = promises.length;

    // resolve immediately
    if (n === 0)
        return now([]);

    var state = P_UNRESOLVED, result = new Array(n), pending = new Array(n), remaining = n;
    var cancel = function() {
        if (state !== P_UNRESOLVED)
            return;
        remaining = 0;
        state = P_CANCELLED;
        for (var i = 0; i < n; i++) {
            var p = pending[i];
            if (p)
                p.cancel();
        }
        pending = null;
    };
    var deferred = new Deferred(cancel);
    // FIXME: what do we do about the dropped results and (worse) errors here?
    //        or can we prove that the tests (and pending array) are unnecessary
    //        based on invariants of promises?
    for (var i = 0; i < n; i++) {
        (function(i) {
            var p = promises[i];
            pending[i] = p;
            p.then(function(value) {
                if (state !== P_UNRESOLVED || !pending[i])
                    return;
                result[i] = value;
                if ((--remaining) === 0) {
                    state = P_RESOLVED;
                    pending = null;
                    deferred.resolve(result);
                } else {
                    pending[i] = null;
                }
            }, function(e) {
                if (state !== P_UNRESOLVED || !pending[i])
                    return;
                error = e;
                remaining = 0;
                state = P_REJECTED;
                for (var j = 0; j < n; j++) {
                    if (j === i || !pending[j])
                        continue;
                    pending[j].cancel();
                }
                pending = null;
                deferred.reject(e);
            });
        })(i);
    }
    return deferred.promise;
}

function choose() {
    var promises = arguments, n = promises.length;
    var state = P_UNRESOLVED, result;
    var cancel = function() {
        if (state !== P_UNRESOLVED)
            return;
        for (var i = 0; i < n; i++)
            promises[i].cancel();
    }
    var deferred = new Deferred(cancel);
    for (var i = 0; i < n; i++) {
        (function(i) {
            promises[i].then(function(value) {
                if (state !== P_UNRESOLVED)
                    return;
                result = value;
                state = P_RESOLVED;
                for (var j = 0; j < n; j++) {
                    if (j !== i)
                        promises[j].cancel();
                }
                deferred.resolve(value);
            }, function(e) {
                if (state !== P_UNRESOLVED)
                    return;
                result = e;
                state = P_REJECTED;
                for (var j = 0; j < n; j++) {
                    if (j !== i)
                        promises[j].cancel();
                }
                deferred.reject(e);
            });
        })(i);
    }
    return deferred.promise;
}

const T_PAUSED    = 0;  // can't be scheduled or executed
const T_STARTED   = 1;  // may or may not currently be executing
const T_CANCELLED = 2;  // cancelled but not yet done cleaning up
const T_CLOSED    = 3;  // completely done

const R_BLOCKED   = 0;  // waiting on a promise
const R_RESOLVED  = 1;  // ready to resume with a resolved value
const R_REJECTED  = 2;  // ready to resume with a rejected value
const R_RUNNING   = 3;  // currently executing

var counter = 0;
function nextTID() {
    var result = counter;
    counter = (counter + 1) & 0xffffffff;
    return result;
}

function Task(thunk) {
    if (!(this instanceof Task))
        return new Task(thunk);
    this.tid = nextTID();                // thread ID
    this.result = void 0;                // intermediate or final result
    this.runState = R_RESOLVED;          // execution status within scheduler
    this.threadState = T_PAUSED;         // state in thread's lifecycle
    this.thread = thunk.call(this);      // thread
    this.scheduler = currentScheduler(); // scheduler
    this.deferred = new Deferred();
    this.then = this.deferred.then;
}

var Tp = Task.prototype = new Promise();

Tp.isStarted = function() {
    return this.threadState === T_STARTED;
};

Tp.isRunning = function() {
    return this.runState === R_RUNNING;
};

Tp.start = function() {
    if (this.threadState !== T_PAUSED)
        throw new Error("task is already started or completed");
    this.threadState = T_STARTED;
    if (this.runState !== R_BLOCKED) {
        this.scheduler.schedule(this);
        pump(this.scheduler);
    }
    return this;
};

Tp.pause = function() {
    if (this.runState === R_RUNNING)
        throw new Error("tasks can only be paused while blocked");
    this.threadState = T_PAUSED;
    this.scheduler.unschedule(this);
    return this;
};

Tp.cancel = function() {
    if (this.runState === R_RUNNING)
        throw new Error("tasks can only be cancelled while blocked");
    this.threadState = T_CANCELLED;
    this.scheduler.schedule(this);
    pump(this.scheduler);
    return this;
};

Tp.toString = function() {
    return "[object Task " + this.tid + "]";
};

const READY = now();

function runScheduledTask(task) {
    var result = task.result, send = (task.runState === R_RESOLVED);
    try {
        task.runState = R_RUNNING;
        task.result = void 0;
        if (task.threadState === T_CANCELLED) {
            task.thread.close();
            task.result = void 0;
            task.runState = R_RESOLVED;
            task.threadState = T_CLOSED;
        } else {
            var p = (send ? task.thread.send(result) : task.thread["throw"](result)) || READY;
            task.runState = R_BLOCKED;
            p.then(function(value) {
                task.result = value;
                task.runState = R_RESOLVED;
                if (task.threadState === T_STARTED) {
                    task.scheduler.schedule(task);
                    pump(task.scheduler);
                }
            }, function(e) {
                task.result = e;
                task.runState = R_REJECTED;
                if (task.threadState === T_STARTED) {
                    task.scheduler.schedule(task);
                    pump(task.scheduler);
                }
            });
        }
    } catch (e) {
        task.threadState = T_CLOSED;
        if (e instanceof TaskResult || e instanceof StopIteration) {
            task.result = e.value;
            task.runState = R_RESOLVED;
            task.deferred.resolve(e.value);
        } else {
            task.result = e;
            task.runState = R_REJECTED;
            task.deferred.reject(e);
        }
    }
}

var runningTask = null;

Task.current = function() {
    return runningTask;
}

function pump(scheduler) {
    if (runningTask)
        return;
    var task = scheduler.choose();
    if (!task)
        return;
    exports.enqueue(function() {
        runningTask = task;
        runScheduledTask(task);
        runningTask = null;
        pump(scheduler);
    });
}

function spawn(thunk) {
    return (new Task(thunk)).start();
}

function currentStack() {
    try {
        throw new Error();
    } catch (e) {
        return e.stack.split(/\n/).slice(1).map(function (line) {
            var match1 = line.match(/^[a-zA-Z0-9_]*/);
            var match2 = line.match(/[^\/]+:[0-9]+$/);
            return (match1 && match2) ? (match1[0] + "@" + match2[0]) : line;
        });
    }
}

function sourceOf(x) {
    return (x && typeof x === "object") ? x.toSource() : String(x);
}

function RandomScheduler() {
    this.ready = []; // unblocked tasks ready to resume
}

RandomScheduler.prototype = {
    choose: function() {
        var n = this.ready.length;
        if (n === 0)
            return null;
        var i = Math.floor(Math.random() * n);
        return this.ready.splice(i, 1)[0];
    },
    schedule: function(task) {
        this.ready.push(task);
    },
    unschedule: function(task) {
        var ready = this.ready;
        for (var i = 0, n = ready.length; i < n; i++) {
            if (ready[i] === task) {
                ready.splice(i, 1);
                return;
            }
        }
    }
};

var scheduler = new RandomScheduler();

function currentScheduler() {
    return scheduler;
}

function setCurrentScheduler(s) {
    scheduler = s;
}

function TaskResult(value) {
    if (!(this instanceof TaskResult))
        return new TaskResult(value);
    this.value = value;
}

TaskResult.prototype = {
    toString: function() {
        return "[TaskResult " + this.value + "]";
    }
};

function sleep(delay, compensate) {
    var start = Date.now();
    var deferred = new Deferred();
    var id = global.setTimeout(resolveOrTryAgain, delay);

    function resolveOrTryAgain() {
        var end = Date.now();
        var actual = end - start;
        if (compensate && actual < delay) {
            id = global.setTimeout(resolveOrTryAgain, delay - actual);
            return;
        }
        deferred.resolve(actual);
    }

    return deferred.promise;
}

// FIXME: https://github.com/mozilla/task.js/issues/17

/*
{{#template}}

{{declareExports}}

{{#export}}Deferred{{/export}}
{{#export}}enqueue{{/export}}
{{#export}}Task{{/export}}
{{#export}}TaskResult{{/export}}
{{#export}}join{{/export}}
{{#export}}choose{{/export}}
{{#export}}now{{/export}}
{{#export}}never{{/export}}
{{#export}}spawn{{/export}}
{{#export}}sleep{{/export}}
{{#export}}currentScheduler{{/export}}
{{#export}}setCurrentScheduler{{/export}}
{{#export}}RandomScheduler{{/export}}

{{/template}}
*/

global.task = exports = {
    uninstall: uninstall,
    Deferred: Deferred,
    enqueue: enqueue_setTimeout(),
    Task: Task,
    TaskResult: TaskResult,
    join: join,
    choose: choose,
    now: now,
    never: never,
    spawn: spawn,
    sleep: sleep,
    currentScheduler: currentScheduler,
    setCurrentScheduler: setCurrentScheduler,
    RandomScheduler: RandomScheduler
};

})(this);
<commit_msg>Some premature optimization -- don't call `Math.random` when it's not needed.<commit_after>// FIXME: https://github.com/mozilla/task.js/issues/17

/* task.js v{{version}} taskjs.org | taskjs.org/license */
(function(global) {

// local name for this module
var exports;

var hasPrevious = "task" in global;
var previous = global.task;

function uninstall() {
    if (hasPrevious)
        global.task = previous;
    else
        delete global.task;
    return exports;
}

function enqueue_setTimeout() {
    function enqueue(thunk) {
        global.setTimeout(thunk, 0);
    }
    return enqueue;
}

function enqueue_nextTick() {
    function enqueue(thunk) {
        global.process.nextTick(thunk);
    }
    return enqueue;
}

// http://ajaxian.com/archives/settimeout-delay
function enqueue_postMessage() {
    var timeouts = [];
    var messageName = "zero-timeout-message";

    function enqueue(thunk) {
        timeouts.push(thunk);
        global.postMessage(messageName, "*");
    }

    global.addEventListener("message", function(event) {
        if (event.source === global && event.data === messageName) {
            event.stopPropagation();
            if (timeouts.length > 0) {
                var thunk = timeouts.shift();
                thunk();
            }
        }
    }, true);

    return enqueue;
}

// FIXME: https://github.com/mozilla/task.js/issues/17

// {{#browser}}
// var enqueue = (typeof global.postMessage === "function")
//             ? enqueue_postMessage()
//             : enqueue_setTimeout();
// {{/browser}}

// {{#node}}
// var enqueue = enqueue_nextTick();
// {{/node}}

// Inspired by:
// https://github.com/kriszyp/node-promise/blob/master/promise.js

// Differences:
// - does not flatten promises on `then`
// - currently no enforcement of throwing
// - uses task.js's `enqueue`
// - null out deferred's waiting queue

function Promise() {
    if (!(this instanceof Promise))
        return new Promise();
}

Promise.prototype = {
    get: function(key) {
        return this.then(function(obj) {
            return obj[key];
        });
    },
    put: function(key, val) {
        return this.then(function(obj) {
            return obj[key] = val;
        });
    },
    call: function(key) {
        return this.then(function(obj) {
            return obj[key].apply(obj, Array.prototype.slice.call(arguments, 1));
        });
    },
    addCallback: function(callback) {
        return this.then(callback);
    },
    addErrback: function(errback) {
        return this.then(function(){}, errback);
    },
    addBoth: function(callback) {
        return this.then(callback, callback);
    },
    addCallbacks: function(callback, errback) {
        return this.then(callback, errback);
    },
    timeout: function(delay, compensate) {
        return choose(this, sleep(delay, compensate).then(function() {
            throw new Error("timeout (" + delay + ")")
        }));
    }
};

const P_UNRESOLVED = 0;
const P_RESOLVED = 1;
const P_REJECTED = 2;
const P_CANCELLED = 3;

function Deferred(cancel) {
    if (!(this instanceof Deferred))
        return new Deferred(cancel);

    // FIXME: could do the "nobody ever saw this error, throw it somewhere!" that node-promise does
    var result, state = P_UNRESOLVED, waiting = [];
    var promise = this.promise = new Promise();

    function notifyAll(value, rejected) {
        switch (state) {
          case P_CANCELLED:
            return;
          case P_UNRESOLVED:
            break;
          default:
            throw new TypeError("deferred is already resolved (state is " + state + ")");
        }
        state = rejected ? P_REJECTED : P_RESOLVED;
        result = value;
        for (var i = 0, n = waiting.length; i < n; i++)
            notify(waiting[i]);
        waiting = null;
    }

    function notify(listener) {
        var func = state === P_REJECTED ? listener.onError : listener.onResolve;
        if (func) {
            exports.enqueue(function() {
                try {
                    listener.next.resolve(func(result));
                } catch (e) {
                    listener.next.reject(e);
                }
            });
        } else if (state === P_REJECTED) {
            listener.next.reject(result);
        } else {
            listener.next.resolve(result);
        }
    }

    this.resolve = this.callback = this.emitSuccess = function(value) {
        notifyAll(value, false);
    };

    var reject = this.reject = this.errback = this.emitError = function(error) {
        notifyAll(error, true);
    };

    this.progress = function(update) {
        for (var i = 0, n = waiting.length; i < n; i++) {
            var progress = waiting[i].progress;
            progress && progress(update);
        }
    };

    this.then = promise.then = function(onResolve, onError, onProgress) {
        var next = new Deferred(cancel);
        var listener = {
            onResolve: onResolve,
            onError: onError,
            onProgress: onProgress,
            next: next
        };
        if (state !== P_UNRESOLVED)
            notify(listener);
        else
            waiting.push(listener);
        return next.promise;
    };

    this.cancel = promise.cancel = function() {
        this.state = P_CANCELLED;
        this.waiting = null;
        cancel();
    };
}

Deferred.prototype = Promise.prototype;

function now(value) {
    var deferred = new Deferred(function(){});
    deferred.resolve(value);
    return deferred.promise;
}

function never() {
    return (new Deferred(function(){})).promise;
}

function join() {
    var promises = arguments, n = promises.length;

    // resolve immediately
    if (n === 0)
        return now([]);

    var state = P_UNRESOLVED, result = new Array(n), pending = new Array(n), remaining = n;
    var cancel = function() {
        if (state !== P_UNRESOLVED)
            return;
        remaining = 0;
        state = P_CANCELLED;
        for (var i = 0; i < n; i++) {
            var p = pending[i];
            if (p)
                p.cancel();
        }
        pending = null;
    };
    var deferred = new Deferred(cancel);
    // FIXME: what do we do about the dropped results and (worse) errors here?
    //        or can we prove that the tests (and pending array) are unnecessary
    //        based on invariants of promises?
    for (var i = 0; i < n; i++) {
        (function(i) {
            var p = promises[i];
            pending[i] = p;
            p.then(function(value) {
                if (state !== P_UNRESOLVED || !pending[i])
                    return;
                result[i] = value;
                if ((--remaining) === 0) {
                    state = P_RESOLVED;
                    pending = null;
                    deferred.resolve(result);
                } else {
                    pending[i] = null;
                }
            }, function(e) {
                if (state !== P_UNRESOLVED || !pending[i])
                    return;
                error = e;
                remaining = 0;
                state = P_REJECTED;
                for (var j = 0; j < n; j++) {
                    if (j === i || !pending[j])
                        continue;
                    pending[j].cancel();
                }
                pending = null;
                deferred.reject(e);
            });
        })(i);
    }
    return deferred.promise;
}

function choose() {
    var promises = arguments, n = promises.length;
    var state = P_UNRESOLVED, result;
    var cancel = function() {
        if (state !== P_UNRESOLVED)
            return;
        for (var i = 0; i < n; i++)
            promises[i].cancel();
    }
    var deferred = new Deferred(cancel);
    for (var i = 0; i < n; i++) {
        (function(i) {
            promises[i].then(function(value) {
                if (state !== P_UNRESOLVED)
                    return;
                result = value;
                state = P_RESOLVED;
                for (var j = 0; j < n; j++) {
                    if (j !== i)
                        promises[j].cancel();
                }
                deferred.resolve(value);
            }, function(e) {
                if (state !== P_UNRESOLVED)
                    return;
                result = e;
                state = P_REJECTED;
                for (var j = 0; j < n; j++) {
                    if (j !== i)
                        promises[j].cancel();
                }
                deferred.reject(e);
            });
        })(i);
    }
    return deferred.promise;
}

const T_PAUSED    = 0;  // can't be scheduled or executed
const T_STARTED   = 1;  // may or may not currently be executing
const T_CANCELLED = 2;  // cancelled but not yet done cleaning up
const T_CLOSED    = 3;  // completely done

const R_BLOCKED   = 0;  // waiting on a promise
const R_RESOLVED  = 1;  // ready to resume with a resolved value
const R_REJECTED  = 2;  // ready to resume with a rejected value
const R_RUNNING   = 3;  // currently executing

var counter = 0;
function nextTID() {
    var result = counter;
    counter = (counter + 1) & 0xffffffff;
    return result;
}

function Task(thunk) {
    if (!(this instanceof Task))
        return new Task(thunk);
    this.tid = nextTID();                // thread ID
    this.result = void 0;                // intermediate or final result
    this.runState = R_RESOLVED;          // execution status within scheduler
    this.threadState = T_PAUSED;         // state in thread's lifecycle
    this.thread = thunk.call(this);      // thread
    this.scheduler = currentScheduler(); // scheduler
    this.deferred = new Deferred();
    this.then = this.deferred.then;
}

var Tp = Task.prototype = new Promise();

Tp.isStarted = function() {
    return this.threadState === T_STARTED;
};

Tp.isRunning = function() {
    return this.runState === R_RUNNING;
};

Tp.start = function() {
    if (this.threadState !== T_PAUSED)
        throw new Error("task is already started or completed");
    this.threadState = T_STARTED;
    if (this.runState !== R_BLOCKED) {
        this.scheduler.schedule(this);
        pump(this.scheduler);
    }
    return this;
};

Tp.pause = function() {
    if (this.runState === R_RUNNING)
        throw new Error("tasks can only be paused while blocked");
    this.threadState = T_PAUSED;
    this.scheduler.unschedule(this);
    return this;
};

Tp.cancel = function() {
    if (this.runState === R_RUNNING)
        throw new Error("tasks can only be cancelled while blocked");
    this.threadState = T_CANCELLED;
    this.scheduler.schedule(this);
    pump(this.scheduler);
    return this;
};

Tp.toString = function() {
    return "[object Task " + this.tid + "]";
};

const READY = now();

function runScheduledTask(task) {
    var result = task.result, send = (task.runState === R_RESOLVED);
    try {
        task.runState = R_RUNNING;
        task.result = void 0;
        if (task.threadState === T_CANCELLED) {
            task.thread.close();
            task.result = void 0;
            task.runState = R_RESOLVED;
            task.threadState = T_CLOSED;
        } else {
            var p = (send ? task.thread.send(result) : task.thread["throw"](result)) || READY;
            task.runState = R_BLOCKED;
            p.then(function(value) {
                task.result = value;
                task.runState = R_RESOLVED;
                if (task.threadState === T_STARTED) {
                    task.scheduler.schedule(task);
                    pump(task.scheduler);
                }
            }, function(e) {
                task.result = e;
                task.runState = R_REJECTED;
                if (task.threadState === T_STARTED) {
                    task.scheduler.schedule(task);
                    pump(task.scheduler);
                }
            });
        }
    } catch (e) {
        task.threadState = T_CLOSED;
        if (e instanceof TaskResult || e instanceof StopIteration) {
            task.result = e.value;
            task.runState = R_RESOLVED;
            task.deferred.resolve(e.value);
        } else {
            task.result = e;
            task.runState = R_REJECTED;
            task.deferred.reject(e);
        }
    }
}

var runningTask = null;

Task.current = function() {
    return runningTask;
}

function pump(scheduler) {
    if (runningTask)
        return;
    var task = scheduler.choose();
    if (!task)
        return;
    exports.enqueue(function() {
        runningTask = task;
        runScheduledTask(task);
        runningTask = null;
        pump(scheduler);
    });
}

function spawn(thunk) {
    return (new Task(thunk)).start();
}

function currentStack() {
    try {
        throw new Error();
    } catch (e) {
        return e.stack.split(/\n/).slice(1).map(function (line) {
            var match1 = line.match(/^[a-zA-Z0-9_]*/);
            var match2 = line.match(/[^\/]+:[0-9]+$/);
            return (match1 && match2) ? (match1[0] + "@" + match2[0]) : line;
        });
    }
}

function sourceOf(x) {
    return (x && typeof x === "object") ? x.toSource() : String(x);
}

function RandomScheduler() {
    this.ready = []; // unblocked tasks ready to resume
}

RandomScheduler.prototype = {
    choose: function() {
        var n = this.ready.length;
        if (n === 0)
            return null;
        if (n === 1) {
            var r = this.ready[0];
            this.ready = []
            return r;
        }
        var i = Math.floor(Math.random() * n);
        return this.ready.splice(i, 1)[0];
    },
    schedule: function(task) {
        this.ready.push(task);
    },
    unschedule: function(task) {
        var ready = this.ready;
        for (var i = 0, n = ready.length; i < n; i++) {
            if (ready[i] === task) {
                ready.splice(i, 1);
                return;
            }
        }
    }
};

var scheduler = new RandomScheduler();

function currentScheduler() {
    return scheduler;
}

function setCurrentScheduler(s) {
    scheduler = s;
}

function TaskResult(value) {
    if (!(this instanceof TaskResult))
        return new TaskResult(value);
    this.value = value;
}

TaskResult.prototype = {
    toString: function() {
        return "[TaskResult " + this.value + "]";
    }
};

function sleep(delay, compensate) {
    var start = Date.now();
    var deferred = new Deferred();
    var id = global.setTimeout(resolveOrTryAgain, delay);

    function resolveOrTryAgain() {
        var end = Date.now();
        var actual = end - start;
        if (compensate && actual < delay) {
            id = global.setTimeout(resolveOrTryAgain, delay - actual);
            return;
        }
        deferred.resolve(actual);
    }

    return deferred.promise;
}

// FIXME: https://github.com/mozilla/task.js/issues/17

/*
{{#template}}

{{declareExports}}

{{#export}}Deferred{{/export}}
{{#export}}enqueue{{/export}}
{{#export}}Task{{/export}}
{{#export}}TaskResult{{/export}}
{{#export}}join{{/export}}
{{#export}}choose{{/export}}
{{#export}}now{{/export}}
{{#export}}never{{/export}}
{{#export}}spawn{{/export}}
{{#export}}sleep{{/export}}
{{#export}}currentScheduler{{/export}}
{{#export}}setCurrentScheduler{{/export}}
{{#export}}RandomScheduler{{/export}}

{{/template}}
*/

global.task = exports = {
    uninstall: uninstall,
    Deferred: Deferred,
    enqueue: enqueue_setTimeout(),
    Task: Task,
    TaskResult: TaskResult,
    join: join,
    choose: choose,
    now: now,
    never: never,
    spawn: spawn,
    sleep: sleep,
    currentScheduler: currentScheduler,
    setCurrentScheduler: setCurrentScheduler,
    RandomScheduler: RandomScheduler
};

})(this);
<|endoftext|>


<commit_before>// ==UserScript==
// @name         Disable story and defects efforts and todo's
// @namespace    Razor
// @version      0.5
// @match        http://v1.bwinparty.corp/V1-Production/Default.aspx?*DetailTrackingPage*
// @grant        none
// ==/UserScript==

$(function () {
    $("input[_v1_updater_new_key='_new_SimpleStoryEffortColumn']").prop('disabled', 'disabled');
    $("input[_v1_updater='Story.ToDo']").prop('disabled', 'disabled');
    $("span[_v1_updater_new_key='_new_StoryEffortColumn']").find("input, select").prop('disabled', 'disabled');

    $("input[_v1_updater_new_key='_new_SimpleDefectEffortColumn']").prop('disabled', 'disabled');
    $("input[_v1_updater='Defect.ToDo']").prop('disabled', 'disabled');
    $("span[_v1_updater_new_key='_new_DefectEffortColumn']").find("input, select").prop('disabled', 'disabled');
});<commit_msg>Fixed bug with change team.<commit_after>// ==UserScript==
// @name         Disable story and defects efforts and todo's
// @namespace    Razor
// @version      0.5.1
// @match        http://v1.bwinparty.corp/V1-Production/Default.aspx?*DetailTrackingPage*
// @require      https://raw.githubusercontent.com/kapetan/jquery-observe/master/jquery-observe.js
// @grant        none
// ==/UserScript==

$(function () {
    var arr = [
                "input[_v1_updater_new_key='_new_SimpleStoryEffortColumn']",
                "input[_v1_updater='Story.ToDo']",
                "span[_v1_updater_new_key='_new_StoryEffortColumn'] input",
                "span[_v1_updater_new_key='_new_StoryEffortColumn'] select",
                "input[_v1_updater_new_key='_new_SimpleDefectEffortColumn']",
                "input[_v1_updater='Defect.ToDo']",
                "span[_v1_updater_new_key='_new_DefectEffortColumn'] input",
                "span[_v1_updater_new_key='_new_DefectEffortColumn'] select"
    ];
    var selector = arr.join();
    $(selector).prop('disabled', 'disabled');

    $("body").observe("added", selector, function () {
        $(this).prop('disabled', 'disabled');
    });
});<|endoftext|>


<commit_before>
// ----------------------------------------------------------------
// ----------------------------------------------------------------
// ----------------------------------------------------------------
"use strict";

mergeInto(LibraryManager.library, {
	// ----------------------------------------------------------------

	// プラグイン初期化
	webPluginSoundInit: function(){
		this.globalWebPluginSound = {};

		// WebAudioAPIのAudioContextを作成
		var soundContext = null;
		if(soundContext == null){try{soundContext = new AudioContext();}catch(e){}}
		if(soundContext == null){try{soundContext = new webkitAudioContext();}catch(e){}}
		if(soundContext != null){
			// WebAudioAPIのAudioContext作成成功
			var createGain = function(){return (!!soundContext.createGain) ? soundContext.createGain() : soundContext.createGainNode();};
			var sourceStart = function(source, when){if(!!source.start){source.start(when);}else{source.noteOn(when);}};
			var sourceStop = function(source, when){if(!!source.stop){source.stop(when);}else{source.noteOff(when);}};
			globalWebPluginSound.bgmVolumeGain = createGain();
			globalWebPluginSound.seVolumeGain = createGain();
			globalWebPluginSound.bgmVolumeGain.connect(soundContext.destination);
			globalWebPluginSound.seVolumeGain.connect(soundContext.destination);

			globalWebPluginSound.bgmList = {};
			globalWebPluginSound.seList = {};
			globalWebPluginSound.bgmZeroId = 0;
			globalWebPluginSound.bgmCurrentId = 0;
			globalWebPluginSound.bgmToneDown = 1.0;

			// 音楽ファイル拡張子
			globalWebPluginSound.soundSuffix = ".m4a";
			var userAgent = window.navigator.userAgent.toLowerCase();
			if(userAgent.indexOf('firefox') > 0){globalWebPluginSound.soundSuffix = ".ogg";}
			if(userAgent.indexOf('opera') > 0){globalWebPluginSound.soundSuffix = ".ogg";}

			// BGM再生関数
			globalWebPluginSound.bgmPlay = function(bgmId){
				globalWebPluginSound.bgmToneDown = 1.0;

				// 同じBGMを再生中なら何もしない
				if(globalWebPluginSound.bgmCurrentId == bgmId){return;}
				var playData = globalWebPluginSound.bgmList[bgmId];
				if(playData == null){globalWebPluginSound.bgmCurrentId = 0; return;}
				globalWebPluginSound.bgmCurrentId = bgmId;
				if(playData.isPlaying){return;}

				playData.play(playData);
			};

			// SE再生関数
			globalWebPluginSound.sePlay = function(seId){
				var playData = globalWebPluginSound.seList[seId];
				if(playData.buffer == null){return;}
				var when = globalWebPluginSound.soundContext.currentTime;
				var source = globalWebPluginSound.soundContext.createBufferSource();
				source.buffer = playData.buffer;
				source.connect(globalWebPluginSound.seVolumeGain);
				sourceStart(source, when);
			};

			// 音楽読込関数
			globalWebPluginSound.soundLoader = function(playData){
				var xhr = new XMLHttpRequest();
				xhr.open("GET", playData.src, true);
				xhr.responseType = "arraybuffer";
				xhr.onreadystatechange = function(e){
					if(xhr.readyState == 4 && xhr.status == 200){
						soundContext.decodeAudioData(xhr.response, function(buffer){
							playData.buffer = buffer;
						});
					}
				};
				xhr.send();
			};
			globalWebPluginSound.soundLoaderBgm = function(src, bgmId){
				globalWebPluginSound.soundLoader(globalWebPluginSound.bgmList[bgmId] = {
					bgmId: bgmId,
					src: src + globalWebPluginSound.soundSuffix,
					countMax: 30,
					countPrev: 0,
					isPlaying: false,
					buffer: null,
					// 再生開始
					play: function(){this.callback(this);},
					// タイマーコールバック
					callback: function(self){if(self.playing()){setTimeout(self.callback, 100, self);}},
					// 再生関数
					playing: function(){
						var isActive = (globalWebPluginSound.bgmCurrentId == this.bgmId && !globalWebFuhahaSurface.isExit);
						if(isActive || this.countPrev > 0){
							if(!this.isPlaying && this.buffer != null){
								// BGM作成と再生
								this.gain = createGain();
								this.source = globalWebPluginSound.soundContext.createBufferSource();
								this.source.loop = true;
								this.source.buffer = this.buffer;
								this.source.connect(this.gain);
								this.gain.value = 0.0;
								this.gain.connect(globalWebPluginSound.bgmVolumeGain);
								sourceStart(this.source, globalWebPluginSound.soundContext.currentTime);
								this.countPrev = 0;
								this.isPlaying = true;
							}

							if(this.isPlaying){
								// BGMのボリュームフェード監視
								var countNext = isActive ? Math.round(this.countMax * globalWebPluginSound.bgmToneDown) : 0;
								if(this.countPrev != countNext){
									if(countNext > this.countPrev){this.countPrev++;}
									if(countNext < this.countPrev){this.countPrev--;}
									var effectVolume = this.countPrev / this.countMax;
									this.gain.gain.setValueAtTime(effectVolume, globalWebPluginSound.soundContext.currentTime);
								}
							}

							return true;
						}else{
							// BGMの停止と破棄
							sourceStop(this.source, globalWebPluginSound.soundContext.currentTime);
							this.gain = null;
							this.source = null;
							this.isPlaying = false;
						}

						return false;
					},
				});
			};
			globalWebPluginSound.soundLoaderSe = function(src, seId){
				globalWebPluginSound.soundLoader(globalWebPluginSound.seList[seId] = {
					src: src + globalWebPluginSound.soundSuffix,
					buffer: null,
				});
			};

			// タッチしないと音を再生開始しない端末のための無音再生
			globalWebPluginSound.soundTouch = function(){
				if(globalWebPluginSound.soundTrigger){
					globalWebPluginSound.soundTrigger = false;
					var source = globalWebPluginSound.soundContext.createBufferSource();
					source.connect(globalWebPluginSound.soundContext.destination);
					sourceStart(source, globalWebPluginSound.soundContext.currentTime);
				}
			};

			globalWebPluginSound.soundTrigger = true;
			globalWebPluginSound.soundContext = soundContext;
		}
	},

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

	// BGM読込
	platformPluginSoundBgmLoad: function(bgmId, src){
		if(globalWebPluginSound.soundContext == null){return;}
		if(bgmId <= 0){return;}
		if(globalWebPluginSound.bgmList[bgmId] != null){return;}
		globalWebPluginSound.soundLoaderBgm(Pointer_stringify(src), bgmId);
	},

	// BGM再生
	platformPluginSoundBgmPlay: function(bgmId){
		if(globalWebPluginSound.soundContext == null){return;}
		globalWebPluginSound.bgmZeroId = bgmId;
		var oldVolume = globalWebPluginSound.bgmVolumeGain.gain.value;
		if(oldVolume > 0){globalWebPluginSound.bgmPlay(bgmId);}
	},

	// BGMトーンダウン
	platformPluginSoundBgmToneDown: function(volume){
		if(globalWebPluginSound.soundContext == null){return;}
		globalWebPluginSound.bgmToneDown = volume;
	},

	// BGM設定音量
	platformPluginSoundBgmVolume: function(volume){
		if(globalWebPluginSound.soundContext == null){return;}

		// 音量をゼロにした瞬間とゼロから戻した瞬間
		var oldVolume = globalWebPluginSound.bgmVolumeGain.gain.value;
		if(oldVolume > 0 && volume <= 0){globalWebPluginSound.bgmPlay(0);}
		if(oldVolume <= 0 && volume > 0){globalWebPluginSound.bgmPlay(globalWebPluginSound.bgmZeroId);}

		globalWebPluginSound.bgmVolumeGain.gain.value = volume;
	},

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

	// SE読込
	platformPluginSoundSeLoad: function(seId, src){
		if(globalWebPluginSound.soundContext == null){return;}
		if(seId <= 0){return;}
		if(globalWebPluginSound.seList[seId] != null){return;}
		globalWebPluginSound.soundLoaderSe(Pointer_stringify(src), seId);
	},

	// SE再生
	platformPluginSoundSePlay: function(seId){
		if(globalWebPluginSound.soundContext == null){return;}
		globalWebPluginSound.sePlay(seId);
	},

	// SE設定音量
	platformPluginSoundSeVolume: function(volume){
		if(globalWebPluginSound.soundContext == null){return;}
		globalWebPluginSound.seVolumeGain.gain.value = volume;
	},

	// ----------------------------------------------------------------
});

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

<commit_msg>setter of gain.value -> setValueAtTime<commit_after>
// ----------------------------------------------------------------
// ----------------------------------------------------------------
// ----------------------------------------------------------------
"use strict";

mergeInto(LibraryManager.library, {
	// ----------------------------------------------------------------

	// プラグイン初期化
	webPluginSoundInit: function(){
		this.globalWebPluginSound = {};

		// WebAudioAPIのAudioContextを作成
		var soundContext = null;
		if(soundContext == null){try{soundContext = new AudioContext();}catch(e){}}
		if(soundContext == null){try{soundContext = new webkitAudioContext();}catch(e){}}
		if(soundContext != null){
			// WebAudioAPIのAudioContext作成成功
			var createGain = function(){return (!!soundContext.createGain) ? soundContext.createGain() : soundContext.createGainNode();};
			var sourceStart = function(source, when){if(!!source.start){source.start(when);}else{source.noteOn(when);}};
			var sourceStop = function(source, when){if(!!source.stop){source.stop(when);}else{source.noteOff(when);}};
			globalWebPluginSound.bgmVolumeGain = createGain();
			globalWebPluginSound.seVolumeGain = createGain();
			globalWebPluginSound.bgmVolumeGain.connect(soundContext.destination);
			globalWebPluginSound.seVolumeGain.connect(soundContext.destination);

			globalWebPluginSound.bgmList = {};
			globalWebPluginSound.seList = {};
			globalWebPluginSound.bgmZeroId = 0;
			globalWebPluginSound.bgmCurrentId = 0;
			globalWebPluginSound.bgmToneDown = 1.0;

			// 音楽ファイル拡張子
			globalWebPluginSound.soundSuffix = ".m4a";
			var userAgent = window.navigator.userAgent.toLowerCase();
			if(userAgent.indexOf('firefox') > 0){globalWebPluginSound.soundSuffix = ".ogg";}
			if(userAgent.indexOf('opera') > 0){globalWebPluginSound.soundSuffix = ".ogg";}

			// BGM再生関数
			globalWebPluginSound.bgmPlay = function(bgmId){
				globalWebPluginSound.bgmToneDown = 1.0;

				// 同じBGMを再生中なら何もしない
				if(globalWebPluginSound.bgmCurrentId == bgmId){return;}
				var playData = globalWebPluginSound.bgmList[bgmId];
				if(playData == null){globalWebPluginSound.bgmCurrentId = 0; return;}
				globalWebPluginSound.bgmCurrentId = bgmId;
				if(playData.isPlaying){return;}

				playData.play(playData);
			};

			// SE再生関数
			globalWebPluginSound.sePlay = function(seId){
				var playData = globalWebPluginSound.seList[seId];
				if(playData.buffer == null){return;}
				var when = globalWebPluginSound.soundContext.currentTime;
				var source = globalWebPluginSound.soundContext.createBufferSource();
				source.buffer = playData.buffer;
				source.connect(globalWebPluginSound.seVolumeGain);
				sourceStart(source, when);
			};

			// 音楽読込関数
			globalWebPluginSound.soundLoader = function(playData){
				var xhr = new XMLHttpRequest();
				xhr.open("GET", playData.src, true);
				xhr.responseType = "arraybuffer";
				xhr.onreadystatechange = function(e){
					if(xhr.readyState == 4 && xhr.status == 200){
						soundContext.decodeAudioData(xhr.response, function(buffer){
							playData.buffer = buffer;
						});
					}
				};
				xhr.send();
			};
			globalWebPluginSound.soundLoaderBgm = function(src, bgmId){
				globalWebPluginSound.soundLoader(globalWebPluginSound.bgmList[bgmId] = {
					bgmId: bgmId,
					src: src + globalWebPluginSound.soundSuffix,
					countMax: 30,
					countPrev: 0,
					isPlaying: false,
					buffer: null,
					// 再生開始
					play: function(){this.callback(this);},
					// タイマーコールバック
					callback: function(self){if(self.playing()){setTimeout(self.callback, 100, self);}},
					// 再生関数
					playing: function(){
						var isActive = (globalWebPluginSound.bgmCurrentId == this.bgmId && !globalWebFuhahaSurface.isExit);
						if(isActive || this.countPrev > 0){
							if(!this.isPlaying && this.buffer != null){
								// BGM作成と再生
								this.gain = createGain();
								this.source = globalWebPluginSound.soundContext.createBufferSource();
								this.source.loop = true;
								this.source.buffer = this.buffer;
								this.source.connect(this.gain);
								this.gain.gain.setValueAtTime(0.0, globalWebPluginSound.soundContext.currentTime);
								this.gain.connect(globalWebPluginSound.bgmVolumeGain);
								sourceStart(this.source, globalWebPluginSound.soundContext.currentTime);
								this.countPrev = 0;
								this.isPlaying = true;
							}

							if(this.isPlaying){
								// BGMのボリュームフェード監視
								var countNext = isActive ? Math.round(this.countMax * globalWebPluginSound.bgmToneDown) : 0;
								if(this.countPrev != countNext){
									if(countNext > this.countPrev){this.countPrev++;}
									if(countNext < this.countPrev){this.countPrev--;}
									var effectVolume = this.countPrev / this.countMax;
									this.gain.gain.setValueAtTime(effectVolume, globalWebPluginSound.soundContext.currentTime);
								}
							}

							return true;
						}else{
							// BGMの停止と破棄
							sourceStop(this.source, globalWebPluginSound.soundContext.currentTime);
							this.gain = null;
							this.source = null;
							this.isPlaying = false;
						}

						return false;
					},
				});
			};
			globalWebPluginSound.soundLoaderSe = function(src, seId){
				globalWebPluginSound.soundLoader(globalWebPluginSound.seList[seId] = {
					src: src + globalWebPluginSound.soundSuffix,
					buffer: null,
				});
			};

			// タッチしないと音を再生開始しない端末のための無音再生
			globalWebPluginSound.soundTouch = function(){
				if(globalWebPluginSound.soundTrigger){
					globalWebPluginSound.soundTrigger = false;
					var source = globalWebPluginSound.soundContext.createBufferSource();
					source.connect(globalWebPluginSound.soundContext.destination);
					sourceStart(source, globalWebPluginSound.soundContext.currentTime);
				}
			};

			globalWebPluginSound.soundTrigger = true;
			globalWebPluginSound.soundContext = soundContext;
		}
	},

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

	// BGM読込
	platformPluginSoundBgmLoad: function(bgmId, src){
		if(globalWebPluginSound.soundContext == null){return;}
		if(bgmId <= 0){return;}
		if(globalWebPluginSound.bgmList[bgmId] != null){return;}
		globalWebPluginSound.soundLoaderBgm(Pointer_stringify(src), bgmId);
	},

	// BGM再生
	platformPluginSoundBgmPlay: function(bgmId){
		if(globalWebPluginSound.soundContext == null){return;}
		globalWebPluginSound.bgmZeroId = bgmId;
		var oldVolume = globalWebPluginSound.bgmVolumeGain.gain.value;
		if(oldVolume > 0){globalWebPluginSound.bgmPlay(bgmId);}
	},

	// BGMトーンダウン
	platformPluginSoundBgmToneDown: function(volume){
		if(globalWebPluginSound.soundContext == null){return;}
		globalWebPluginSound.bgmToneDown = volume;
	},

	// BGM設定音量
	platformPluginSoundBgmVolume: function(volume){
		if(globalWebPluginSound.soundContext == null){return;}

		// 音量をゼロにした瞬間とゼロから戻した瞬間
		var oldVolume = globalWebPluginSound.bgmVolumeGain.gain.value;
		if(oldVolume > 0 && volume <= 0){globalWebPluginSound.bgmPlay(0);}
		if(oldVolume <= 0 && volume > 0){globalWebPluginSound.bgmPlay(globalWebPluginSound.bgmZeroId);}

		globalWebPluginSound.bgmVolumeGain.gain.setValueAtTime(volume, globalWebPluginSound.soundContext.currentTime);
	},

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

	// SE読込
	platformPluginSoundSeLoad: function(seId, src){
		if(globalWebPluginSound.soundContext == null){return;}
		if(seId <= 0){return;}
		if(globalWebPluginSound.seList[seId] != null){return;}
		globalWebPluginSound.soundLoaderSe(Pointer_stringify(src), seId);
	},

	// SE再生
	platformPluginSoundSePlay: function(seId){
		if(globalWebPluginSound.soundContext == null){return;}
		globalWebPluginSound.sePlay(seId);
	},

	// SE設定音量
	platformPluginSoundSeVolume: function(volume){
		if(globalWebPluginSound.soundContext == null){return;}
		globalWebPluginSound.seVolumeGain.gain.setValueAtTime(volume, globalWebPluginSound.soundContext.currentTime);
	},

	// ----------------------------------------------------------------
});

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

<|endoftext|>


<commit_before>var LifeDB = (function() {
	// private properties
	var databaseName, // Holds the name of the database
		insertIntoDataBase, // The first core method to be hitted in time of inserting data to database
		showErrorMessage, // This method display error in console
		errorMessages, // This variables holds all kind of error messagesl
		checkAndSetGlobalStorage, // This method will check wheather sessionStorage is availeble for storing data
		isSessionStorageAvaileble, // If set then session storage is availeble for storing data
		isNodeEnvironment, // If set then the environment is node js
		checkIfNodeEnvironment, // This method set the isNodeEnvironment flag
		globalDataStorage, // This variable will be used as data storage
		backUpData, // Backup the data in sessionStorage or in file
		checkAndRestoreData, // This method checks if there is any backup exists and restore the data to database
		checkIfPageExists, // This method checks if the page exists or not
		filterRecords, // This method filtered the records based on query object provided
		getPageData, // This method returns the total page data
		checkAndFilterWithEqual, // This method filter the recordset with equality checking of key value pare
		applyAndSeparatedQueryOnRecords, // This method apply And separated queries on recordset
		checkDataWithQuery, // This method apply a single query on a single record
		operatorList,// Holds the list of operators used in life-db
		checkEquality, // check equality of attribute and value
		checkGreterThan, //
		checkLessThan;

	// public properties
	this.initiate;
	this.insert;
	this.update;
	this.find;
	this.remove;

	/**
	* @description Defining all the error messages with type of the error
	*/
	errorMessages = {
		"dbNameNotSpecified": "Database name mast have to provide in time of initiating the database",
		"pageNameCannotBeEmpty": "Page name required",
		"pageDoesnotExists": "Provided page doesn't exists"
	};

	/**
	* @description Defining all the error messages with type of the error
	*/
	operatorList = [
		"@eq",
		"@lt",
		"@gt"
	];

	/**
	* @description Check the equality of values of attribute from record and attribute provided
	* @param data {Object} - A single record
	* @param attributeName {String} - Attribute name from query
	* @param attributeValue {String} - Attribute value from query
	* @returns {Boolean} if the value matches return true false instead
	*/
	checkEquality = (function(data, attributeName, attributeValue) {

	});

	/**
	* @description This method returns the total page data
	* @param pageName {String} - The name of the page where the query will hit
	* @return {Array} - Array of matched records
	*/
	getPageData = (function(pageName) {
		return globalDataStorage[pageName];
	});

	/**
	* @description This method apply a query on a single record
	* @param data {Object} - A single record
	* @param query {String} - A single query
	* @return {Boolean} True if query matches the record false instead
	*/
	checkDataWithQuery = (function(data, query) {
		var operator,
			operatorIndex,
			splittedQuery;
		for(operatorIndex in operatorList) {
			if(query.indexOf(operatorList[operatorIndex]) !== -1) {
				operator = operatorList[operatorIndex];
				break;
			}
		}
		splittedQuery = query.split(operator);
		// splittedQuery[0] attribute name
		// splittedQuery[1] value
		switch(operator) {
			case "@eq":
				return checkEquality(data, splittedQuery[0], splittedQuery[1]);
			break;
			case "@gt":
				return checkGreterThan(data, splittedQuery[0], splittedQuery[1]);
			break;
			case "@lt":
				return checkLessThan(data, splittedQuery[0], splittedQuery[1]);
			break;
		}
	});

	/**
	* @description This method apply And separated queries on recordset
	* @param dataArray {Array} - The recordset
	* @param andSeparatedQuery {String} - AND separated query
	* @return {Array} Recordset
	*/
	applyAndSeparatedQueryOnRecords = (function(dataArray, andSeparatedQuery) {
		var queryArray,
			queryIndex,
			dataIndex,
			newDataArray;
		queryArray = andSeparatedQuery.split("||");
		newDataArray = [];
		for(dataIndex in dataArray) {
			for(queryIndex in queryArray) {
				if(checkDataWithQuery(dataArray[dataIndex], queryArray[queryIndex])) {
					newDataArray.push(dataArray[dataIndex]);
					break;
				}
			}
		}
		return newDataArray;
	});

	/**
	* @description This method filtered the records based on query object provided
	* @param pageName {String} - The name of the page where the query will hit
	* @param queryString {String} - The query string, Optional, if not provided all of the page data will be returned
	* @param limit {Array} - Array of 2 numbers first the lower limit 2nd the upper limit, Optional
	* @param sort {Array} - Array of 2 strings first the attribute name 2nd the direction of sort, Optional
	* @return {Array} - Array of matched records
	*/
	filterRecords = (function(pageName, queryString, limit, sort) {
		var dataArray,
			andSeparatedQueries,
			indexOfAndSeparatedQueries;
		dataArray = getPageData(pageName);
		if(typeof queryObject !== "undefined" && queryObject.trim !== "") {
			andSeparatedQueries = queryString.split("&&");
			for(indexOfAndSeparatedQueries in andSeparatedQueries) {
				dataArray = applyAndSeparatedQueryOnRecords(dataArray, andSeparatedQueries[indexOfAndSeparatedQueries]);
			}
		}
		return dataArray;
	});

	/**
	* @description This method checks if the page exists or not
	* @param pageName {String} - The name of the page
	* @returns {Boolean} - Return true if page exists, false instead
	*/
	checkIfPageExists = (function(pageName) {
		if(typeof globalDataStorage[pageName] === "undefined") {
			return false;
		} else {
			return true;
		}
	});

	/**
	* @description This function checks if backup exists or not, if exists then restores the data
	*/
	checkAndRestoreData = (function() {
		var fs;
		if(!isNodeEnvironment && isSessionStorageAvaileble) {
			if(typeof sessionStorage[databaseName] === "undefined") {
				// empty sessionStorage so Restore process ignored
			} else {
				if(sessionStorage[databaseName].trim() !== "") {
					globalDataStorage = JSON.parse(sessionStorage[databaseName]);
				} else {
					// empty sessionStorage so Restore process ignored
				}
			}
		} else if(isNodeEnvironment) {
			fs = require('fs');
			if(fs.statSync(databaseName).isFile()) {
				globalDataStorage = JSON.parse(fs.readFileSync(databaseName));
			} else {
				// file not exists so Restore process ignored
			}
		} else {
			// sessionStorage not exists and not a node environment so Restore process ignored
		}
	});

	/**
	* @description This public method is called to insert single or multiple data to a perticuler page
	* @param pageName {String} - The name of the page where the record or records will go
	* @param record {Object/Array} - The data which are going to be inserted in the page
	* @return {Number} - The number of rows effected
	*/
	insertIntoDataBase = (function(pageName, record) {
		var recordIndex;
		try {
			if(typeof globalDataStorage === "undefined") {
				globalDataStorage = {};
			}
			if(typeof globalDataStorage[pageName] === "undefined") {
				globalDataStorage[pageName] = [];
			}
			if(Array.isArray(record)) {
				for(recordIndex in record) {
					globalDataStorage[pageName].push(record[recordIndex]);
				}
				return recordIndex;
			} else {
				globalDataStorage[pageName].push(record);
				return 1;
			}
		} catch(exception) {
			return 0;
		}
	});

	/**
	* @description This function backup the database to sessionStorage if the environment is browser or backup the database in file
	* if the environment is Node
	*
	*/
	backUpData = (function() {
		var fs;
		if(!isNodeEnvironment && isSessionStorageAvaileble) {
			sessionStorage[databaseName] = JSON.stringify(globalDataStorage);
		} else if(isNodeEnvironment) {
			fs = require('fs');
			fs.writeFileSync(databaseName, JSON.stringify(globalDataStorage));
		} else {
			// ignore backup
		}
	});

	/**
	* @description The function responsible for displaying all kind of errors
	* @param {string} errorType - The type of the error
	*/
	showErrorMessage = (function(errorType) {
		console.error(errorMessages[errorType]);
	});

	/**
	* @description This function checks wheather the environment is Node environment or not
	*/
	checkIfNodeEnvironment = (function() {
		if(this===window) {
			isNodeEnvironment = false;
		} else {
			isNodeEnvironment = true;
		}
	});

	/**
	* @description This method checks if the sessionStorage is availeble to be used as data storage or not.
	* If availeble then this method set the flag "isSessionStorageAvaileble" as "true" else "false"
	*/
	checkAndSetGlobalStorage = (function() {
		if(typeof sessionStorage !== "undefined") {
			isSessionStorageAvaileble = true;
			sessionStorage[databaseName] = "";
		} else {
			isSessionStorageAvaileble = false;
		}
	});

	/**
	* @description This function instantiated the database.
	* @param {string} databaseName - The name of the database
	*/
	this.initiate = (function() {
		if(typeof arguments[0][0] == "undefined") {
			showErrorMessage("dbNameNotSpecified");
			return false;
		} else {
			databaseName = arguments[0][0];
		}
		checkAndSetGlobalStorage();
		checkIfNodeEnvironment();
		checkAndRestoreData();
	})(arguments);

	/**
	* @description This public method is called to insert single or multiple data to a perticuler page
	* @param pageName {String} - The name of the page where the record or records will go
	* @param record {Object/Array} - The data which are going to be inserted in the page
	* @param callBack {Function} - Optional, The callback function which will be called afterthe insert process is complete
	* @param backupDatabase {Boolean} - Optional, default true, If true then the program will try to backup the data in session storage or file
	*/
	this.insert = (function(pageName, record, callBack, backupDatabase) {
		var numberOfEffectedRows;
		numberOfEffectedRows = insertIntoDataBase(pageName, record);
		if(typeof backupDatabase === "undefined" || backupDatabase) {
			backUpData();
		}
		if(!numberOfEffectedRows) {
			callback(true, 0); // errorOccured, numberOfEffectedRows 0
		} else {
			callback(false, numberOfEffectedRows);
		}
	});

	/**
	* @param pageName {String} - The name of the page where the query will hit
	* @param queryString {String} - The query string, Optional, if not provided all of the page data will be returned
	* @param limit {Array} - Array of 2 numbers first the lower limit 2nd the upper limit, Optional
	* @param sort {Array} - Array of 2 strings first the attribute name 2nd the direction of sort, Optional
	* @return {Array} - Array of matched records
	* @description This public method is called to filtered the records of a page based on query
	*/
	this.find = (function(pageName, queryString, limit, sort) {
		if(pageName.trim() === "") {
			showErrorMessage("pageNameCannotBeEmpty");
			return false;
		} else {
			if(!checkIfPageExists(pageName)) {
				showErrorMessage("pageDoesnotExists");
				return false;
			} else {
				if(typeof limit == "undefined") {
					limit = [0,0];
				}
				if(typeof sort == "undefined") {
					sort = ["", ""];
				}
				return filterRecords(pageName, queryString, limit, sort);
			}
		}
	});
});<commit_msg>find done<commit_after>var LifeDB = (function() {
	// private properties
	var databaseName, // Holds the name of the database
		insertIntoDataBase, // The first core method to be hitted in time of inserting data to database
		showErrorMessage, // This method display error in console
		errorMessages, // This variables holds all kind of error messagesl
		checkAndSetGlobalStorage, // This method will check wheather sessionStorage is availeble for storing data
		isSessionStorageAvaileble, // If set then session storage is availeble for storing data
		isNodeEnvironment, // If set then the environment is node js
		checkIfNodeEnvironment, // This method set the isNodeEnvironment flag
		globalDataStorage, // This variable will be used as data storage
		backUpData, // Backup the data in sessionStorage or in file
		checkAndRestoreData, // This method checks if there is any backup exists and restore the data to database
		checkIfPageExists, // This method checks if the page exists or not
		filterRecords, // This method filtered the records based on query object provided
		getPageData, // This method returns the total page data
		checkAndFilterWithEqual, // This method filter the recordset with equality checking of key value pare
		applyAndSeparatedQueryOnRecords, // This method apply And separated queries on recordset
		checkDataWithQuery, // This method apply a single query on a single record
		operatorList,// Holds the list of operators used in life-db
		checkEquality, // check equality of attribute and value
		checkGreterThan, //
		checkLessThan,
		checkGreterThanEqual,
		checkLessThanEqual;

	// public properties
	this.initiate;
	this.insert;
	this.update;
	this.find;
	this.remove;

	/**
	* @description Defining all the error messages with type of the error
	*/
	errorMessages = {
		"dbNameNotSpecified": "Database name mast have to provide in time of initiating the database",
		"pageNameCannotBeEmpty": "Page name required",
		"pageDoesnotExists": "Provided page doesn't exists"
	};

	/**
	* @description Defining all the error messages with type of the error
	*/
	operatorList = [
		"@eq",
		"@lt",
		"@gt",
		"@le",
		"@ge"
	];

	/**
	* @description Check the equality of values of attribute from record and attribute provided
	* @param data {Object} - A single record
	* @param attributeName {String} - Attribute name from query
	* @param attributeValue {String} - Attribute value from query
	* @returns {Boolean} if the value matches return true, false instead
	*/
	checkEquality = (function(data, attributeName, attributeValue) {
		if(typeof data[attributeName] === "undefined") { // attribute doesn't exists so return false
			return false;
		} else {
			if(data[attributeName] === attributeValue) {
				return true;
			} else {
				return false;
			}
		}
	});

	/**
	* @description Check the attribute value is greater than the value provided
	* @param data {Object} - A single record
	* @param attributeName {String} - Attribute name from query
	* @param attributeValue {String} - Attribute value from query
	* @returns {Boolean} if the value greter return true, false instead
	*/
	checkGreterThan = (function(data, attributeName, attributeValue) {
		if(typeof data[attributeName] === "undefined") { // attribute doesn't exists so return false
			return false;
		} else {
			if(isNaN(data[attributeName])) { // Value from data is not a number so return false
				return false;
			} else {
				if(data[attributeName] > attributeValue) {
					return true;
				} else {
					return false;
				}
			}

		}
	});

	/**
	* @description Check the attribute value is greater or equal than the value provided
	* @param data {Object} - A single record
	* @param attributeName {String} - Attribute name from query
	* @param attributeValue {String} - Attribute value from query
	* @returns {Boolean} if the value greter or equal return true, false instead
	*/
	checkGreterThanEqual = (function(data, attributeName, attributeValue) {
		if(typeof data[attributeName] === "undefined") { // attribute doesn't exists so return false
			return false;
		} else {
			if(isNaN(data[attributeName])) { // Value from data is not a number so return false
				return false;
			} else {
				if(data[attributeName] >= attributeValue) {
					return true;
				} else {
					return false;
				}
			}

		}
	});

	/**
	* @description Check the attribute value is less than the value provided
	* @param data {Object} - A single record
	* @param attributeName {String} - Attribute name from query
	* @param attributeValue {String} - Attribute value from query
	* @returns {Boolean} if the value less return true, false instead
	*/
	checkLessThan = (function(data, attributeName, attributeValue) {
		if(typeof data[attributeName] === "undefined") { // attribute doesn't exists so return false
			return false;
		} else {
			if(isNaN(data[attributeName])) { // Value from data is not a number so return false
				return false;
			} else {
				if(data[attributeName] < attributeValue) {
					return true;
				} else {
					return false;
				}
			}

		}
	});

	/**
	* @description Check the attribute value is less or equal than the value provided
	* @param data {Object} - A single record
	* @param attributeName {String} - Attribute name from query
	* @param attributeValue {String} - Attribute value from query
	* @returns {Boolean} if the value less or equal return true, false instead
	*/
	checkLessThanEqual = (function(data, attributeName, attributeValue) {
		if(typeof data[attributeName] === "undefined") { // attribute doesn't exists so return false
			return false;
		} else {
			if(isNaN(data[attributeName])) { // Value from data is not a number so return false
				return false;
			} else {
				if(data[attributeName] <= attributeValue) {
					return true;
				} else {
					return false;
				}
			}

		}
	});

	/**
	* @description This method returns the total page data
	* @param pageName {String} - The name of the page where the query will hit
	* @return {Array} - Array of matched records
	*/
	getPageData = (function(pageName) {
		return globalDataStorage[pageName];
	});

	/**
	* @description This method apply a query on a single record
	* @param data {Object} - A single record
	* @param query {String} - A single query
	* @return {Boolean} True if query matches the record false instead
	*/
	checkDataWithQuery = (function(data, query) {
		var operator,
			operatorIndex,
			splittedQuery;
		for(operatorIndex in operatorList) {
			if(query.indexOf(operatorList[operatorIndex]) !== -1) {
				operator = operatorList[operatorIndex];
				break;
			}
		}
		splittedQuery = query.split(" "+operator+" ");
		// splittedQuery[0] attribute name
		// splittedQuery[1] value
		switch(operator) {
			case "@eq":
				return checkEquality(data, splittedQuery[0], splittedQuery[1]);
			break;
			case "@gt":
				return checkGreterThan(data, splittedQuery[0], splittedQuery[1]);
			break;
			case "@lt":
				return checkLessThan(data, splittedQuery[0], splittedQuery[1]);
			break;
			case "@ge":
				return checkGreterThanEqual(data, splittedQuery[0], splittedQuery[1]);
			break;
			case "@le":
				return checkLessThanEqual(data, splittedQuery[0], splittedQuery[1]);
			break;
		}
	});

	/**
	* @description This method apply And separated queries on recordset
	* @param dataArray {Array} - The recordset
	* @param andSeparatedQuery {String} - AND separated query
	* @return {Array} Recordset
	*/
	applyAndSeparatedQueryOnRecords = (function(dataArray, andSeparatedQuery) {
		var queryArray,
			queryIndex,
			dataIndex,
			newDataArray;
		queryArray = andSeparatedQuery.split("||");
		newDataArray = [];
		for(dataIndex in dataArray) {
			for(queryIndex in queryArray) {
				if(checkDataWithQuery(dataArray[dataIndex], queryArray[queryIndex])) {
					newDataArray.push(dataArray[dataIndex]);
					break;
				}
			}
		}
		return newDataArray;
	});

	/**
	* @description This method filtered the records based on query object provided
	* @param pageName {String} - The name of the page where the query will hit
	* @param queryString {String} - The query string, Optional, if not provided all of the page data will be returned
	* @param limit {Array} - Array of 2 numbers first the lower limit 2nd the upper limit, Optional
	* @param sort {Array} - Array of 2 strings first the attribute name 2nd the direction of sort, Optional
	* @return {Array} - Array of matched records
	*/
	filterRecords = (function(pageName, queryString, limit, sort) {
		var dataArray,
			andSeparatedQueries,
			indexOfAndSeparatedQueries;
		dataArray = getPageData(pageName);
		if(typeof queryObject !== "undefined" && queryObject.trim !== "") {
			andSeparatedQueries = queryString.split("&&");
			for(indexOfAndSeparatedQueries in andSeparatedQueries) {
				dataArray = applyAndSeparatedQueryOnRecords(dataArray, andSeparatedQueries[indexOfAndSeparatedQueries]);
			}
		}
		return dataArray;
	});

	/**
	* @description This method checks if the page exists or not
	* @param pageName {String} - The name of the page
	* @returns {Boolean} - Return true if page exists, false instead
	*/
	checkIfPageExists = (function(pageName) {
		if(typeof globalDataStorage[pageName] === "undefined") {
			return false;
		} else {
			return true;
		}
	});

	/**
	* @description This function checks if backup exists or not, if exists then restores the data
	*/
	checkAndRestoreData = (function() {
		var fs;
		if(!isNodeEnvironment && isSessionStorageAvaileble) {
			if(typeof sessionStorage[databaseName] === "undefined") {
				// empty sessionStorage so Restore process ignored
			} else {
				if(sessionStorage[databaseName].trim() !== "") {
					globalDataStorage = JSON.parse(sessionStorage[databaseName]);
				} else {
					// empty sessionStorage so Restore process ignored
				}
			}
		} else if(isNodeEnvironment) {
			fs = require('fs');
			if(fs.statSync(databaseName).isFile()) {
				globalDataStorage = JSON.parse(fs.readFileSync(databaseName));
			} else {
				// file not exists so Restore process ignored
			}
		} else {
			// sessionStorage not exists and not a node environment so Restore process ignored
		}
	});

	/**
	* @description This public method is called to insert single or multiple data to a perticuler page
	* @param pageName {String} - The name of the page where the record or records will go
	* @param record {Object/Array} - The data which are going to be inserted in the page
	* @return {Number} - The number of rows effected
	*/
	insertIntoDataBase = (function(pageName, record) {
		var recordIndex;
		try {
			if(typeof globalDataStorage === "undefined") {
				globalDataStorage = {};
			}
			if(typeof globalDataStorage[pageName] === "undefined") {
				globalDataStorage[pageName] = [];
			}
			if(Array.isArray(record)) {
				for(recordIndex in record) {
					globalDataStorage[pageName].push(record[recordIndex]);
				}
				return recordIndex;
			} else {
				globalDataStorage[pageName].push(record);
				return 1;
			}
		} catch(exception) {
			return 0;
		}
	});

	/**
	* @description This function backup the database to sessionStorage if the environment is browser or backup the database in file
	* if the environment is Node
	*
	*/
	backUpData = (function() {
		var fs;
		if(!isNodeEnvironment && isSessionStorageAvaileble) {
			sessionStorage[databaseName] = JSON.stringify(globalDataStorage);
		} else if(isNodeEnvironment) {
			fs = require('fs');
			fs.writeFileSync(databaseName, JSON.stringify(globalDataStorage));
		} else {
			// ignore backup
		}
	});

	/**
	* @description The function responsible for displaying all kind of errors
	* @param {string} errorType - The type of the error
	*/
	showErrorMessage = (function(errorType) {
		console.error(errorMessages[errorType]);
	});

	/**
	* @description This function checks wheather the environment is Node environment or not
	*/
	checkIfNodeEnvironment = (function() {
		if(this===window) {
			isNodeEnvironment = false;
		} else {
			isNodeEnvironment = true;
		}
	});

	/**
	* @description This method checks if the sessionStorage is availeble to be used as data storage or not.
	* If availeble then this method set the flag "isSessionStorageAvaileble" as "true" else "false"
	*/
	checkAndSetGlobalStorage = (function() {
		if(typeof sessionStorage !== "undefined") {
			isSessionStorageAvaileble = true;
			sessionStorage[databaseName] = "";
		} else {
			isSessionStorageAvaileble = false;
		}
	});

	/**
	* @description This function instantiated the database.
	* @param {string} databaseName - The name of the database
	*/
	this.initiate = (function() {
		if(typeof arguments[0][0] == "undefined") {
			showErrorMessage("dbNameNotSpecified");
			return false;
		} else {
			databaseName = arguments[0][0];
		}
		checkAndSetGlobalStorage();
		checkIfNodeEnvironment();
		checkAndRestoreData();
	})(arguments);

	/**
	* @description This public method is called to insert single or multiple data to a perticuler page
	* @param pageName {String} - The name of the page where the record or records will go
	* @param record {Object/Array} - The data which are going to be inserted in the page
	* @param callBack {Function} - Optional, The callback function which will be called afterthe insert process is complete
	* @param backupDatabase {Boolean} - Optional, default true, If true then the program will try to backup the data in session storage or file
	*/
	this.insert = (function(pageName, record, callBack, backupDatabase) {
		var numberOfEffectedRows;
		numberOfEffectedRows = insertIntoDataBase(pageName, record);
		if(typeof backupDatabase === "undefined" || backupDatabase) {
			backUpData();
		}
		if(!numberOfEffectedRows) {
			callback(true, 0); // errorOccured, numberOfEffectedRows 0
		} else {
			callback(false, numberOfEffectedRows);
		}
	});

	/**
	* @param pageName {String} - The name of the page where the query will hit
	* @param queryString {String} - The query string, Optional, if not provided all of the page data will be returned
	* @param limit {Array} - Array of 2 numbers first the lower limit 2nd the upper limit, Optional
	* @param sort {Array} - Array of 2 strings first the attribute name 2nd the direction of sort, Optional
	* @return {Array} - Array of matched records
	* @description This public method is called to filtered the records of a page based on query
	*/
	this.find = (function(pageName, queryString, limit, sort) {
		if(pageName.trim() === "") {
			showErrorMessage("pageNameCannotBeEmpty");
			return false;
		} else {
			if(!checkIfPageExists(pageName)) {
				showErrorMessage("pageDoesnotExists");
				return false;
			} else {
				if(typeof limit == "undefined") {
					limit = [0,0];
				}
				if(typeof sort == "undefined") {
					sort = ["", ""];
				}
				return filterRecords(pageName, queryString, limit, sort);
			}
		}
	});
});<|endoftext|>


<commit_before>'use strict';
import React from 'react';
import ReactDOM from 'react-dom';
import { Router, Route, IndexRoute, hashHistory, browserHistory } from 'react-router'

import '../public/styles/master.scss';

// Route-specific views:
import Home from './components/Home';
import About from './components/About';
import Focus from './components/Focus';
import Contact from './components/Contact';
import Error404 from './components/Error404';

// Route-invariant site layout views:
import NavBar from './components/NavBar';
import MainLayout from './components/MainLayout';

// Top-level React (pure functional) component:
const App = () => (
  <Router history={ hashHistory }>
    <Route path='/' component={ MainLayout }>
      <IndexRoute component={ Home } />
      <Route path='/about' component={ About } />
      <Route path='/focus' component={ Focus } />
      <Route path='/contact' component={ Contact } />
      <Route path='*' component={ Error404 } />
    </Route>
  </Router>
);

export default App;
<commit_msg>refactor: Delete unnecessary imports and import new Routes component<commit_after>'use strict';
import React from 'react';

import '../public/styles/master.scss';
import Routes from './Router';

// Top-level React (pure functional) component:
const App = () => ( <Routes /> );

export default App;
<|endoftext|>


<commit_before>angular.module('olivegardenApp', ['ngCookies', 'ui-router', 'ui.codemirror'])
  .config(function($routeProvider) {
    $routeProvider
    .when('/', {
      controller: 'ChallengeController',
      templateUrl: '../app/views/dashboard.html'
    });
});<commit_msg>Added public states<commit_after>angular.module('olivegardenApp', ['ngCookies', 'ui-router', 'ui.codemirror'])
  .config(['$stateProvider', '$urlRouterProvider', '$locationProvider', '$httpProvider', function($stateProvider, $urlRouterProvider, $locationProvider, $httpProvider) {

    $stateProvider
        .state('public', {
            abstract: true,
            template: "<ui-view/>",
            data: {
                access: access.public
            }
        })
        .state('public.404', {
            url: '/404/',
            templateUrl: '404'
        });
}]);<|endoftext|>


<commit_before>/**
 * app.js
 *
 * This is the entry file for the application, only setup and boilerplate
 * code.
 */

// Needed for redux-saga es6 generator support
import 'babel-polyfill';

// Import all the third party stuff
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import { applyRouterMiddleware, Router, browserHistory } from 'react-router';
import { syncHistoryWithStore } from 'react-router-redux';
import { useScroll } from 'react-router-scroll';
import request from 'utils/request';
import shareConfig from 'utils/shareConfig';
import 'sanitize.css/sanitize.css';
// import photo swipe css
import '!!style-loader!css-loader!photoswipe/dist/photoswipe.css';
import '!!style-loader!css-loader!photoswipe/dist/default-skin/default-skin.css';

// Import root app
import App from 'containers/App';

// Import selector for `syncHistoryWithStore`
import { makeSelectLocationState } from 'containers/App/selectors';

// Import Language Provider
import LanguageProvider from 'containers/LanguageProvider';

// Import Swiper css
import 'styles/swiper.scss';

// Import fast click
import FastClick from 'assets/lib/fastclick';

// Load the favicon, the manifest.json file and the .htaccess file
/* eslint-disable import/no-unresolved, import/extensions */
import '!file-loader?name=[name].[ext]!./favicon.ico';
import '!file-loader?name=[name].[ext]!./manifest.json';
import 'file-loader?name=[name].[ext]!./.htaccess';
/* eslint-enable import/no-unresolved, import/extensions */

import configureStore from './store';

// Import i18n messages
import { translationMessages } from './i18n';

// Import CSS reset and Global Styles
import './global-styles';

// Import root routes
import createRoutes from './routes';

// inject fast click
FastClick.attach(document.body);

// Create redux store with history
// this uses the singleton browserHistory provided by react-router
// Optionally, this could be changed to leverage a created history
// e.g. `const browserHistory = useRouterHistory(createBrowserHistory)();`
const initialState = {};
const store = configureStore(initialState, browserHistory);

// Sync history and store, as the react-router-redux reducer
// is under the non-default key ("routing"), selectLocationState
// must be provided for resolving how to retrieve the "route" in the state
const history = syncHistoryWithStore(browserHistory, store, {
  selectLocationState: makeSelectLocationState(),
});

// Set up the router, wrapping all Routes in the App component
const rootRoute = {
  component: App,
  childRoutes: createRoutes(store),
};

const render = (messages) => {
  ReactDOM.render(
    <Provider store={store}>
      <LanguageProvider messages={messages}>
        <Router
          history={history}
          routes={rootRoute}
          render={
            // Scroll to top when going to a new page, imitating default browser
            // behaviour
            applyRouterMiddleware(useScroll())
          }
        />
      </LanguageProvider>
    </Provider>,
    document.getElementById('app')
  );
};

// Hot reloadable translation json files
if (module.hot) {
  // modules.hot.accept does not accept dynamic dependencies,
  // have to be constants at compile-time
  module.hot.accept('./i18n', () => {
    render(translationMessages);
  });
}

// try to init app initial data from backend to store
export function initAppInfo() {
  request.doGet('initialize/check').then((res) => {
    store.dispatch({
      type: 'LOAD_APP_INITIAL',
      payload: {
        data: res.data,
      },
    });
  });

  // weixin share config
  shareConfig.wxConfig();
}

// export the global store to solve dispath things
export function getStore() {
  return store;
}

// Chunked polyfill for browsers without Intl support
if (!window.Intl) {
  (new Promise((resolve) => {
    resolve(import('intl'));
  }))
    .then(() => Promise.all([
      import('intl/locale-data/jsonp/en.js'),
    ]))
    .then(() => {
      render(translationMessages);
      initAppInfo();
    })
    .catch((err) => {
      throw err;
    });
} else {
  render(translationMessages);

  initAppInfo();
}

// Install ServiceWorker and AppCache in the end since
// it's not most important operation and if main code fails,
// we do not want it installed
if (process.env.NODE_ENV === 'production') {
  require('offline-plugin/runtime').install(); // eslint-disable-line global-require
}
<commit_msg>. remove double weixin config when first in app<commit_after>/**
 * app.js
 *
 * This is the entry file for the application, only setup and boilerplate
 * code.
 */

// Needed for redux-saga es6 generator support
import 'babel-polyfill';

// Import all the third party stuff
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import { applyRouterMiddleware, Router, browserHistory } from 'react-router';
import { syncHistoryWithStore } from 'react-router-redux';
import { useScroll } from 'react-router-scroll';
import request from 'utils/request';
import 'sanitize.css/sanitize.css';
// import photo swipe css
import '!!style-loader!css-loader!photoswipe/dist/photoswipe.css';
import '!!style-loader!css-loader!photoswipe/dist/default-skin/default-skin.css';

// Import root app
import App from 'containers/App';

// Import selector for `syncHistoryWithStore`
import { makeSelectLocationState } from 'containers/App/selectors';

// Import Language Provider
import LanguageProvider from 'containers/LanguageProvider';

// Import Swiper css
import 'styles/swiper.scss';

// Import fast click
import FastClick from 'assets/lib/fastclick';

// Load the favicon, the manifest.json file and the .htaccess file
/* eslint-disable import/no-unresolved, import/extensions */
import '!file-loader?name=[name].[ext]!./favicon.ico';
import '!file-loader?name=[name].[ext]!./manifest.json';
import 'file-loader?name=[name].[ext]!./.htaccess';
/* eslint-enable import/no-unresolved, import/extensions */

import configureStore from './store';

// Import i18n messages
import { translationMessages } from './i18n';

// Import CSS reset and Global Styles
import './global-styles';

// Import root routes
import createRoutes from './routes';

// inject fast click
FastClick.attach(document.body);

// Create redux store with history
// this uses the singleton browserHistory provided by react-router
// Optionally, this could be changed to leverage a created history
// e.g. `const browserHistory = useRouterHistory(createBrowserHistory)();`
const initialState = {};
const store = configureStore(initialState, browserHistory);

// Sync history and store, as the react-router-redux reducer
// is under the non-default key ("routing"), selectLocationState
// must be provided for resolving how to retrieve the "route" in the state
const history = syncHistoryWithStore(browserHistory, store, {
  selectLocationState: makeSelectLocationState(),
});

// Set up the router, wrapping all Routes in the App component
const rootRoute = {
  component: App,
  childRoutes: createRoutes(store),
};

const render = (messages) => {
  ReactDOM.render(
    <Provider store={store}>
      <LanguageProvider messages={messages}>
        <Router
          history={history}
          routes={rootRoute}
          render={
            // Scroll to top when going to a new page, imitating default browser
            // behaviour
            applyRouterMiddleware(useScroll())
          }
        />
      </LanguageProvider>
    </Provider>,
    document.getElementById('app')
  );
};

// Hot reloadable translation json files
if (module.hot) {
  // modules.hot.accept does not accept dynamic dependencies,
  // have to be constants at compile-time
  module.hot.accept('./i18n', () => {
    render(translationMessages);
  });
}

// try to init app initial data from backend to store
export function initAppInfo() {
  request.doGet('initialize/check').then((res) => {
    store.dispatch({
      type: 'LOAD_APP_INITIAL',
      payload: {
        data: res.data,
      },
    });
  });
}

// export the global store to solve dispath things
export function getStore() {
  return store;
}

// Chunked polyfill for browsers without Intl support
if (!window.Intl) {
  (new Promise((resolve) => {
    resolve(import('intl'));
  }))
    .then(() => Promise.all([
      import('intl/locale-data/jsonp/en.js'),
    ]))
    .then(() => {
      render(translationMessages);
      initAppInfo();
    })
    .catch((err) => {
      throw err;
    });
} else {
  render(translationMessages);

  initAppInfo();
}

// Install ServiceWorker and AppCache in the end since
// it's not most important operation and if main code fails,
// we do not want it installed
if (process.env.NODE_ENV === 'production') {
  require('offline-plugin/runtime').install(); // eslint-disable-line global-require
}
<|endoftext|>


<commit_before>import Resolver from 'resolver';

var App = Ember.Application.extend({
  LOG_ACTIVE_GENERATION: true,
  LOG_MODULE_RESOLVER: true,
  LOG_TRANSITIONS: true,
  LOG_TRANSITIONS_INTERNAL: true,
  LOG_VIEW_LOOKUPS: true,
  modulePrefix: 'appkit', // TODO: loaded via config
  Resolver: Resolver['default'],
  init: function () {
    window.ENV.firebase = new Firebase("https://" + window.ENV.dbName + ".firebaseio.com/" + window.ENV.dbBucket);

    // Open a connection to the local web socket, and set up send command
    var localSocket = new window.WebSocket('ws://localhost:6557');
    var connected = false;
    var storedCommands = [];

    window.ENV.sendGruntCommand = function(command) {
      if(connected) {
        localSocket.send(command);
      } else {
        storedCommands.push(command);
      }
    };

    localSocket.onopen = function() {
      connected = true;

      storedCommands.forEach(function(item) {
        window.ENV.sendGruntCommand(item);
      });
      storedCommands = [];
    };

    this._super.apply(this, arguments);
  }
});

// This helps ember-validations not blow up
// https://github.com/dockyard/ember-validations/issues/26#issuecomment-31877071
DS.Model.reopen({
  isValid: false
});

export default App;
<commit_msg>set up done callback for multi step commands<commit_after>import Resolver from 'resolver';

var App = Ember.Application.extend({
  LOG_ACTIVE_GENERATION: true,
  LOG_MODULE_RESOLVER: true,
  LOG_TRANSITIONS: true,
  LOG_TRANSITIONS_INTERNAL: true,
  LOG_VIEW_LOOKUPS: true,
  modulePrefix: 'appkit', // TODO: loaded via config
  Resolver: Resolver['default'],
  init: function () {
    window.ENV.firebase = new Firebase("https://" + window.ENV.dbName + ".firebaseio.com/" + window.ENV.dbBucket);

    // Open a connection to the local web socket, and set up send command
    var localSocket = new window.WebSocket('ws://localhost:6557');
    var connected = false;
    var storedCommands = [];
    var emptyCallback = function() { };
    var doneCallback = emptyCallback;

    window.ENV.sendGruntCommand = function(command, callback) {
      if(connected) {
        localSocket.send(command);
        if(callback) doneCallback = callback;
      } else {
        storedCommands.push(command);
      }
    };

    localSocket.onmessage = function(event) {
      if(event.data === 'done') {
        doneCallback();
        doneCallback = emptyCallback; //Reset so done doesn't get called twice
      }
    };

    localSocket.onopen = function() {
      connected = true;

      storedCommands.forEach(function(item) {
        window.ENV.sendGruntCommand(item);
      });
      storedCommands = [];
    };

    this._super.apply(this, arguments);
  }
});

// This helps ember-validations not blow up
// https://github.com/dockyard/ember-validations/issues/26#issuecomment-31877071
DS.Model.reopen({
  isValid: false
});

export default App;
<|endoftext|>


<commit_before>/**
 * Electron helper packages
 */
import os from 'os';
import { remote } from 'electron';
import jetpack from 'fs-jetpack';
import env from './env';

/**
 * Application logic for painting browser
 */
import appData from './lib/appData.js';
import language from './lib/language.js';
import screenManager from './lib/screenManager.js';
import Screensaver from './lib/screensaver.js';
import MainScreen from './lib/MainScreen.js';
import ViewerScreen from './lib/ViewerScreen.js';

/**
 * Vendor libraries for the painting viewer
 */
import { tween } from './vendor/gsap/src/minified/TweenMax.min';
import { Zoomer } from './vendor/Zoomer/jquery.fs.zoomer.min';

var app = remote.app;
var appDir = jetpack.cwd(app.getAppPath());

document.addEventListener('DOMContentLoaded', function() {

  //Load XML
  $.ajax({
    type: 'GET',
    url: './assets/static/data/config.xml',
    dataType: 'xml',
    success: function(xml) {

      appData.updateSettings(xml);
      initialize();

    },

    error: function(jqXHR, textStatus, errorThrown) {
    },

  });

  function initialize() {

    screenManager.init();
    screenManager.addScreen(new MainScreen($('#screen_main'))); // Add Main screen
    screenManager.addScreen(new ViewerScreen($('#screen_viewer'))); // Add Viewer screen
    screenManager.showScreen(screenManager.SCREEN_MAIN);

    language.setupToggle('#language_btn');
    language.setupTranslations($(appData.configXML).find('component').first());

    var ss = new Screensaver(
      appData.screensaverTimeout, './assets/dynamic/videos/screensaver.webm', function() {
      //On sleep
      language.setLanguage(Language.ENGLISH);
      screenManager.showscreen(screenManager.SCREEN_MAIN);
      }
    );

  }

  // document.getElementById('greet').innerHTML = greet();
  // document.getElementById('platform-info').innerHTML = os.platform();
  // document.getElementById('env-name').innerHTML = env.name;
});
<commit_msg>Indentation help<commit_after>/**
 * Electron helper packages
 */
import os from 'os';
import { remote } from 'electron';
import jetpack from 'fs-jetpack';
import env from './env';

/**
 * Application logic for painting browser
 */
import appData from './lib/appData.js';
import language from './lib/language.js';
import screenManager from './lib/screenManager.js';
import Screensaver from './lib/screensaver.js';
import MainScreen from './lib/MainScreen.js';
import ViewerScreen from './lib/ViewerScreen.js';

/**
 * Vendor libraries for the painting viewer
 */
import { tween } from './vendor/gsap/src/minified/TweenMax.min';
import { Zoomer } from './vendor/Zoomer/jquery.fs.zoomer.min';

var app = remote.app;
var appDir = jetpack.cwd(app.getAppPath());

document.addEventListener('DOMContentLoaded', function() {

  //Load XML
  $.ajax({
    type: 'GET',
    url: './assets/static/data/config.xml',
    dataType: 'xml',
    success: function(xml) {

      appData.updateSettings(xml);
      initialize();

    },

    error: function(jqXHR, textStatus, errorThrown) {
    },

  });

  function initialize() {

    screenManager.init();
    screenManager.addScreen(new MainScreen($('#screen_main'))); // Add Main screen
    screenManager.addScreen(new ViewerScreen($('#screen_viewer'))); // Add Viewer screen
    screenManager.showScreen(screenManager.SCREEN_MAIN);

    language.setupToggle('#language_btn');
    language.setupTranslations($(appData.configXML).find('component').first());

    var ss = new Screensaver(
      appData.screensaverTimeout, './assets/dynamic/videos/screensaver.webm', function() {
        //On sleep
        language.setLanguage(Language.ENGLISH);
        screenManager.showscreen(screenManager.SCREEN_MAIN);
      }
    );

  }

  // document.getElementById('greet').innerHTML = greet();
  // document.getElementById('platform-info').innerHTML = os.platform();
  // document.getElementById('env-name').innerHTML = env.name;
});
<|endoftext|>