<commit_before>(function (globals) {

    /**
     * Maintain local copies of frequently used functions and constants.
     */

    var OLD_WU = globals.wu,
    ARR_SLICE = Array.prototype.slice,
    UNDEF = undefined,
    NULL = null,

    /**
     * Define publicly exposed wu function.
     */

    wu = globals.wu = function wu(obj) {
        // TODO: switch/case on typeof(obj)
        return obj instanceof Function ?
            augmentFunction(obj) :
            wu.Iterator(obj);
    };

    wu.noConflict = function noConflict() {
        globals.wu = OLD_WU;
        return wu;
    };

    /**
     * General helpers.
     */

    var isInstance = function isInstance(obj, Type)  {
        return obj instanceof Type;
    },
    toArray = wu.toArray = function toArray(obj) {
        return isInstance(obj, wu.Iterator) ?
            obj.toArray() :
            ARR_SLICE.call(obj);
    },
    toObjProtoString = function toObjProtoString(obj) {
        return Object.prototype.toString.call(obj);
    },
    toIterator = function toIterator(obj) {
        return isInstance(obj, wu.Iterator) ?
            obj :
            new wu.Iterator(obj);
    },
    toBool = wu.toBool = function toBool(obj) {
        return !!obj;
    };

    /**
     * Equality testing.
     */

    var arrayEq = function arrayEq(a, b) {
        return a.length === 0 ?
            a.length === b.length :
            wu.eq(a[0], b[0]) && wu.eq(a.slice(1),
                                       b.slice(1));
    };

    var objectEq = function objectEq(a, b) {
        var prop, propertiesSeen = [];
        for (prop in a) {
            propertiesSeen.push(prop);
            if ( a.hasOwnProperty(prop) && !wu.eq(a[prop], b[prop]) )
                return false;
        }
        for (prop in b) {
            if ( b.hasOwnProperty(prop) &&
                 !wu.has(propertiesSeen, prop) &&
                 !wu.eq(a[prop], b[prop]) )
                return false;
        }
        return true;
    };

    var regExpEq = function regExpEq(a, b) {
        return a.source === b.source &&
            a.global === b.global &&
            a.ignoreCase === b.ignoreCase &&
            a.multiline === b.multiline;
    };

    var eq = wu.eq = function eq(a, b) {
        var typeOfA = toObjProtoString(a);
        if (typeOfA !== toObjProtoString(b)) {
            return false;
        }

        else {
            switch (typeOfA) {
                case "[object Array]":
                    return arrayEq(a, b);
                case "[object Object]":
                    return objectEq(a, b);
                case "[object RegExp]":
                    return regExpEq(a, b);
                case "[object Date]":
                    return a.valueOf() === b.valueOf();
                default:
                    return a === b;
            }
        }
    };

    /**
     * Iterators!
     */

    var StopIteration = wu.StopIteration = function StopIteration() {};
    StopIteration.prototype.toString = function toString() {
        return "[object StopIteration]";
    };

    var addNextMethod = function iterHelper(obj) {
        var pairs, prop, len, chr, items;

        if (isInstance(obj, Array)) {
            // Copy obj to items so that .shift() won't have side effects on
            // original.
            items = wu.toArray(obj);
            this.next = function next() {
                return items.length > 0 ?
                    items.shift() :
                    new wu.StopIteration;
            };
        }

        else if (isInstance(obj, Object) && (isInstance(obj, wu.Iterator) !== true)) {
            pairs = [];
            for (prop in obj)
                if (obj.hasOwnProperty(prop))
                    pairs.push([prop, obj[prop]]);

            addNextMethod.call(this, pairs);
        }

        else if (toObjProtoString(obj) === "[object String]") {
            len = obj.length;
            this.next = function next() {
                if (len > 0) {
                    chr = obj.charAt(0);
                    obj = obj.slice(1);
                    len--;
                    return chr;
                }
                else {
                    return new wu.StopIteration;
                }
            };
        }

        else if (toObjProtoString(obj) === "[object Number]") {
            this.next = function next() {
                return obj-- === 0 ?
                    new StopIteration :
                    obj;
            };
        }

        else if (isInstance(obj, wu.Iterator)) {
            if (typeof obj.next !== "function")
                throw new Error("Iterator without a next method!");
            else
                NULL;
        }

        else {
            throw new TypeError("Object is not iterable: " + obj);
        }
    };

    wu.Iterator = function Iterator(objOrFn) {
        if (isInstance(this, wu.Iterator) === false)
            return new wu.Iterator(objOrFn);

        // If the user passed in a function to use as the next method, use that
        // instead of duck typing our own.
        if (toObjProtoString(objOrFn) === "[object Function]") {
            this.next = objOrFn;
        }
        else {
            addNextMethod.call(this, objOrFn);
        }

        this.toArray = this.toArray || function toArray() {
            var item = this.next(),
                res = [];
            while ( !isInstance(item, wu.StopIteration) ) {
                res.push(item);
                item = this.next();
            }
            return res;
        };

        this.map = this.map || wu.curry(wu.map, this);

        // TODO: filter, reduce, has, zip, chain, etc...

        return UNDEF;
    };

    // Maintain prototype chain for Iterators.
    wu.Iterator.prototype = wu.prototype;

    /**
     * Iterating helper functions.
     */

    wu.all = function all(iterable, fn, context) {
        iterable = toIterator(iterable);
        fn = fn || wu.toBool;
        context = context || this;

        var item = iterable.next();

        while ( !isInstance(item, wu.StopIteration) ) {
            if ( !fn.call(context, item) )
                return false;
            item = iterable.next();
        }
        return true;
    };

    wu.any = function any(iterable, fn, context) {
        var oppositeFn = fn === UNDEF ?
            function oppositeFn(obj) { return !toBool(obj); } :
            function oppositeFn(obj) {
                return !fn.call(context, obj);
            };
        return !wu.all(iterable, oppositeFn);
    };

    // wu.chain

    wu.has = function has(iterable, item) {
        return wu.any(iterable, wu.curry(wu.eq, item));
    };

    wu.map = function map(iterable, fn, context) {
        iterable = toIterator(iterable);
        context = context || this;

        var results = [],
            item = iterable.next();

        return wu.Iterator(function next() {
            var result = isInstance(item, StopIteration) ?
                item :
                fn.call(context, item);
            item = iterable.next();
            return result;
        });
    };

    var rangeHelper = function rangeHelper(start, stop, incr) {
        // Handle first case since we are doing +=
        start = start - incr;

        return wu.Iterator(function next() {
            return start + incr >= stop ?
                new wu.StopIteration :
                start += incr;
        });
    };

    wu.range = function range() {
        switch (arguments.length) {
            case 1:
                return rangeHelper(0, arguments[0], 1);
            case 2:
                return rangeHelper(arguments[0], arguments[1], 1);
            case 3:
                return rangeHelper(arguments[0], arguments[1], arguments[2]);
            default:
                throw new TypeError("Wrong number of arguments passed to wu.range!");
        }
    };

    wu.zip = function zip(iterA, iterB) {
        iterA = toIterator(iterA);
        iterB = toIterator(iterB);
        return wu.Iterator(function next() {
            var a = iterA.next(),
                b = iterB.next(),
                aIsStop = isInstance(a, StopIteration),
                bIsStop = isInstance(b, StopIteration),
                res;
            if (aIsStop && bIsStop) {
                return new StopIteration;
            }
            else {
                res = new Array;
                res[0] = aIsStop ? NULL : a;
                res[1] = bIsStop ? NULL : b;
                return res;
            }
        });
    };

    /**
     * Functions that are also methods (in some form) for wu functions.
     */

    wu.bind = function bind(scope, fn /*, variadic number of arguments */) {
        var args = ARR_SLICE(arguments, 2);
        return function bound() {
            return fn.apply(scope, args.concat(arguments));
        };
    };

    wu.compose = function compose(/* variadic number of functions */) {
        var fns = wu.toArray(arguments);
        return function composed() {
            var returnValue = fns.pop().apply(this, arguments);
            while (fns.length) {
                returnValue = fns.pop()(returnValue);
            }
            return returnValue;
        };
    };

    wu.curry = function curry(fn /* variadic number of args */) {
        var args = ARR_SLICE.call(arguments, 1);
        return function curried() {
            return fn.apply(this, args.concat(wu.toArray(arguments)));
        };
    };

    /**
     * Augmentation of functions with wu methods.
     */

    function augmentFunction(fn) {
        fn.all = function all(iterable, context) {
            return wu.all(iterable, this, context);
        };

        fn.any = function any(iterable, context) {
            return wu.any(iterable, this, context);
        };

        fn.bind = function bind(scope) {
            return wu.bind.apply(
                scope,
                [this].concat(ARR_SLICE.call(arguments, 1))
            );
        };

        fn.compose = function compose() {
            return wu.compose.apply(this, [this].concat(arguments));
        };

        return fn;
    }

    wu.tang = { clan: 36 };

}(window || exports));<commit_msg>Refactoring addNextMethod to use switch/case instead of if/else<commit_after>(function (globals) {

    /**
     * Maintain local copies of frequently used functions and constants.
     */

    var OLD_WU = globals.wu,
    ARR_SLICE = Array.prototype.slice,
    UNDEF = undefined,
    NULL = null,

    /**
     * Define publicly exposed wu function.
     */

    wu = globals.wu = function wu(obj) {
        // TODO: switch/case on typeof(obj)
        return obj instanceof Function ?
            augmentFunction(obj) :
            wu.Iterator(obj);
    };

    wu.noConflict = function noConflict() {
        globals.wu = OLD_WU;
        return wu;
    };

    /**
     * General helpers.
     */

    var isInstance = function isInstance(obj, Type)  {
        return obj instanceof Type;
    },
    toObjProtoString = function toObjProtoString(obj) {
        return Object.prototype.toString.call(obj);
    },
    toIterator = function toIterator(obj) {
        return isInstance(obj, wu.Iterator) ?
            obj :
            new wu.Iterator(obj);
    },
    toArray = wu.toArray = function toArray(obj) {
        return isInstance(obj, wu.Iterator) ?
            obj.toArray() :
            ARR_SLICE.call(obj);
    },
    toBool = wu.toBool = function toBool(obj) {
        return !!obj;
    };

    /**
     * Equality testing.
     */

    var arrayEq = function arrayEq(a, b) {
        return a.length === 0 ?
            a.length === b.length :
            wu.eq(a[0], b[0]) && wu.eq(a.slice(1),
                                       b.slice(1));
    };

    var objectEq = function objectEq(a, b) {
        var prop, propertiesSeen = [];
        for (prop in a) {
            propertiesSeen.push(prop);
            if ( a.hasOwnProperty(prop) && !wu.eq(a[prop], b[prop]) )
                return false;
        }
        for (prop in b) {
            if ( b.hasOwnProperty(prop) &&
                 !wu.has(propertiesSeen, prop) &&
                 !wu.eq(a[prop], b[prop]) )
                return false;
        }
        return true;
    };

    var regExpEq = function regExpEq(a, b) {
        return a.source === b.source &&
            a.global === b.global &&
            a.ignoreCase === b.ignoreCase &&
            a.multiline === b.multiline;
    };

    var eq = wu.eq = function eq(a, b) {
        var typeOfA = toObjProtoString(a);
        if (typeOfA !== toObjProtoString(b)) {
            return false;
        }

        else {
            switch (typeOfA) {
                case "[object Array]":
                    return arrayEq(a, b);
                case "[object Object]":
                    return objectEq(a, b);
                case "[object RegExp]":
                    return regExpEq(a, b);
                case "[object Date]":
                    return a.valueOf() === b.valueOf();
                default:
                    return a === b;
            }
        }
    };

    /**
     * Iterators!
     */

    var StopIteration = wu.StopIteration = function StopIteration() {};
    StopIteration.prototype.toString = function toString() {
        return "[object StopIteration]";
    };

    var addNextMethod = function iterHelper(obj) {
        var pairs, prop, len, chr, items,
        attachNextForArrayLikeObjs = function attachNextForArrayLikeObjs(obj) {
            // Copy obj to items so that .shift() won't have side effects on
            // original.
            items = wu.toArray(obj);
            this.next = function next() {
                return items.length > 0 ?
                    items.shift() :
                    new wu.StopIteration;
            };
        };

        switch (toObjProtoString(obj)) {
            case "[object Array]":
                attachNextForArrayLikeObjs.call(this, obj);
                break;
            case "[object NodeList]":
                attachNextForArrayLikeObjs.call(this, obj);
                break;
            case "[object Object]":
                if (isInstance(obj, wu.Iterator)) {
                    if (typeof obj.next !== "function")
                        throw new Error("Iterator without a next method!");
                    else
                        NULL;
                }
                else if (obj.toString() === "[object Arguments]") {
                    attachNextForArrayLikeObjs.call(this, obj);
                }
                else {
                    pairs = [];
                    for (prop in obj)
                        if (obj.hasOwnProperty(prop))
                            pairs.push([prop, obj[prop]]);

                    addNextMethod.call(this, pairs);
                }
                break;
            case "[object String]":
                len = obj.length;
                this.next = function next() {
                    if (len > 0) {
                        chr = obj.charAt(0);
                        obj = obj.slice(1);
                        len--;
                        return chr;
                    }
                    else {
                        return new wu.StopIteration;
                    }
                };
                break;
            case "[object Number]":
                this.next = function next() {
                    return obj-- === 0 ?
                        new StopIteration :
                        obj;
                };
                break;
            default:
                throw new TypeError("Object is not iterable: " + obj);
        }
    };

    wu.Iterator = function Iterator(objOrFn) {
        if (isInstance(this, wu.Iterator) === false)
            return new wu.Iterator(objOrFn);

        // If the user passed in a function to use as the next method, use that
        // instead of duck typing our own.
        if (toObjProtoString(objOrFn) === "[object Function]") {
            this.next = objOrFn;
        }
        else {
            addNextMethod.call(this, objOrFn);
        }

        this.toArray = this.toArray || function toArray() {
            var item = this.next(),
                res = [];
            while ( !isInstance(item, wu.StopIteration) ) {
                res.push(item);
                item = this.next();
            }
            return res;
        };

        this.map = this.map || wu.curry(wu.map, this);

        // TODO: filter, reduce, has, zip, chain, etc...

        return UNDEF;
    };

    // Maintain prototype chain for Iterators.
    wu.Iterator.prototype = wu.prototype;

    /**
     * Iterating helper functions.
     */

    wu.all = function all(iterable, fn, context) {
        iterable = toIterator(iterable);
        fn = fn || wu.toBool;
        context = context || this;

        var item = iterable.next();

        while ( !isInstance(item, wu.StopIteration) ) {
            if ( !fn.call(context, item) )
                return false;
            item = iterable.next();
        }
        return true;
    };

    wu.any = function any(iterable, fn, context) {
        var oppositeFn = fn === UNDEF ?
            function oppositeFn(obj) { return !toBool(obj); } :
            function oppositeFn(obj) {
                return !fn.call(context, obj);
            };
        return !wu.all(iterable, oppositeFn);
    };

    // wu.chain

    wu.has = function has(iterable, item) {
        return wu.any(iterable, wu.curry(wu.eq, item));
    };

    wu.map = function map(iterable, fn, context) {
        iterable = toIterator(iterable);
        context = context || this;

        var results = [],
            item = iterable.next();

        return wu.Iterator(function next() {
            var result = isInstance(item, StopIteration) ?
                item :
                fn.call(context, item);
            item = iterable.next();
            return result;
        });
    };

    var rangeHelper = function rangeHelper(start, stop, incr) {
        // Handle first case since we are doing +=
        start = start - incr;

        return wu.Iterator(function next() {
            return start + incr >= stop ?
                new wu.StopIteration :
                start += incr;
        });
    };

    wu.range = function range() {
        switch (arguments.length) {
            case 1:
                return rangeHelper(0, arguments[0], 1);
            case 2:
                return rangeHelper(arguments[0], arguments[1], 1);
            case 3:
                return rangeHelper(arguments[0], arguments[1], arguments[2]);
            default:
                throw new TypeError("Wrong number of arguments passed to wu.range!");
        }
    };

    wu.zip = function zip(iterA, iterB) {
        iterA = toIterator(iterA);
        iterB = toIterator(iterB);
        return wu.Iterator(function next() {
            var a = iterA.next(),
                b = iterB.next(),
                aIsStop = isInstance(a, StopIteration),
                bIsStop = isInstance(b, StopIteration),
                res;
            if (aIsStop && bIsStop) {
                return new StopIteration;
            }
            else {
                res = new Array;
                res[0] = aIsStop ? NULL : a;
                res[1] = bIsStop ? NULL : b;
                return res;
            }
        });
    };

    /**
     * Functions that are also methods (in some form) for wu functions.
     */

    wu.bind = function bind(scope, fn /*, variadic number of arguments */) {
        var args = ARR_SLICE(arguments, 2);
        return function bound() {
            return fn.apply(scope, args.concat(arguments));
        };
    };

    wu.compose = function compose(/* variadic number of functions */) {
        var fns = wu.toArray(arguments);
        return function composed() {
            var returnValue = fns.pop().apply(this, arguments);
            while (fns.length) {
                returnValue = fns.pop()(returnValue);
            }
            return returnValue;
        };
    };

    wu.curry = function curry(fn /* variadic number of args */) {
        var args = ARR_SLICE.call(arguments, 1);
        return function curried() {
            return fn.apply(this, args.concat(wu.toArray(arguments)));
        };
    };

    /**
     * Augmentation of functions with wu methods.
     */

    function augmentFunction(fn) {
        fn.all = function all(iterable, context) {
            return wu.all(iterable, this, context);
        };

        fn.any = function any(iterable, context) {
            return wu.any(iterable, this, context);
        };

        fn.bind = function bind(scope) {
            return wu.bind.apply(
                scope,
                [this].concat(ARR_SLICE.call(arguments, 1))
            );
        };

        fn.compose = function compose() {
            return wu.compose.apply(this, [this].concat(arguments));
        };

        return fn;
    }

    wu.tang = { clan: 36 };

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


<commit_before>(function (globals) {

    /**
     * Maintain local copies of frequently used functions and constants.
     */

    var OLD_WU = globals.wu,
    ARR_SLICE = Array.prototype.slice,
    UNDEF = undefined,
    NULL = null,

    /**
     * Define publicly exposed wu function.
     */

    wu = globals.wu = function wu(obj) {
        // TODO: switch/case on typeof(obj)
        return obj instanceof Function ?
            augmentFunction(obj) :
            wu.Iterator(obj);
    };

    wu.noConflict = function noConflict() {
        globals.wu = OLD_WU;
        return wu;
    };

    /**
     * General helpers.
     */

    var isInstance = function isInstance(obj, Type)  {
        return obj instanceof Type;
    },
    toObjProtoString = function toObjProtoString(obj) {
        return Object.prototype.toString.call(obj);
    },
    toIterator = function toIterator(obj) {
        return isInstance(obj, wu.Iterator) ?
            obj :
            new wu.Iterator(obj);
    },
    toArray = wu.toArray = function toArray(obj) {
        return isInstance(obj, wu.Iterator) ?
            obj.toArray() :
            ARR_SLICE.call(obj);
    },
    toBool = wu.toBool = function toBool(obj) {
        return !!obj;
    };

    /**
     * Equality testing.
     */

    var arrayEq = function arrayEq(a, b) {
        return a.length === 0 ?
            a.length === b.length :
            wu.eq(a[0], b[0]) && wu.eq(a.slice(1),
                                       b.slice(1));
    };

    var objectEq = function objectEq(a, b) {
        var prop, propertiesSeen = [];
        for (prop in a) {
            propertiesSeen.push(prop);
            if ( a.hasOwnProperty(prop) && !wu.eq(a[prop], b[prop]) )
                return false;
        }
        for (prop in b) {
            if ( b.hasOwnProperty(prop) &&
                 !wu.has(propertiesSeen, prop) &&
                 !wu.eq(a[prop], b[prop]) )
                return false;
        }
        return true;
    };

    var regExpEq = function regExpEq(a, b) {
        return a.source === b.source &&
            a.global === b.global &&
            a.ignoreCase === b.ignoreCase &&
            a.multiline === b.multiline;
    };

    var eq = wu.eq = function eq(a, b) {
        var typeOfA = toObjProtoString(a);
        if (typeOfA !== toObjProtoString(b)) {
            return false;
        }

        else {
            switch (typeOfA) {
                case "[object Array]":
                    return arrayEq(a, b);
                case "[object Object]":
                    return objectEq(a, b);
                case "[object RegExp]":
                    return regExpEq(a, b);
                case "[object Date]":
                    return a.valueOf() === b.valueOf();
                default:
                    return a === b;
            }
        }
    };

    /**
     * Iterators!
     */

    var StopIteration = wu.StopIteration = function StopIteration() {};
    StopIteration.prototype.toString = function toString() {
        return "[object StopIteration]";
    };

    var addNextMethod = function iterHelper(obj) {
        var pairs, prop, len, chr, items,
        attachNextForArrayLikeObjs = function attachNextForArrayLikeObjs(obj) {
            // Copy obj to items so that .shift() won't have side effects on
            // original.
            items = wu.toArray(obj);
            this.next = function next() {
                return items.length > 0 ?
                    items.shift() :
                    new wu.StopIteration;
            };
        };

        switch (toObjProtoString(obj)) {
            case "[object Array]":
                attachNextForArrayLikeObjs.call(this, obj);
                break;
            case "[object NodeList]":
                attachNextForArrayLikeObjs.call(this, obj);
                break;
            case "[object Object]":
                if (isInstance(obj, wu.Iterator)) {
                    if (typeof obj.next !== "function")
                        throw new Error("Iterator without a next method!");
                    else
                        NULL;
                }
                else if (obj.toString() === "[object Arguments]") {
                    attachNextForArrayLikeObjs.call(this, obj);
                }
                else {
                    pairs = [];
                    for (prop in obj)
                        if (obj.hasOwnProperty(prop))
                            pairs.push([prop, obj[prop]]);

                    addNextMethod.call(this, pairs);
                }
                break;
            case "[object String]":
                len = obj.length;
                this.next = function next() {
                    if (len > 0) {
                        chr = obj.charAt(0);
                        obj = obj.slice(1);
                        len--;
                        return chr;
                    }
                    else {
                        return new wu.StopIteration;
                    }
                };
                break;
            case "[object Number]":
                this.next = function next() {
                    return obj-- === 0 ?
                        new StopIteration :
                        obj;
                };
                break;
            default:
                throw new TypeError("Object is not iterable: " + obj);
        }
    };

    wu.Iterator = function Iterator(objOrFn) {
        if (isInstance(this, wu.Iterator) === false)
            return new wu.Iterator(objOrFn);

        // If the user passed in a function to use as the next method, use that
        // instead of duck typing our own.
        if (toObjProtoString(objOrFn) === "[object Function]") {
            this.next = objOrFn;
        }
        else {
            addNextMethod.call(this, objOrFn);
        }

        this.toArray = this.toArray || function toArray() {
            var item = this.next(),
                res = [];
            while ( !isInstance(item, wu.StopIteration) ) {
                res.push(item);
                item = this.next();
            }
            return res;
        };

        this.map = this.map || wu.curry(wu.map, this);

        // TODO: filter, reduce, has, zip, chain, etc...

        return UNDEF;
    };

    // Maintain prototype chain for Iterators.
    wu.Iterator.prototype = wu.prototype;

    /**
     * Iterating helper functions.
     */

    wu.all = function all(iterable, fn, context) {
        iterable = toIterator(iterable);
        fn = fn || wu.toBool;
        context = context || this;

        var item = iterable.next();

        while ( !isInstance(item, wu.StopIteration) ) {
            if ( !fn.call(context, item) )
                return false;
            item = iterable.next();
        }
        return true;
    };

    wu.any = function any(iterable, fn, context) {
        var oppositeFn = fn === UNDEF ?
            function oppositeFn(obj) { return !toBool(obj); } :
            function oppositeFn(obj) {
                return !fn.call(context, obj);
            };
        return !wu.all(iterable, oppositeFn);
    };

    // wu.chain

    wu.has = function has(iterable, item) {
        return wu.any(iterable, wu.curry(wu.eq, item));
    };

    wu.map = function map(iterable, fn, context) {
        iterable = toIterator(iterable);
        context = context || this;

        var results = [],
            item = iterable.next();

        return wu.Iterator(function next() {
            var result = isInstance(item, StopIteration) ?
                item :
                fn.call(context, item);
            item = iterable.next();
            return result;
        });
    };

    var rangeHelper = function rangeHelper(start, stop, incr) {
        // Handle first case since we are doing +=
        start = start - incr;

        return wu.Iterator(function next() {
            return start + incr >= stop ?
                new wu.StopIteration :
                start += incr;
        });
    };

    wu.range = function range() {
        switch (arguments.length) {
            case 1:
                return rangeHelper(0, arguments[0], 1);
            case 2:
                return rangeHelper(arguments[0], arguments[1], 1);
            case 3:
                return rangeHelper(arguments[0], arguments[1], arguments[2]);
            default:
                throw new TypeError("Wrong number of arguments passed to wu.range!");
        }
    };

    wu.zip = function zip(iterA, iterB) {
        iterA = toIterator(iterA);
        iterB = toIterator(iterB);
        return wu.Iterator(function next() {
            var a = iterA.next(),
                b = iterB.next(),
                aIsStop = isInstance(a, StopIteration),
                bIsStop = isInstance(b, StopIteration),
                res;
            if (aIsStop && bIsStop) {
                return new StopIteration;
            }
            else {
                res = new Array;
                res[0] = aIsStop ? NULL : a;
                res[1] = bIsStop ? NULL : b;
                return res;
            }
        });
    };

    /**
     * Functions that are also methods (in some form) for wu functions.
     */

    wu.bind = function bind(scope, fn /*, variadic number of arguments */) {
        var args = ARR_SLICE.call(arguments, 2);
        return function bound() {
            return fn.apply(scope, args.concat(wu.toArray(arguments)));
        };
    };

    wu.compose = function compose(/* variadic number of functions */) {
        var fns = wu.toArray(arguments);
        return function composed() {
            var returnValue = fns.pop().apply(this, arguments);
            while (fns.length) {
                returnValue = fns.pop()(returnValue);
            }
            return returnValue;
        };
    };

    wu.curry = function curry(fn /* variadic number of args */) {
        var args = ARR_SLICE.call(arguments, 1);
        return function curried() {
            return fn.apply(this, args.concat(wu.toArray(arguments)));
        };
    };

    /**
     * Augmentation of functions with wu methods.
     */

    function augmentFunction(fn) {
        fn.all = function all(iterable, context) {
            return wu.all(iterable, this, context);
        };

        fn.any = function any(iterable, context) {
            return wu.any(iterable, this, context);
        };

        fn.bind = function bind(scope) {
            return wu.bind.apply(
                scope,
                [this].concat(ARR_SLICE.call(arguments, 1))
            );
        };

        fn.compose = function compose() {
            return wu.compose.apply(this, [this].concat(arguments));
        };

        return fn;
    }

    wu.tang = { clan: 36 };

}(window || exports));<commit_msg>Fixing bugs in wu(fn).compose and wu(fn).bind<commit_after>(function (globals) {

    /**
     * Maintain local copies of frequently used functions and constants.
     */

    var OLD_WU = globals.wu,
    ARR_SLICE = Array.prototype.slice,
    UNDEF = undefined,
    NULL = null,

    /**
     * Define publicly exposed wu function.
     */

    wu = globals.wu = function wu(obj) {
        // TODO: switch/case on typeof(obj)
        return obj instanceof Function ?
            augmentFunction(obj) :
            wu.Iterator(obj);
    };

    wu.noConflict = function noConflict() {
        globals.wu = OLD_WU;
        return wu;
    };

    /**
     * General helpers.
     */

    var isInstance = function isInstance(obj, Type)  {
        return obj instanceof Type;
    },
    toObjProtoString = function toObjProtoString(obj) {
        return Object.prototype.toString.call(obj);
    },
    toIterator = function toIterator(obj) {
        return isInstance(obj, wu.Iterator) ?
            obj :
            new wu.Iterator(obj);
    },
    toArray = wu.toArray = function toArray(obj) {
        return isInstance(obj, wu.Iterator) ?
            obj.toArray() :
            ARR_SLICE.call(obj);
    },
    toBool = wu.toBool = function toBool(obj) {
        return !!obj;
    };

    /**
     * Equality testing.
     */

    var arrayEq = function arrayEq(a, b) {
        return a.length === 0 ?
            a.length === b.length :
            wu.eq(a[0], b[0]) && wu.eq(a.slice(1),
                                       b.slice(1));
    };

    var objectEq = function objectEq(a, b) {
        var prop, propertiesSeen = [];
        for (prop in a) {
            propertiesSeen.push(prop);
            if ( a.hasOwnProperty(prop) && !wu.eq(a[prop], b[prop]) )
                return false;
        }
        for (prop in b) {
            if ( b.hasOwnProperty(prop) &&
                 !wu.has(propertiesSeen, prop) &&
                 !wu.eq(a[prop], b[prop]) )
                return false;
        }
        return true;
    };

    var regExpEq = function regExpEq(a, b) {
        return a.source === b.source &&
            a.global === b.global &&
            a.ignoreCase === b.ignoreCase &&
            a.multiline === b.multiline;
    };

    var eq = wu.eq = function eq(a, b) {
        var typeOfA = toObjProtoString(a);
        if (typeOfA !== toObjProtoString(b)) {
            return false;
        }

        else {
            switch (typeOfA) {
                case "[object Array]":
                    return arrayEq(a, b);
                case "[object Object]":
                    return objectEq(a, b);
                case "[object RegExp]":
                    return regExpEq(a, b);
                case "[object Date]":
                    return a.valueOf() === b.valueOf();
                default:
                    return a === b;
            }
        }
    };

    /**
     * Iterators!
     */

    var StopIteration = wu.StopIteration = function StopIteration() {};
    StopIteration.prototype.toString = function toString() {
        return "[object StopIteration]";
    };

    var addNextMethod = function iterHelper(obj) {
        var pairs, prop, len, chr, items,
        attachNextForArrayLikeObjs = function attachNextForArrayLikeObjs(obj) {
            // Copy obj to items so that .shift() won't have side effects on
            // original.
            items = wu.toArray(obj);
            this.next = function next() {
                return items.length > 0 ?
                    items.shift() :
                    new wu.StopIteration;
            };
        };

        switch (toObjProtoString(obj)) {
            case "[object Array]":
                attachNextForArrayLikeObjs.call(this, obj);
                break;
            case "[object NodeList]":
                attachNextForArrayLikeObjs.call(this, obj);
                break;
            case "[object Object]":
                if (isInstance(obj, wu.Iterator)) {
                    if (typeof obj.next !== "function")
                        throw new Error("Iterator without a next method!");
                    else
                        NULL;
                }
                else if (obj.toString() === "[object Arguments]") {
                    attachNextForArrayLikeObjs.call(this, obj);
                }
                else {
                    pairs = [];
                    for (prop in obj)
                        if (obj.hasOwnProperty(prop))
                            pairs.push([prop, obj[prop]]);

                    addNextMethod.call(this, pairs);
                }
                break;
            case "[object String]":
                len = obj.length;
                this.next = function next() {
                    if (len > 0) {
                        chr = obj.charAt(0);
                        obj = obj.slice(1);
                        len--;
                        return chr;
                    }
                    else {
                        return new wu.StopIteration;
                    }
                };
                break;
            case "[object Number]":
                this.next = function next() {
                    return obj-- === 0 ?
                        new StopIteration :
                        obj;
                };
                break;
            default:
                throw new TypeError("Object is not iterable: " + obj);
        }
    };

    wu.Iterator = function Iterator(objOrFn) {
        if (isInstance(this, wu.Iterator) === false)
            return new wu.Iterator(objOrFn);

        // If the user passed in a function to use as the next method, use that
        // instead of duck typing our own.
        if (toObjProtoString(objOrFn) === "[object Function]") {
            this.next = objOrFn;
        }
        else {
            addNextMethod.call(this, objOrFn);
        }

        this.toArray = this.toArray || function toArray() {
            var item = this.next(),
                res = [];
            while ( !isInstance(item, wu.StopIteration) ) {
                res.push(item);
                item = this.next();
            }
            return res;
        };

        this.map = this.map || wu.curry(wu.map, this);

        // TODO: filter, reduce, has, zip, chain, etc...

        return UNDEF;
    };

    // Maintain prototype chain for Iterators.
    wu.Iterator.prototype = wu.prototype;

    /**
     * Iterating helper functions.
     */

    wu.all = function all(iterable, fn, context) {
        iterable = toIterator(iterable);
        fn = fn || wu.toBool;
        context = context || this;

        var item = iterable.next();

        while ( !isInstance(item, wu.StopIteration) ) {
            if ( !fn.call(context, item) )
                return false;
            item = iterable.next();
        }
        return true;
    };

    wu.any = function any(iterable, fn, context) {
        var oppositeFn = fn === UNDEF ?
            function oppositeFn(obj) { return !toBool(obj); } :
            function oppositeFn(obj) {
                return !fn.call(context, obj);
            };
        return !wu.all(iterable, oppositeFn);
    };

    // wu.chain

    wu.has = function has(iterable, item) {
        return wu.any(iterable, wu.curry(wu.eq, item));
    };

    wu.map = function map(iterable, fn, context) {
        iterable = toIterator(iterable);
        context = context || this;

        var results = [],
            item = iterable.next();

        return wu.Iterator(function next() {
            var result = isInstance(item, StopIteration) ?
                item :
                fn.call(context, item);
            item = iterable.next();
            return result;
        });
    };

    var rangeHelper = function rangeHelper(start, stop, incr) {
        // Handle first case since we are doing +=
        start = start - incr;

        return wu.Iterator(function next() {
            return start + incr >= stop ?
                new wu.StopIteration :
                start += incr;
        });
    };

    wu.range = function range() {
        switch (arguments.length) {
            case 1:
                return rangeHelper(0, arguments[0], 1);
            case 2:
                return rangeHelper(arguments[0], arguments[1], 1);
            case 3:
                return rangeHelper(arguments[0], arguments[1], arguments[2]);
            default:
                throw new TypeError("Wrong number of arguments passed to wu.range!");
        }
    };

    wu.zip = function zip(iterA, iterB) {
        iterA = toIterator(iterA);
        iterB = toIterator(iterB);
        return wu.Iterator(function next() {
            var a = iterA.next(),
                b = iterB.next(),
                aIsStop = isInstance(a, StopIteration),
                bIsStop = isInstance(b, StopIteration),
                res;
            if (aIsStop && bIsStop) {
                return new StopIteration;
            }
            else {
                res = new Array;
                res[0] = aIsStop ? NULL : a;
                res[1] = bIsStop ? NULL : b;
                return res;
            }
        });
    };

    /**
     * Functions that are also methods (in some form) for wu functions.
     */

    wu.bind = function bind(scope, fn /*, variadic number of arguments */) {
        var args = ARR_SLICE.call(arguments, 2);
        return function bound() {
            return fn.apply(scope, args.concat(wu.toArray(arguments)));
        };
    };

    wu.compose = function compose(/* variadic number of functions */) {
        var fns = wu.toArray(arguments);
        return function composed() {
            var returnValue = fns.pop().apply(this, arguments);
            while (fns.length) {
                returnValue = fns.pop()(returnValue);
            }
            return returnValue;
        };
    };

    wu.curry = function curry(fn /* variadic number of args */) {
        var args = ARR_SLICE.call(arguments, 1);
        return function curried() {
            return fn.apply(this, args.concat(wu.toArray(arguments)));
        };
    };

    /**
     * Augmentation of functions with wu methods.
     */

    function augmentFunction(fn) {
        fn.all = function all(iterable, context) {
            return wu.all(iterable, this, context);
        };

        fn.any = function any(iterable, context) {
            return wu.any(iterable, this, context);
        };

        fn.bind = function bind(scope) {
            var args = [scope, this].concat(ARR_SLICE.call(arguments, 1));
            return wu.bind.apply(this, args);
        };

        fn.compose = function compose() {
            return wu.compose.apply(this, [this].concat(toArray(arguments)));
        };

        return fn;
    }

    wu.tang = { clan: 36 };

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


<commit_before>
App.Item = function(properties) {
  properties = properties || {};
  App.Glyph.call(this, properties);
  this.name = properties.name || '';
};

//------------------------------
// Repository:
//------------------------------

App.ItemRepository = new App.Repository("items", App.Item);

App.ItemRepository.define('apple', {
  name: 'apple',
  ch:   '%',
  fg:   '#f00'
});

App.ItemRepository.define('rock', {
  name: 'rock',
  ch:   '*',
  fg:   '#fff'
});
<commit_msg>added item.describe() & item.describeOne() functions<commit_after>
App.Item = function(properties) {
  properties = properties || {};
  App.Glyph.call(this, properties);
  this.name = properties.name || '';
};

App.Item.prototype.describe = function() {
  return this.name;
};

App.Item.prototype.describeOne = function(shouldCapitalize) {
  var prefixes = shouldCapitalize ? ['A','An'] : ['a','an'];
  var desc     = this.describe();
  var first    = desc.charAt(0).toLowerCase();
  var prefix   = 'aeiou'.indexOf(first)<0 ? prefixes[0] : prefixes[1];
  return prefix +" "+ desc;
};

//------------------------------
// Repository:
//------------------------------

App.ItemRepository = new App.Repository("items", App.Item);

App.ItemRepository.define('apple', {
  name: 'apple',
  ch:   '%',
  fg:   '#f00'
});

App.ItemRepository.define('rock', {
  name: 'rock',
  ch:   '*',
  fg:   '#fff'
});
<|endoftext|>


<commit_before>import React from 'react';
import { AppRegistry, Text, StyleSheet, View } from 'react-native';
import { StackNavigator } from 'react-navigation';
import Login from './app/containers/login/Login';
import LoginCode from './app/containers/login/LoginCode';
import HomeScreen from './app/containers/home/HomeScreen';
import Dashboard from './app/containers/dashboard/Dashboard';

const App = StackNavigator({
  Home: { screen: HomeScreen },
  Login: { screen: Login },
  LoginCode: { screen: LoginCode },
  Dashboard: { screen: Dashboard },
}, {
  initialRouteName: 'LoginCode',
});

AppRegistry.registerComponent('App', () => App);

export default App;<commit_msg>Changes default route back to Home<commit_after>import React from 'react';
import { AppRegistry, Text, StyleSheet, View } from 'react-native';
import { StackNavigator } from 'react-navigation';
import Login from './app/containers/login/Login';
import LoginCode from './app/containers/login/LoginCode';
import HomeScreen from './app/containers/home/HomeScreen';
import Dashboard from './app/containers/dashboard/Dashboard';

const App = StackNavigator({
  Home: { screen: HomeScreen },
  Login: { screen: Login },
  LoginCode: { screen: LoginCode },
  Dashboard: { screen: Dashboard },
}, {
  initialRouteName: 'Home',
});

AppRegistry.registerComponent('App', () => App);

export default App;<|endoftext|>


<commit_before>Ext.define('CustomApp', {
    extend: 'Rally.app.App',
    componentCls: 'app',

    launch: function() {
        MyApp = this;

        MyApp.storeCopies = [];
        MyApp.epicList = [];
        MyApp.currentScopePage = 1;
        MyApp.scopeDetails = [];
        MyApp.scopeDescription = [];
        MyApp.currentFeaturePage = 1;
        MyApp.featureDetails = [];
        MyApp.featureDescription = [];

        MyApp.globalContext = this.getContext().getDataContext();

        // Load the program list and create the program combobox
        MyApp._loadProgramList();
    },

    _wrapComponent: function(component, cls) {
        var wrapper = Ext.create('Ext.container.Container', {
            componentCls: cls
        });

        wrapper.add(component);

        return wrapper;
    },

    _loadProgramList: function() {
        var thisIsMyStore = Ext.create('Rally.data.WsapiDataStore', {
            autoLoad: true,

            model: 'PortfolioItem/Epic',

            context: MyApp.globalContext,

            fetch: ['Name' ],

            sorters: {
                property: 'Name',
                direction: 'ASC'
            },

            listeners: {
                load: function( myStore, records ) {
                    console.log( myStore );
                    var index=0;
                    for (index=0; index<records.length; index++) {
                        MyApp.epicList.push( records[index].data.Name );
                    }
                    MyApp._drawComboBox();
                }
            }
        });
    },

    _drawComboBox: function() {
        MyApp.combo = Ext.create('Ext.form.ComboBox', {
            fieldLabel: 'Program',

            store: MyApp.epicList,

            listeners: {
                'change': function(combo, newVal) {
                    MyApp.selectedEpicName = newVal;

                    MyApp._loadProgramDetails();
                }
            }
        });

        MyApp.programPane = Ext.create('Ext.container.Container', {
            componentCls: 'inner'
        });

        MyApp.add(MyApp._wrapComponent(MyApp.programPane, 'program'));

        MyApp.programPane.add(MyApp.combo);
    },

    _loadProgramDetails: function() {
        Ext.create('Rally.data.WsapiDataStore', {
            autoLoad: true,

            model: 'PortfolioItem/Epic',

            context: MyApp.globalContext,

            fetch: ['Name',
                    'c_SAPProjectNumber',
                    'InvestmentCategory',
                    'PlannedStartDate',
                    'PlannedEndDate',
                    'LastUpdateDate',
                    'Description'
                    ],

            filters: [
                    {
                        property: 'Name',
                        operator: 'Contains',
                        value: MyApp.selectedEpicName
                    }
                    ],

            sorters: {
                property: 'Rank',
                direction: 'ASC'
            },

            listeners: {
                load: MyApp._writeProgramDetails
            }
        });
    },

    _writeProgramDetails: function(myStore, records) {
        MyApp.storeCopies.push( myStore );

        // Remove the combo box
        MyApp.programPane.remove(MyApp.combo);

        title = records[0].data.Name;

        MyApp.programName = Ext.create('Ext.panel.Panel', {
            width: '100%',
            html: '

' + title + '

',
            renderTo: Ext.getBody()
        });

        MyApp.programPane.add( MyApp.programName );

        MyApp.programDetails = Ext.create('Rally.ui.grid.Grid', {
            store: myStore,
            border: 1,
            columnCfgs: [
                {dataIndex: 'c_SAPProjectNumber', text:'SAP #'},
                'InvestmentCategory',
                'PlannedStartDate',
                'PlannedEndDate',
                'LastUpdateDate'
            ],
            showPagingToolbar: false
        });

        MyApp.programPane.add(MyApp.programDetails);

        MyApp.programDescription = Ext.create('Ext.panel.Panel', {
            width: '100%',
            html: '
' + records[0].data.Description + '
',
            renderTo: Ext.getBody()
        });

        MyApp.programPane.add( MyApp.programDescription );

        MyApp.scopePane = Ext.create('Ext.container.Container', {
            componentCls: 'inner'
        });
        MyApp.add(MyApp._wrapComponent(MyApp.scopePane, 'scope'));

        MyApp.scopeTotal = Ext.create('Ext.panel.Panel', {
            width: '100%',
            html: '

Scope Summary

',
            renderTo: Ext.getBody()
        });

        MyApp.scopePane.add( MyApp.scopeTotal );

        MyApp._loadScopeDetails();
    },

    _loadScopeDetails: function() {
        thisStore = Ext.create('Rally.data.WsapiDataStore', {
            pageSize: 1,    // Load 1 page at a time
            limit: 1,       // Limit to 1

            model: 'PortfolioItem/MMF',
            context: MyApp.globalContext,

            fetch: ['Parent',
                    'Project',
                    'Name',
                    'c_SAPProjectNumber',
                    'InvestmentCategory',
                    'PlannedStartDate',
                    'PlannedEndDate',
                    'LastUpdateDate',
                    'Description'
                    ],

            filters: [
                    {
                        property: 'Parent.Name',
                        operator: 'Contains',
                        value: MyApp.selectedEpicName
                    }
                ],

            sorters: {
                property: 'Rank',
                direction: 'ASC'
            },

            listeners: {
                load: function( myStore, records ) {
                    MyApp.storeCopies.push( myStore );

                    MyApp._buildScopeDetails( myStore, records );

                    // Load the next until all pages are loaded
                    if ( myStore.currentPage < myStore.totalCount )
                    {
                        ++MyApp.currentScopePage;
                        MyApp._loadScopeDetails();
                    }
                    else
                    {
                        var index = 0;
                        for (index=0; index< myStore.totalCount; index++ ){
                            MyApp.scopePane.add(MyApp.scopeDetails[index]);
                            MyApp.scopePane.add(MyApp.scopeDescription[index] );
                        }

                        MyApp.featurePane = Ext.create('Ext.container.Container', {
                            componentCls: 'inner'
                        });
                        MyApp.add(MyApp._wrapComponent(MyApp.featurePane, 'feature'));

                        MyApp.featureTotal = Ext.create('Ext.panel.Panel', {
                            width: '100%',
                            html: '

Feature Summary by PSI

',
                            renderTo: Ext.getBody()
                        });

                        MyApp.featurePane.add( MyApp.featureTotal );

                        // Move to features
                        MyApp._loadFeatureDetails();
                    }
                }
            }
        });

        thisStore.loadPage( MyApp.currentScopePage );
    },

    _buildScopeDetails: function(myStore, records) {
        // Filter off the epic from the scope title
        var epicTitle = MyApp.selectedEpicName + ': ';
        var title = records[0].data.Name;
        if ( 0 === title.indexOf( epicTitle ) ) {
            title = title.substr( epicTitle.length );
        }

        MyApp.scopeDetails.push( Ext.create('Rally.ui.grid.Grid', {
            store: myStore,
            title: '' + title + '',
            border: 1,
            columnCfgs: [
                'Name',
                {dataIndex: 'c_SAPProjectNumber', text:'SAP #'},
                'InvestmentCategory',
                'PlannedStartDate',
                'PlannedEndDate',
                'LastUpdateDate',
                'Project'
            ],
            showPagingToolbar: false
        }) );

        MyApp.scopeDescription.push( Ext.create('Ext.panel.Panel', {
            width: '100%',
            html: '
' + records[0].data.Description + '
',
            renderTo: Ext.getBody()
        }) );
    },

    _loadFeatureDetails: function() {
        thisStore = Ext.create('Rally.data.WsapiDataStore', {
            pageSize: 1,    // Load 1 page at a time
            limit: 1,       // Limit to 1

            model: 'PortfolioItem/Feature',
            context: MyApp.globalContext,

            fetch: ['Parent',
                    'Project',
                    'Name',
                    'PreliminaryEstimate',
                    'ValueScore',
                    'RiskScore',
                    'LastUpdateDate',
                    'Description',
                    'Release'
                ],

            filters: [
                    {
                        property: 'Parent.Parent.Name',
                        operator: 'Contains',
                        value: MyApp.selectedEpicName
                    }
                ],

            sorters: {
                property: 'Release',
                direction: 'ASC'
            },

            listeners: {
                load: function( myStore, records ) {
                    MyApp.storeCopies.push( myStore );

                    MyApp._writeFeatureDetails( myStore, records );

                    // Load the next until all pages are loaded
                    if ( myStore.currentPage < myStore.totalCount )
                    {
                        ++MyApp.currentFeaturePage;
                        MyApp._loadFeatureDetails();
                    }
                    else
                    {
                        var index = 0;
                        for (index=0; index< myStore.totalCount; index++ ){
                            MyApp.featurePane.add(MyApp.featureDetails[index]);
                            MyApp.featurePane.add(MyApp.featureDescription[index] );
                        }

                        for (index=0; index< MyApp.storeCopies.length; index++){
                            console.log( MyApp.storeCopies[index] );
                        }
                    }
                }
            }
        });

        thisStore.loadPage( MyApp.currentFeaturePage );
    },

    _writeFeatureDetails: function(myStore, records) {
        var title = records[0].data.Name;

        MyApp.featureDetails.push( Ext.create('Rally.ui.grid.Grid', {
            store: myStore,
            border: 1,
            title: '' + title + '',
            columnCfgs: [
                'Name',
                'PreliminaryEstimate',
                'ValueScore',
                'RiskScore',
                'Project',
                'LastUpdateDate',
                'Release'
            ],
            showPagingToolbar: false
        }));

        MyApp.featureDescription.push( Ext.create('Ext.panel.Panel', {
            width: '100%',
            html: '
' + records[0].data.Description + '
',
            renderTo: Ext.getBody()
        }));
    }
});
<commit_msg>Removed additional variables that were no longer needed and moved updating panes to _write calls<commit_after>Ext.define('CustomApp', {
    extend: 'Rally.app.App',
    componentCls: 'app',

    launch: function() {
        MyApp = this;

        MyApp.epicList = [];
        MyApp.currentScopePage = 1;
        MyApp.currentFeaturePage = 1;

        MyApp.globalContext = this.getContext().getDataContext();

        // Load the program list and create the program combobox
        MyApp._loadProgramList();
    },

    _wrapComponent: function(component, cls) {
        var wrapper = Ext.create('Ext.container.Container', {
            componentCls: cls
        });

        wrapper.add(component);

        return wrapper;
    },

    _loadProgramList: function() {
        var thisIsMyStore = Ext.create('Rally.data.WsapiDataStore', {
            autoLoad: true,

            model: 'PortfolioItem/Epic',

            context: MyApp.globalContext,

            fetch: ['Name' ],

            sorters: {
                property: 'Name',
                direction: 'ASC'
            },

            listeners: {
                load: function( myStore, records ) {
                    //console.log( myStore );
                    var index=0;
                    for (index=0; index<records.length; index++) {
                        MyApp.epicList.push( records[index].data.Name );
                    }
                    MyApp._drawComboBox();
                }
            }
        });
    },

    _drawComboBox: function() {
        MyApp.combo = Ext.create('Ext.form.ComboBox', {
            fieldLabel: 'Program',

            store: MyApp.epicList,

            listeners: {
                'change': function(combo, newVal) {
                    MyApp.selectedEpicName = newVal;

                    MyApp._loadProgramDetails();
                }
            }
        });

        MyApp.programPane = Ext.create('Ext.container.Container', {
            componentCls: 'inner'
        });

        MyApp.add(MyApp._wrapComponent(MyApp.programPane, 'program'));

        MyApp.programPane.add(MyApp.combo);
    },

    _loadProgramDetails: function() {
        Ext.create('Rally.data.WsapiDataStore', {
            autoLoad: true,

            model: 'PortfolioItem/Epic',

            context: MyApp.globalContext,

            fetch: ['Name',
                    'c_SAPProjectNumber',
                    'InvestmentCategory',
                    'PlannedStartDate',
                    'PlannedEndDate',
                    'LastUpdateDate',
                    'Description'
                    ],

            filters: [
                    {
                        property: 'Name',
                        operator: 'Contains',
                        value: MyApp.selectedEpicName
                    }
                    ],

            sorters: {
                property: 'Rank',
                direction: 'ASC'
            },

            listeners: {
                load: MyApp._writeProgramDetails
            }
        });
    },

    _writeProgramDetails: function(myStore, records) {

        // Remove the combo box
        MyApp.programPane.remove(MyApp.combo);

        title = records[0].data.Name;

        MyApp.programName = Ext.create('Ext.panel.Panel', {
            width: '100%',
            html: '

' + title + '

',
            renderTo: Ext.getBody()
        });

        MyApp.programPane.add( MyApp.programName );

        MyApp.programDetails = Ext.create('Rally.ui.grid.Grid', {
            store: myStore,
            border: 1,
            columnCfgs: [
                {dataIndex: 'c_SAPProjectNumber', text:'SAP #'},
                'InvestmentCategory',
                'PlannedStartDate',
                'PlannedEndDate',
                'LastUpdateDate'
            ],
            showPagingToolbar: false
        });

        MyApp.programPane.add(MyApp.programDetails);

        MyApp.programDescription = Ext.create('Ext.panel.Panel', {
            width: '100%',
            html: '
' + records[0].data.Description + '
',
            renderTo: Ext.getBody()
        });

        MyApp.programPane.add( MyApp.programDescription );

        MyApp.scopePane = Ext.create('Ext.container.Container', {
            componentCls: 'inner'
        });
        MyApp.add(MyApp._wrapComponent(MyApp.scopePane, 'scope'));

        MyApp.scopeTotal = Ext.create('Ext.panel.Panel', {
            width: '100%',
            html: '

Scope Summary

',
            renderTo: Ext.getBody()
        });

        MyApp.scopePane.add( MyApp.scopeTotal );

        MyApp._loadScopeDetails();
    },

    _loadScopeDetails: function() {
        thisStore = Ext.create('Rally.data.WsapiDataStore', {
            pageSize: 1,    // Load 1 page at a time
            limit: 1,       // Limit to 1

            model: 'PortfolioItem/MMF',
            context: MyApp.globalContext,

            fetch: ['Parent',
                    'Project',
                    'Name',
                    'c_SAPProjectNumber',
                    'InvestmentCategory',
                    'PlannedStartDate',
                    'PlannedEndDate',
                    'LastUpdateDate',
                    'Description'
                    ],

            filters: [
                    {
                        property: 'Parent.Name',
                        operator: 'Contains',
                        value: MyApp.selectedEpicName
                    }
                ],

            sorters: {
                property: 'Rank',
                direction: 'ASC'
            },

            listeners: {
                load: function( myStore, records ) {
                    MyApp._buildScopeDetails( myStore, records );

                    // Load the next until all pages are loaded
                    if ( myStore.currentPage < myStore.totalCount )
                    {
                        ++MyApp.currentScopePage;
                        MyApp._loadScopeDetails();
                    }
                    else
                    {
                        MyApp.featurePane = Ext.create('Ext.container.Container', {
                            componentCls: 'inner'
                        });
                        MyApp.add(MyApp._wrapComponent(MyApp.featurePane, 'feature'));

                        MyApp.featureTotal = Ext.create('Ext.panel.Panel', {
                            width: '100%',
                            html: '

Feature Summary by PSI

',
                            renderTo: Ext.getBody()
                        });

                        MyApp.featurePane.add( MyApp.featureTotal );

                        // Move to features
                        MyApp._loadFeatureDetails();
                    }
                }
            }
        });

        thisStore.loadPage( MyApp.currentScopePage );
    },

    _buildScopeDetails: function(myStore, records) {
        // Filter off the epic from the scope title
        var epicTitle = MyApp.selectedEpicName + ': ';
        var title = records[0].data.Name;
        if ( 0 === title.indexOf( epicTitle ) ) {
            title = title.substr( epicTitle.length );
        }

        thisDetail = Ext.create('Rally.ui.grid.Grid', {
            store: myStore,
            title: '' + title + '',
            border: 1,
            columnCfgs: [
                {dataIndex: 'c_SAPProjectNumber', text:'SAP #'},
                'InvestmentCategory',
                'PlannedStartDate',
                'PlannedEndDate',
                'LastUpdateDate',
                'Project'
            ],
            showPagingToolbar: false
        });

        MyApp.scopePane.add( thisDetail );

        thisDescription = Ext.create('Ext.panel.Panel', {
            width: '100%',
            html: '
' + records[0].data.Description + '
',
            renderTo: Ext.getBody()
        });

        MyApp.scopePane.add( thisDescription );
    },

    _loadFeatureDetails: function() {
        thisStore = Ext.create('Rally.data.WsapiDataStore', {
            pageSize: 1,    // Load 1 page at a time
            limit: 1,       // Limit to 1

            model: 'PortfolioItem/Feature',
            context: MyApp.globalContext,

            fetch: ['Parent',
                    'Project',
                    'Name',
                    'PreliminaryEstimate',
                    'ValueScore',
                    'RiskScore',
                    'LastUpdateDate',
                    'Description',
                    'Release'
                ],

            filters: [
                    {
                        property: 'Parent.Parent.Name',
                        operator: 'Contains',
                        value: MyApp.selectedEpicName
                    }
                ],

            sorters: {
                property: 'Release',
                direction: 'ASC'
            },

            listeners: {
                load: function( myStore, records ) {
                    MyApp._writeFeatureDetails( myStore, records );

                    // Load the next until all pages are loaded
                    if ( myStore.currentPage < myStore.totalCount )
                    {
                        ++MyApp.currentFeaturePage;
                        MyApp._loadFeatureDetails();
                    }
                }
            }
        });

        thisStore.loadPage( MyApp.currentFeaturePage );
    },

    _writeFeatureDetails: function(myStore, records) {
        var title = records[0].data.Name;

        thisDetail = Ext.create('Rally.ui.grid.Grid', {
            store: myStore,
            border: 1,
            title: '' + title + '',
            columnCfgs: [
                'PreliminaryEstimate',
                'ValueScore',
                'RiskScore',
                'Project',
                'LastUpdateDate',
                'Release'
            ],
            showPagingToolbar: false
        });

        MyApp.featurePane.add( thisDetail );

        thisDescription = Ext.create('Ext.panel.Panel', {
            width: '100%',
            html: '
' + records[0].data.Description + '
',
            renderTo: Ext.getBody()
        });

        MyApp.featurePane.add( thisDescription );
    }
});
<|endoftext|>


<commit_before>import React, { Component } from 'react';
import {
  StyleSheet,
  View,
  TouchableHighlight,
} from 'react-native';
import { Container, Content } from 'native-base';
import ResponsiveImage from 'react-native-responsive-image';
import PropTypes from 'prop-types';

const styles = StyleSheet.create({
  container: {
    flex: 1,
  },
  layout: {
    flex: 1,
    flexDirection: 'row',
    justifyContent: 'center',
    alignItems: 'center',
  },
  box: {
    padding: 20,
    backgroundColor: 'rgba(0,0,0,0.05)',
    margin: 10,
  },
});

export default class ReactNativeProject extends Component {
  static propTypes = {
    navigation: PropTypes.object.isRequired,
  };

  static navigationOptions = {
    title: 'අන්තර්ජාල නැබ',
  };

  render() {
    const { navigate } = this.props.navigation;

    return (
      <Container>
        <Content>
          <View style={[styles.layout]}>
            <TouchableHighlight onPress={() => navigate('Detail', { title: 'පුවත් පත්' })}>
              <View style={styles.box} >
                <ResponsiveImage source={require('./img/news-papers.png')} initWidth="138" initHeight="138" />
              </View>
            </TouchableHighlight>
            <View style={styles.box} >
              <ResponsiveImage source={require('./img/unknown.png')} initWidth="138" initHeight="138" />
            </View>
          </View>
          <View style={[styles.layout]}>
            <View style={styles.box} >
              <ResponsiveImage source={require('./img/unknown.png')} initWidth="138" initHeight="138" />
            </View>
            <View style={styles.box} >
              <ResponsiveImage source={require('./img/unknown.png')} initWidth="138" initHeight="138" />
            </View>
          </View>
        </Content>
      </Container>
    );
  }
}
<commit_msg>Refactor App to be slighly data driven<commit_after>import React, { Component } from 'react';
import {
  StyleSheet,
  View,
} from 'react-native';
import { Container, Content } from 'native-base';
import PropTypes from 'prop-types';

import TwoColumnView from './src/components/common/TwoColumnView';
import BoxItem from './src/components/common/BoxItem';

const categories = [
  {
    id: '1',
    title: 'පුවත් පත්',
    thumbnail: 'CATEGORY_NEWSPAPERS',
    items: [
      {
        id: '1_1',
        title: 'දිවයින',
        thumbnail: 'NEWSPAPERS_DIVAINA',
      },
      {
        id: '1_2',
        title: 'ලංකාදීප',
        thumbnail: 'NEWSPAPERS_LANKADEEPA',
      },
      {
        id: '1_3',
        title: 'රිවිර',
        thumbnail: 'NEWSPAPERS_RIVIRA',
      },
      {
        id: '1_4',
        title: 'දෙරණ',
        thumbnail: 'NEWSPAPERS_DERANA',
      },
    ],
  },
];

const styles = StyleSheet.create({
  container: {
    flex: 1,
  },
});

export default class ReactNativeProject extends Component {
  static propTypes = {
    navigation: PropTypes.object.isRequired,
  };

  static navigationOptions = {
    title: 'අන්තර්ජාල නැබ',
  };

  renderCategories() {
    const { navigate } = this.props.navigation;

    const nodes = categories.map(category => (
      <BoxItem
        key={category.id}
        onPress={() => navigate('Detail', { title: category.title })}
        {...category}
      />
    ));

    return (
      <TwoColumnView>
        {nodes}
      </TwoColumnView>
    );
  }

  render() {
    return (
      <Container>
        <Content>
          <View style={styles.container}>
            {this.renderCategories()}
          </View>
        </Content>
      </Container>
    );
  }
}
<|endoftext|>


<commit_before>var Ext = window.Ext4 || window.Ext;

Ext.define('CustomApp', {
    extend: 'Rally.app.App',
    componentCls: 'app',

    // entry point to app
    launch: function() {
        this._doLayout();
    },

    //initial layout of widgets
    _doLayout: function() {
        this._loadFeatures();
    },

    // load features into store
    _loadFeatures: function() {
        window.console && console.log("Loading features");

        Ext.create('Rally.data.WsapiDataStore', {
            model: 'PortfolioItem/Feature',
            autoLoad: true,
            listeners: {
                load: function(store, records, success) {
                    console.log("Loaded Store with %i records", records.length);
                    this._calculateScore(records); // make sure the scores are up to date
                    this._updateGrid(store); // populate the grid
                },

                update: function(store, rec, modified, opts) {
                    console.log("data updated");
                    this._calculateScore([rec]); // only update the record (feature) that changed
                },
                scope: this
            },

            fetch: ['Name', 'FormattedID', 'JobSize', 'TimeValue', 'OERR', 'UserValue', 'Score']
        });
    },

    _calculateScore: function(records) {
        Ext.Array.each(records, function(feature) {
            // get the data used to calc score
            // if poor performance is an issue, you can try taking off the parseInt casts
            var jobSize = parseInt(feature.data.JobSize + "", 10); // parse int ensures we are dealing with ints, base 10
            var timeValue = parseInt(feature.data.TimeValue + "", 10);
            var OERR = parseInt(feature.data.OERR + "", 10);
            var userValue = parseInt(feature.data.UserValue + "", 10);

            if (jobSize > 0) { // jobSize is the denominator so make sure it's not 0
                var score = ~~ (((userValue + timeValue + OERR) / jobSize) + 0.5); // shortcut for casting to int

                if (parseInt(feature.get("Score") + "", 10) !== score) { // only update if score changed
                    feature.set('Score', score); // set score value in db
                    // don't call feature.save(); it just breaks stuff
                    console.log("Setting a new score");
                }
            }
        });
    },

    _createGrid: function(myStore) {
        console.log("Load up a populated grid!", myStore);
        this._myGrid = Ext.create('Rally.ui.grid.Grid', {
            xtype: 'rallygrid',
            title: 'Feature Scoring Grid',
            height: 200,
            store: myStore,
            enableEditing: true,
            selType: 'cellmodel',
            columnCfgs: [
                { // override ID and Name - no changes on these allowed in this grid
                    text: 'Portfolio ID',
                    dataIndex: 'FormattedID',
                    flex: 1,
                    xtype: 'templatecolumn',
                    tpl: Ext.create('Rally.ui.renderer.template.FormattedIDTemplate') // make the ID a live link
                },

                {
                    text: "Name",
                    dataIndex: "Name",
                    flex: 2
                },

                "TimeValue", 'OERR', 'UserValue', 'JobSize', // use native Ext formatting - allows cell edits & got rid of errors

                { // override score so that the user can't edit it
                    text: "Score",
                    dataIndex: 'Score'
                }
            ]
        });
        this.add(this._myGrid);

        // override the event publish to prevent random refreshes of the whole app when the cell changes
        var celledit = this._myGrid.plugins[0];
        var oldPub = celledit.publish;
        var newPub = function (event, varargs) {
            if (event !== "objectupdate") {
                oldPub.apply(this, arguments);
            } else {
                // no-op
            }
        };

        celledit.publish = Ext.bind(newPub, celledit);
    },
    _updateGrid: function(myStore) {
        if (this._myGrid === undefined) {
            this._createGrid(myStore);
        }
        else {
            this._myGrid.reconfigure(myStore);
        }
    }
<<<<<<< HEAD
});
=======
});
>>>>>>> origin/master
<commit_msg>removed merge artifacts<commit_after>var Ext = window.Ext4 || window.Ext;

Ext.define('CustomApp', {
    extend: 'Rally.app.App',
    componentCls: 'app',

    // entry point to app
    launch: function() {
        this._doLayout();
    },

    //initial layout of widgets
    _doLayout: function() {
        this._loadFeatures();
    },

    // load features into store
    _loadFeatures: function() {
        window.console && console.log("Loading features");

        Ext.create('Rally.data.WsapiDataStore', {
            model: 'PortfolioItem/Feature',
            autoLoad: true,
            listeners: {
                load: function(store, records, success) {
                    console.log("Loaded Store with %i records", records.length);
                    this._calculateScore(records); // make sure the scores are up to date
                    this._updateGrid(store); // populate the grid
                },

                update: function(store, rec, modified, opts) {
                    console.log("data updated");
                    this._calculateScore([rec]); // only update the record (feature) that changed
                },
                scope: this
            },

            fetch: ['Name', 'FormattedID', 'JobSize', 'TimeValue', 'OERR', 'UserValue', 'Score']
        });
    },

    _calculateScore: function(records) {
        Ext.Array.each(records, function(feature) {
            // get the data used to calc score
            // if poor performance is an issue, you can try taking off the parseInt casts
            var jobSize = parseInt(feature.data.JobSize + "", 10); // parse int ensures we are dealing with ints, base 10
            var timeValue = parseInt(feature.data.TimeValue + "", 10);
            var OERR = parseInt(feature.data.OERR + "", 10);
            var userValue = parseInt(feature.data.UserValue + "", 10);

            if (jobSize > 0) { // jobSize is the denominator so make sure it's not 0
                var score = ~~ (((userValue + timeValue + OERR) / jobSize) + 0.5); // shortcut for casting to int

                if (parseInt(feature.get("Score") + "", 10) !== score) { // only update if score changed
                    feature.set('Score', score); // set score value in db
                    // don't call feature.save(); it just breaks stuff
                    console.log("Setting a new score");
                }
            }
        });
    },

    _createGrid: function(myStore) {
        console.log("Load up a populated grid!", myStore);
        this._myGrid = Ext.create('Rally.ui.grid.Grid', {
            xtype: 'rallygrid',
            title: 'Feature Scoring Grid',
            height: 200,
            store: myStore,
            enableEditing: true,
            selType: 'cellmodel',
            columnCfgs: [
                { // override ID and Name - no changes on these allowed in this grid
                    text: 'Portfolio ID',
                    dataIndex: 'FormattedID',
                    flex: 1,
                    xtype: 'templatecolumn',
                    tpl: Ext.create('Rally.ui.renderer.template.FormattedIDTemplate') // make the ID a live link
                },

                {
                    text: "Name",
                    dataIndex: "Name",
                    flex: 2
                },

                "TimeValue", 'OERR', 'UserValue', 'JobSize', // use native Ext formatting - allows cell edits & got rid of errors

                { // override score so that the user can't edit it
                    text: "Score",
                    dataIndex: 'Score'
                }
            ]
        });
        this.add(this._myGrid);

        // override the event publish to prevent random refreshes of the whole app when the cell changes
        var celledit = this._myGrid.plugins[0];
        var oldPub = celledit.publish;
        var newPub = function (event, varargs) {
            if (event !== "objectupdate") {
                oldPub.apply(this, arguments);
            } else {
                // no-op
            }
        };

        celledit.publish = Ext.bind(newPub, celledit);
    },
    _updateGrid: function(myStore) {
        if (this._myGrid === undefined) {
            this._createGrid(myStore);
        }
        else {
            this._myGrid.reconfigure(myStore);
        }
    }

});
<|endoftext|>


<commit_before>var $ = require('programmatic')

// Join an array of code blocks into a single chunk separated by blank lines.

module.exports = function (blocks) {
    var block = blocks[0]
    for (var i = 1, I = blocks.length; i < I; i++) {
        block = $(`
            `, block, `

            `, blocks[i], `
        `)
    }
    return block
}
<commit_msg>Use `const` and `let` in join.<commit_after>const $ = require('programmatic')

// Join an array of code blocks into a single chunk separated by blank lines.

module.exports = function (blocks) {
    let block = blocks[0]
    for (let i = 1, I = blocks.length; i < I; i++) {
        block = $(`
            `, block, `

            `, blocks[i], `
        `)
    }
    return block
}
<|endoftext|>


<commit_before>"use strict";

var PNG = function(){

	// initialize all members to keep the same hidden class
	this.width = 0;
	this.height = 0;
	this.bitDepth = 0;
	this.colorType = 0;
	this.compressionMethod = 0;
	this.filterMethod = 0;
	this.interlaceMethod = 0;

	this.colors = 0;
	this.hasAlphaChannel = false;
	this.pixelBits = 0;

	this.palette = null;
	this.pixels = null;

};

PNG.prototype.getWidth = function(){
	return this.width;
};

PNG.prototype.setWidth = function(width){
	this.width = width;
};

PNG.prototype.getHeight = function(){
	return this.height;
};

PNG.prototype.setHeight = function(height){
	this.height = height;
};

PNG.prototype.getBitDepth = function(){
	return this.bitDepth;
};

PNG.prototype.setBitDepth = function(bitDepth){
	if ([2, 4, 8, 16].indexOf(bitDepth) === -1){
		throw new Error("invalid bith depth " + bitDepth);
	}
	this.bitDepth = bitDepth;
};

PNG.prototype.getColorType = function(){
	return this.colorType;
};

PNG.prototype.setColorType = function(colorType){

	//   Color    Allowed    Interpretation
	//   Type    Bit Depths
	//
	//   0       1,2,4,8,16  Each pixel is a grayscale sample.
	//
	//   2       8,16        Each pixel is an R,G,B triple.
	//
	//   3       1,2,4,8     Each pixel is a palette index;
	//                       a PLTE chunk must appear.
	//
	//   4       8,16        Each pixel is a grayscale sample,
	//                       followed by an alpha sample.
	//
	//   6       8,16        Each pixel is an R,G,B triple,
	//                       followed by an alpha sample.

	var colors = 0, hasAlphaChannel = false;

	switch (colorType){
		case 0: colors = 1; break;
		case 2: colors = 3; break;
		case 3: colors = 1; break;
		case 4: colors = 2; hasAlphaChannel = true; break;
		case 6: colors = 4; hasAlphaChannel = true; break;
		default: throw new Error("invalid color type");
	}

	this.colors = colors;
	this.hasAlphaChannel = hasAlphaChannel;
	this.colorType = colorType;
};

PNG.prototype.getCompressionMethod = function(){
	return this.compressionMethod;
};

PNG.prototype.setCompressionMethod = function(compressionMethod){
	if (compressionMethod !== 0){
		throw new Error("invalid compression method " + compressionMethod);
	}
	this.compressionMethod = compressionMethod;
};

PNG.prototype.getFilterMethod = function(){
	return this.filterMethod;
};

PNG.prototype.setFilterMethod = function(filterMethod){
	if (filterMethod !== 0){
		throw new Error("invalid filter method " + filterMethod);
	}
	this.filterMethod = filterMethod;
};

PNG.prototype.getInterlaceMethod = function(){
	return this.interlaceMethod;
};

PNG.prototype.setInterlaceMethod = function(interlaceMethod){
	if (interlaceMethod !== 0 && interlaceMethod !== 1){
		throw new Error("invalid interlace method " + interlaceMethod);
	}
	this.interlaceMethod = interlaceMethod;
};

PNG.prototype.setPalette = function(palette){
	if (palette.length % 3 !== 0){
		throw new Error("incorrect PLTE chunk length");
	}
	if (palette.length > (Math.pow(2, this.bitDepth) * 3)){
		throw new Error("palette has more colors than 2^bitdepth");
	}
	this.palette = palette;
};

PNG.prototype.getPalette = function(){
	return this.palette;
};

/**
 * get the pixel color on a certain location
 * result is an array: [red, green, blue, alpha]
 */
PNG.prototype.getPixel = function(x, y){
	if (!this.pixels) throw new Error("pixel data is empty");
	if (x >= this.width || y >= this.height){
		throw new Error("x,y position out of bound");
	}
	var i = this.colors * this.bitDepth / 8 * (y * this.width + x);
	var colors = this.pixels.slice(i, i + this.colors);

	switch (this.colorType){
		case 0: return [colors[0], colors[0], colors[0], 255];
		case 2: return [colors[0], colors[1], colors[2], 255];
		case 3: return [
			this.palette[colors[0] * 3 + 0],
			this.palette[colors[0] * 3 + 1],
			this.palette[colors[0] * 3 + 2],
			255];
		case 4: return [colors[0], colors[0], colors[0], colors[1]];
		case 6: return [colors[0], colors[1], colors[2], colors[3]];
	}

};

module.exports = PNG;
<commit_msg>Change hasAlphaChannel PNG property to simply alpha<commit_after>"use strict";

var PNG = function(){

	// initialize all members to keep the same hidden class
	this.width = 0;
	this.height = 0;
	this.bitDepth = 0;
	this.colorType = 0;
	this.compressionMethod = 0;
	this.filterMethod = 0;
	this.interlaceMethod = 0;

	this.colors = 0;
	this.alpha = false;
	this.pixelBits = 0;

	this.palette = null;
	this.pixels = null;

};

PNG.prototype.getWidth = function(){
	return this.width;
};

PNG.prototype.setWidth = function(width){
	this.width = width;
};

PNG.prototype.getHeight = function(){
	return this.height;
};

PNG.prototype.setHeight = function(height){
	this.height = height;
};

PNG.prototype.getBitDepth = function(){
	return this.bitDepth;
};

PNG.prototype.setBitDepth = function(bitDepth){
	if ([2, 4, 8, 16].indexOf(bitDepth) === -1){
		throw new Error("invalid bith depth " + bitDepth);
	}
	this.bitDepth = bitDepth;
};

PNG.prototype.getColorType = function(){
	return this.colorType;
};

PNG.prototype.setColorType = function(colorType){

	//   Color    Allowed    Interpretation
	//   Type    Bit Depths
	//
	//   0       1,2,4,8,16  Each pixel is a grayscale sample.
	//
	//   2       8,16        Each pixel is an R,G,B triple.
	//
	//   3       1,2,4,8     Each pixel is a palette index;
	//                       a PLTE chunk must appear.
	//
	//   4       8,16        Each pixel is a grayscale sample,
	//                       followed by an alpha sample.
	//
	//   6       8,16        Each pixel is an R,G,B triple,
	//                       followed by an alpha sample.

	var colors = 0, alpha = false;

	switch (colorType){
		case 0: colors = 1; break;
		case 2: colors = 3; break;
		case 3: colors = 1; break;
		case 4: colors = 2; alpha = true; break;
		case 6: colors = 4; alpha = true; break;
		default: throw new Error("invalid color type");
	}

	this.colors = colors;
	this.alpha = alpha;
	this.colorType = colorType;
};

PNG.prototype.getCompressionMethod = function(){
	return this.compressionMethod;
};

PNG.prototype.setCompressionMethod = function(compressionMethod){
	if (compressionMethod !== 0){
		throw new Error("invalid compression method " + compressionMethod);
	}
	this.compressionMethod = compressionMethod;
};

PNG.prototype.getFilterMethod = function(){
	return this.filterMethod;
};

PNG.prototype.setFilterMethod = function(filterMethod){
	if (filterMethod !== 0){
		throw new Error("invalid filter method " + filterMethod);
	}
	this.filterMethod = filterMethod;
};

PNG.prototype.getInterlaceMethod = function(){
	return this.interlaceMethod;
};

PNG.prototype.setInterlaceMethod = function(interlaceMethod){
	if (interlaceMethod !== 0 && interlaceMethod !== 1){
		throw new Error("invalid interlace method " + interlaceMethod);
	}
	this.interlaceMethod = interlaceMethod;
};

PNG.prototype.setPalette = function(palette){
	if (palette.length % 3 !== 0){
		throw new Error("incorrect PLTE chunk length");
	}
	if (palette.length > (Math.pow(2, this.bitDepth) * 3)){
		throw new Error("palette has more colors than 2^bitdepth");
	}
	this.palette = palette;
};

PNG.prototype.getPalette = function(){
	return this.palette;
};

/**
 * get the pixel color on a certain location
 * result is an array: [red, green, blue, alpha]
 */
PNG.prototype.getPixel = function(x, y){
	if (!this.pixels) throw new Error("pixel data is empty");
	if (x >= this.width || y >= this.height){
		throw new Error("x,y position out of bound");
	}
	var i = this.colors * this.bitDepth / 8 * (y * this.width + x);
	var colors = this.pixels.slice(i, i + this.colors);

	switch (this.colorType){
		case 0: return [colors[0], colors[0], colors[0], 255];
		case 2: return [colors[0], colors[1], colors[2], 255];
		case 3: return [
			this.palette[colors[0] * 3 + 0],
			this.palette[colors[0] * 3 + 1],
			this.palette[colors[0] * 3 + 2],
			255];
		case 4: return [colors[0], colors[0], colors[0], colors[1]];
		case 6: return [colors[0], colors[1], colors[2], colors[3]];
	}

};

module.exports = PNG;
<|endoftext|>