<commit_before>var Promise = require('bluebird');
var fs = Promise.promisifyAll(require('fs'));
var path = require('path');
var _ = require('lodash');
var mkdirp = Promise.promisify(require('mkdirp'));

var config = {
    'dryrun': false,
    'encoding': 'utf8',
    'files': {
        'scaffile': '.scaf',
        'scafout': '.scafout',
        'scafctx': '.scafctx',
    },
    'prefix': '-- ',
    'special': '_',
};

var keys = {
    'key': config.special + 'k',
    'value': config.special + 'v',
    'self': config.special + 'self',
    'root': config.special + 'root',
    'parent': config.special + 'parent',
};

function ConflictingError(target, files) {
    this.message = "Multiple files writing to the same place: '" + target + "' => [" + files.join(', ') + "]";
    this.target = target;
    this.files = files;
    this.name = "ConflictingError";
    Error.captureStackTrace(this, ConflictingError);
}
ConflictingError.prototype = Object.create(Error.prototype);
ConflictingError.prototype.constructor = ConflictingError;

function NotFoundError(pa) {
    this.message = "No such file or directory: " + pa;
    this.pa = pa;
    this.name = "NotFoundError";
    Error.captureStackTrace(this, NotFoundError);
}
NotFoundError.prototype = Object.create(Error.prototype);
NotFoundError.prototype.constructor = NotFoundError;

var files = {};

function build_recursive(obj, reader, writer, pa, parentname) {
    if (parentname === undefined) {
        parentname = '';
    }
    return Promise.resolve(reader.isdir(pa))
        .then(isdir => {
            if (isdir) {
                return build_dir(obj, reader, writer, pa, parentname);
            } else {
                return build_file(obj, reader, writer, pa, parentname);
            }
        });
}

function utils_create_kv(k, v) {
    var tmp = {};
    tmp[keys.key] = k;
    tmp[keys.value] = v;
    return tmp;
}

function utils_parse_scope(obj, scopestr) {
    /* jshint -W083 */
    var scope = scopestr.replace('[]', '.[]').replace('{}', '.{}').replace(/^\./, '').split('.');
    var res = [obj];
    var old;
    for (var ch of scope) {
        old = res;
        res = [];
        for (var e of old) {
            var subres = [];
            if (ch == '[]') {
                if (_.isArray(e)) {
                    subres = subres.concat(e);
                } else if (_.isObject(e)) {
                    subres = subres.concat(_.values(_.omit(e, _.values(keys))));
                }
            } else if (ch == '{}') {
                if (_.isArray(e[keys.self])) {
                    _.transform(e[keys.self], (res, v, k) => {
                        res.push(utils_create_kv(k, v));
                    }, subres);
                } else if (_.isObject(e[keys.self])) {
                    _.transform(_.omit(e[keys.self], _.values(keys)), (result, v, k) => {
                        result.push(utils_create_kv(k, v));
                    }, subres);
                }
            } else {
                subres.push(e[ch]);
            }
            for (var e2 of subres) {
                res.push(utils_normailze_elem(e2, e));
            }
        }
    }
    return res;
}

function utils_normailze_elem(elem, parent) {
    var root = parent?parent[keys.root] || parent:elem;
    if (!_.isObject(elem)) {
        var tmp = {};
        tmp[keys.self] = elem;
        elem = tmp;
    } else {
        elem[keys.self] = elem;
    }
    elem[keys.parent] = parent;
    elem[keys.root] = root;
    return elem;
}

function utils_parse_recursive(optss, res) {
    if (optss.length === 0)
        return res;
    var more = [];
    if (res === undefined) {
        res = [];
    }
    for (var opts of optss) {
        var tmp = utils_parse_once(opts);
        for (var parsed of tmp) {
            if (parsed.args.length === 0) {
                res.push(parsed);
            } else {
                more.push(parsed);
            }
        }
    }
    return utils_parse_recursive(more, res);
}

function utils_parse_once(opts) {
    var res = [];
    if (opts.args.length === 0)
        return [opts];

    var el = opts.args[0];
    var t;
    switch (el.type) {
        case 'scope':
            var ctxs = utils_parse_scope(opts.ctx, el.arg);
            for (var ctx of ctxs) {
                res.push({
                    'ctx': ctx,
                    'name': opts.name.slice(),
                    'args': opts.args.slice(1),
                });
            }
            break;
        case 'cond':
            t = _.template(el.arg);
            var cond = t(opts.ctx);
            opts.args = opts.args.slice(1);
            if (cond)
                res = [opts];
            break;
        case 'name':
            t = _.template(el.arg);
            var name = t(opts.ctx);
            opts.name.push(name);
            opts.args = opts.args.slice(1);
            res = [opts];
            break;
    }
    return res;
}

function parse_scaf(content, originalname, obj, parentname) {
    var opts = {
        'ctx': obj,
        'name': [],
        'args': [],
    };

    // TODO: fix later, too slow
    var orig = [];
    var lines = content.split('\n');
    for (var line of lines) {
        if (line.startsWith(config.prefix)) {
            line = line.substring(config.prefix.length);
            var tmp = line.split(' ');
            var op = tmp[0];
            var arg = tmp.length > 1?tmp.slice(1).join(' '):'';
            switch (op) {
                case 'scope':
                    opts.args.push({'arg': arg, 'type': 'scope'});
                    break;
                case 'cond':
                    opts.args.push({'arg': arg, 'type': 'cond'});
                    break;
                case 'name':
                    opts.args.push({'arg': arg, 'type': 'name'});
                    break;
            }
        } else {
            orig.push(line);
        }
    }
    return Promise.resolve(opts)
        .then(opts => {
            opts.ctx = utils_normailze_elem(opts.ctx)
            return utils_parse_recursive([opts]);
        })
        .map(opts => {
            var name;
            if (opts.name.length === 0) {
                name = originalname;
            } else {
                opts.name = opts.name.filter(x => x);
                if (opts.name.length === 0) {
                    name = '';
                } else {
                    name = path.join.apply(path, opts.name);
                }
            }
            var wholename = path.join(parentname, name);
            return {
                'ctx': opts.ctx,
                'wholename': wholename,
                'orig': orig.join('\n'),
            };
        });
}

function build_dir(obj, reader, writer, dir, parentname) {
    var scaf = path.join(dir, config.files.scaffile);
    return Promise.resolve(reader.exists(scaf))
        .then(e => {
            if (e) {
                return reader.read(scaf);
            } else {
                return '';
            }
        })
        .then(content => {
            return parse_scaf(content, dir, obj, parentname);
        })
        .map(opts => {
            return Promise.resolve(reader.ls(dir))
                .filter(x => (_.values(config.files).indexOf(x) == -1))
                .map(x => build_recursive(opts.ctx, reader, writer, path.join(dir, x), opts.wholename))
                .reduce((res, f) => {
                    return _.extend(res, f);
                }, {});
        })
        .reduce((res, f) => {
            return _.extend(res, f);
        }, {});
}

var fsreadable = {
    'read': function(file) {
        return fs.readFileAsync(path.join(this.base, file), config.encoding);
    },
    'isdir': function(pa) {
        return fs.statAsync(path.join(this.base,pa)).then(stat => stat.isDirectory());
    },
    'exists': function(pa) {
        return fs.accessAsync(path.join(this.base, pa), fs.constants.F_OK)
            .return(true)
            .catch(() => false);
    },
    'ls': function(dir) {
        return fs.readdirAsync(path.join(this.base, dir));
    },
};
var fswritable = {
    'write': function(file, content) {
        return fs.writeFileAsync(path.join(this.base, file), content, {'encoding': config.encoding});
    },
    'mkdirp': function(dir) {
        return mkdirp(path.join(this.base, dir));
    },
    'init': () => {},
    'commit': () => {},
};

var objreadable = {
    'read': function(file){
        var el = this.ro;
        var p = file.split('/').filter(x => ['', '.'].indexOf(x) === -1);
        for (var e of p) {
            el = el[e];
        }
        return el;
    },
    'isdir': function(pa){
        var el = this.ro;
        var p = pa.split('/').filter(x => ['', '.'].indexOf(x) === -1);
        for (var e of p) {
            el = el[e];
        }
        return _.isObject(el);
    },
    'exists': function(pa){
        var el = this.ro;
        var p = pa.split('/').filter(x => ['', '.'].indexOf(x) === -1);
        for (var e of p) {
            el = el[e];
            if (el === undefined)
                return false;
        }
        return true;
    },
    'ls': function(dir){
        var el = this.ro;
        var p = dir.split('/').filter(x => ['', '.'].indexOf(x) === -1);
        for (var e of p) {
            el = el[e];
        }
        return _.keys(el);
    },
};
var objwritable = {
    'write': function(file, content){
        var el = this.wo;
        var p = file.split('/').filter(x => ['', '.'].indexOf(x) === -1);
        var par = p.slice(0, -1);
        for (var e of par) {
            el = el[e];
        }
        // TODO: raise if it is a dir
        el[p.pop()] = content;
    },
    'mkdirp': function(dir) {
        var el = this.wo;
        var p = dir.split('/').filter(x => ['', '.'].indexOf(x) === -1);
        for (var e of p) {
            if (el[e] === undefined)
                el[e] = {};
            // TODO: raise if a file
            el = el[e];
        }
    },
    'init': () => {},
    'commit': () => {},
};

function build_file(obj, reader, writer, file, parentname) {
    return Promise.resolve(reader.read(file))
        .then(content => {
            return parse_scaf(content, file, obj, parentname);
        })
        .map(opts => {
            var cont = _.template(opts.orig);
            if (files[opts.wholename] === undefined) {
                files[opts.wholename] = file;
            } else {
                throw new ConflictingError(opts.wholename, [files[opts.wholename], file]);
            }
            var wholename = opts.wholename;
            var text = cont(opts.ctx);
            var ret = {};
            var p = !config.dryrun?Promise.resolve(writer.mkdirp(path.dirname(wholename))):Promise.resolve();
            return p.then(_ => {
                    console.log(wholename, '\n', text);
                    if (!config.dryrun)
                        return writer.write(wholename, text);
                })
                .then(_ => {ret[wholename] = text; })
                .return(ret);
        })
        .reduce((res, f) => {
            return _.extend(res, f);
        }, {});
}

function build(obj, reader, writer, pa, parentname) {
    parentname = parentname || '.';
    pa = pa || '.';
    return Promise.resolve(writer.init())
        .then(_ => reader.exists(pa))
        .then(e => {
            if (e) {
                return build_recursive(obj, reader, writer, pa, parentname);
            } else {
                throw new NotFoundError(pa);
            }
        })
        .then(r => {
            return writer.commit();
        });
}

var ObjReader = function(ro) {
    this.ro = ro || {};
};
ObjReader.prototype = objreadable;
ObjReader.prototype.constructor = ObjReader;

var ObjWriter = function(wo) {
    this.wo = wo || {};
};
ObjWriter.prototype = objwritable;
ObjWriter.prototype.constructor = ObjWriter;

var JsonReader = function(file) {
    this.ro = {};
    this.file = file;
    this.init = () => {
        return fs.readFileAsync(this.file, config.encoding)
            .then(JSON.parse)
            .then(json => {this.ro = json;});
    };
};
JsonReader.prototype = objreadable;
JsonReader.prototype.constructor = JsonReader;

var JsonWriter = function(file) {
    this.wo = {};
    this.file = file || config.files.scafout;
    this.commit = () => {
        return fs.writeFileAsync(this.file, JSON.stringify(this.wo), {'encoding': config.encoding})
            .return(this.wo);
    };
};
JsonWriter.prototype = objwritable;
JsonWriter.prototype.constructor = JsonWriter;

var FsReader = function(base) {
    this.base = base;
};
FsReader.prototype = fsreadable;
FsReader.prototype.constructor = FsReader;

var FsWriter = function(base) {
    this.base = base;
};
FsWriter.prototype = fswritable;
FsWriter.prototype.constructor = FsWriter;

function main(args) {
    var defaultargs = {
        'reader': 'fs',
        'writer': 'json',
        'in': '.',
        'out': config.files.scafout,
        'ctx': config.files.scafctx,
    };
    args = _.extend(defaultargs, args);
    var reader = args.reader === 'json'?new JsonReader(args['in']):new FsReader(args['in']);
    var writer = args.writer === 'json'?new JsonWriter(args.out):new FsWriter(args.out);
    return fs.readFileAsync(args.ctx, config.encoding)
        .then(JSON.parse)
        .then(ctx => build(ctx, reader, writer));
}

module.exports = {
    'config': config,
    'errors': {
        'NotFoundError': NotFoundError,
        'ConflictingError': ConflictingError,
    },
    'readers': {
        'fs': FsReader,
        'json': JsonReader,
        'obj': ObjReader,
    },
    'writers': {
        'fs': FsWriter,
        'json': JsonWriter,
        'obj': ObjWriter,
    },
    'build': build,
    'main': main,
};
<commit_msg>code cleanup<commit_after>var Promise = require('bluebird');
var fs = Promise.promisifyAll(require('fs'));
var path = require('path');
var _ = require('lodash');
var mkdirp = Promise.promisify(require('mkdirp'));

var config = {
    'dryrun': false,
    'encoding': 'utf8',
    'files': {
        'scaffile': '.scaf',
        'scafout': '.scafout',
        'scafctx': '.scafctx',
    },
    'prefix': '-- ',
    'special': '_',
};

var keys = {
    'key': config.special + 'k',
    'value': config.special + 'v',
    'self': config.special + 'self',
    'root': config.special + 'root',
    'parent': config.special + 'parent',
};

function ConflictingError(target, files) {
    this.message = "Multiple files writing to the same place: '" + target + "' => [" + files.join(', ') + "]";
    this.target = target;
    this.files = files;
    this.name = "ConflictingError";
    Error.captureStackTrace(this, ConflictingError);
}
ConflictingError.prototype = Object.create(Error.prototype);
ConflictingError.prototype.constructor = ConflictingError;

function NotFoundError(pa) {
    this.message = "No such file or directory: " + pa;
    this.pa = pa;
    this.name = "NotFoundError";
    Error.captureStackTrace(this, NotFoundError);
}
NotFoundError.prototype = Object.create(Error.prototype);
NotFoundError.prototype.constructor = NotFoundError;

var files = {};

function build_recursive(obj, reader, writer, pa, parentname) {
    if (parentname === undefined) {
        parentname = '';
    }
    return Promise.resolve(reader.isdir(pa))
        .then(isdir => {
            if (isdir) {
                return build_dir(obj, reader, writer, pa, parentname);
            } else {
                return build_file(obj, reader, writer, pa, parentname);
            }
        });
}

function utils_create_kv(k, v) {
    var tmp = {};
    tmp[keys.key] = k;
    tmp[keys.value] = v;
    return tmp;
}

function utils_parse_scope(obj, scopestr) {
    /* jshint -W083 */
    var scope = scopestr.replace('[]', '.[]').replace('{}', '.{}').replace(/^\./, '').split('.');
    var res = [obj];
    var old;
    for (var ch of scope) {
        old = res;
        res = [];
        for (var e of old) {
            var subres = [];
            if (ch == '[]') {
                if (_.isArray(e)) {
                    subres = subres.concat(e);
                } else if (_.isObject(e)) {
                    subres = subres.concat(_.values(_.omit(e, _.values(keys))));
                }
            } else if (ch == '{}') {
                if (_.isArray(e[keys.self])) {
                    _.transform(e[keys.self], (res, v, k) => {
                        res.push(utils_create_kv(k, v));
                    }, subres);
                } else if (_.isObject(e[keys.self])) {
                    _.transform(_.omit(e[keys.self], _.values(keys)), (result, v, k) => {
                        result.push(utils_create_kv(k, v));
                    }, subres);
                }
            } else {
                subres.push(e[ch]);
            }
            for (var e2 of subres) {
                res.push(utils_normailze_elem(e2, e));
            }
        }
    }
    return res;
}

function utils_normailze_elem(elem, parent) {
    var root = parent?parent[keys.root] || parent:elem;
    if (!_.isObject(elem)) {
        var tmp = {};
        tmp[keys.self] = elem;
        elem = tmp;
    } else {
        elem[keys.self] = elem;
    }
    elem[keys.parent] = parent;
    elem[keys.root] = root;
    return elem;
}

function utils_parse_recursive(optss, res) {
    if (optss.length === 0)
        return res;
    var more = [];
    if (res === undefined) {
        res = [];
    }
    for (var opts of optss) {
        var tmp = utils_parse_once(opts);
        for (var parsed of tmp) {
            if (parsed.args.length === 0) {
                res.push(parsed);
            } else {
                more.push(parsed);
            }
        }
    }
    return utils_parse_recursive(more, res);
}

function utils_parse_once(opts) {
    var res = [];
    if (opts.args.length === 0)
        return [opts];

    var el = opts.args[0];
    var t;
    switch (el.type) {
        case 'scope':
            var ctxs = utils_parse_scope(opts.ctx, el.arg);
            for (var ctx of ctxs) {
                res.push({
                    'ctx': ctx,
                    'name': opts.name.slice(),
                    'args': opts.args.slice(1),
                });
            }
            break;
        case 'cond':
            t = _.template(el.arg);
            var cond = t(opts.ctx);
            opts.args = opts.args.slice(1);
            if (cond)
                res = [opts];
            break;
        case 'name':
            t = _.template(el.arg);
            var name = t(opts.ctx);
            opts.name.push(name);
            opts.args = opts.args.slice(1);
            res = [opts];
            break;
    }
    return res;
}

function parse_scaf(content, originalname, obj, parentname) {
    var opts = {
        'ctx': obj,
        'name': [],
        'args': [],
    };

    // TODO: fix later, too slow
    var orig = [];
    var lines = content.split('\n');
    for (var line of lines) {
        if (line.startsWith(config.prefix)) {
            line = line.substring(config.prefix.length);
            var tmp = line.split(' ');
            var op = tmp[0];
            var arg = tmp.length > 1?tmp.slice(1).join(' '):'';
            switch (op) {
                case 'scope':
                    opts.args.push({'arg': arg, 'type': 'scope'});
                    break;
                case 'cond':
                    opts.args.push({'arg': arg, 'type': 'cond'});
                    break;
                case 'name':
                    opts.args.push({'arg': arg, 'type': 'name'});
                    break;
            }
        } else {
            orig.push(line);
        }
    }
    return Promise.resolve(opts)
        .then(opts => {
            opts.ctx = utils_normailze_elem(opts.ctx);
            return utils_parse_recursive([opts]);
        })
        .map(opts => {
            var name;
            if (opts.name.length === 0) {
                name = originalname;
            } else {
                opts.name = opts.name.filter(x => x);
                if (opts.name.length === 0) {
                    name = '';
                } else {
                    name = path.join.apply(path, opts.name);
                }
            }
            var wholename = path.join(parentname, name);
            return {
                'ctx': opts.ctx,
                'wholename': wholename,
                'orig': orig.join('\n'),
            };
        });
}

function build_dir(obj, reader, writer, dir, parentname) {
    var scaf = path.join(dir, config.files.scaffile);
    return Promise.resolve(reader.exists(scaf))
        .then(e => {
            if (e) {
                return reader.read(scaf);
            } else {
                return '';
            }
        })
        .then(content => {
            return parse_scaf(content, dir, obj, parentname);
        })
        .map(opts => {
            return Promise.resolve(reader.ls(dir))
                .filter(x => (_.values(config.files).indexOf(x) == -1))
                .map(x => build_recursive(opts.ctx, reader, writer, path.join(dir, x), opts.wholename))
                .reduce((res, f) => {
                    return _.extend(res, f);
                }, {});
        })
        .reduce((res, f) => {
            return _.extend(res, f);
        }, {});
}

var fsreadable = {
    'read': function(file) {
        return fs.readFileAsync(path.join(this.base, file), config.encoding);
    },
    'isdir': function(pa) {
        return fs.statAsync(path.join(this.base,pa)).then(stat => stat.isDirectory());
    },
    'exists': function(pa) {
        return fs.accessAsync(path.join(this.base, pa), fs.constants.F_OK)
            .return(true)
            .catch(() => false);
    },
    'ls': function(dir) {
        return fs.readdirAsync(path.join(this.base, dir));
    },
};
var fswritable = {
    'write': function(file, content) {
        return fs.writeFileAsync(path.join(this.base, file), content, {'encoding': config.encoding});
    },
    'mkdirp': function(dir) {
        return mkdirp(path.join(this.base, dir));
    },
    'init': () => {},
    'commit': () => {},
};

var objreadable = {
    'read': function(file){
        var el = this.ro;
        var p = file.split('/').filter(x => ['', '.'].indexOf(x) === -1);
        for (var e of p) {
            el = el[e];
        }
        return el;
    },
    'isdir': function(pa){
        var el = this.ro;
        var p = pa.split('/').filter(x => ['', '.'].indexOf(x) === -1);
        for (var e of p) {
            el = el[e];
        }
        return _.isObject(el);
    },
    'exists': function(pa){
        var el = this.ro;
        var p = pa.split('/').filter(x => ['', '.'].indexOf(x) === -1);
        for (var e of p) {
            el = el[e];
            if (el === undefined)
                return false;
        }
        return true;
    },
    'ls': function(dir){
        var el = this.ro;
        var p = dir.split('/').filter(x => ['', '.'].indexOf(x) === -1);
        for (var e of p) {
            el = el[e];
        }
        return _.keys(el);
    },
};
var objwritable = {
    'write': function(file, content){
        var el = this.wo;
        var p = file.split('/').filter(x => ['', '.'].indexOf(x) === -1);
        var par = p.slice(0, -1);
        for (var e of par) {
            el = el[e];
        }
        // TODO: raise if it is a dir
        el[p.pop()] = content;
    },
    'mkdirp': function(dir) {
        var el = this.wo;
        var p = dir.split('/').filter(x => ['', '.'].indexOf(x) === -1);
        for (var e of p) {
            if (el[e] === undefined)
                el[e] = {};
            // TODO: raise if a file
            el = el[e];
        }
    },
    'init': () => {},
    'commit': () => {},
};

function build_file(obj, reader, writer, file, parentname) {
    return Promise.resolve(reader.read(file))
        .then(content => {
            return parse_scaf(content, file, obj, parentname);
        })
        .map(opts => {
            var cont = _.template(opts.orig);
            if (files[opts.wholename] === undefined) {
                files[opts.wholename] = file;
            } else {
                throw new ConflictingError(opts.wholename, [files[opts.wholename], file]);
            }
            var wholename = opts.wholename;
            var text = cont(opts.ctx);
            var ret = {};
            var p = !config.dryrun?Promise.resolve(writer.mkdirp(path.dirname(wholename))):Promise.resolve();
            return p.then(_ => {
                    if (!config.dryrun)
                        return writer.write(wholename, text);
                })
                .then(_ => {ret[wholename] = text; })
                .return(ret);
        })
        .reduce((res, f) => {
            return _.extend(res, f);
        }, {});
}

function build(obj, reader, writer, pa, parentname) {
    parentname = parentname || '.';
    pa = pa || '.';
    return Promise.resolve(writer.init())
        .then(_ => reader.exists(pa))
        .then(e => {
            if (e) {
                return build_recursive(obj, reader, writer, pa, parentname);
            } else {
                throw new NotFoundError(pa);
            }
        })
        .then(r => {
            return writer.commit();
        });
}

var ObjReader = function(ro) {
    this.ro = ro || {};
};
ObjReader.prototype = objreadable;
ObjReader.prototype.constructor = ObjReader;

var ObjWriter = function(wo) {
    this.wo = wo || {};
};
ObjWriter.prototype = objwritable;
ObjWriter.prototype.constructor = ObjWriter;

var JsonReader = function(file) {
    this.ro = {};
    this.file = file;
    this.init = () => {
        return fs.readFileAsync(this.file, config.encoding)
            .then(JSON.parse)
            .then(json => {this.ro = json;});
    };
};
JsonReader.prototype = objreadable;
JsonReader.prototype.constructor = JsonReader;

var JsonWriter = function(file) {
    this.wo = {};
    this.file = file || config.files.scafout;
    this.commit = () => {
        return fs.writeFileAsync(this.file, JSON.stringify(this.wo), {'encoding': config.encoding})
            .return(this.wo);
    };
};
JsonWriter.prototype = objwritable;
JsonWriter.prototype.constructor = JsonWriter;

var FsReader = function(base) {
    this.base = base;
};
FsReader.prototype = fsreadable;
FsReader.prototype.constructor = FsReader;

var FsWriter = function(base) {
    this.base = base;
};
FsWriter.prototype = fswritable;
FsWriter.prototype.constructor = FsWriter;

function main(args) {
    var defaultargs = {
        'reader': 'fs',
        'writer': 'json',
        'in': '.',
        'out': config.files.scafout,
        'ctx': config.files.scafctx,
    };
    args = _.extend(defaultargs, args);
    var reader = args.reader === 'json'?new JsonReader(args['in']):new FsReader(args['in']);
    var writer = args.writer === 'json'?new JsonWriter(args.out):new FsWriter(args.out);
    return fs.readFileAsync(args.ctx, config.encoding)
        .then(JSON.parse)
        .then(ctx => build(ctx, reader, writer));
}

module.exports = {
    'config': config,
    'errors': {
        'NotFoundError': NotFoundError,
        'ConflictingError': ConflictingError,
    },
    'readers': {
        'fs': FsReader,
        'json': JsonReader,
        'obj': ObjReader,
    },
    'writers': {
        'fs': FsWriter,
        'json': JsonWriter,
        'obj': ObjWriter,
    },
    'build': build,
    'main': main,
};
<|endoftext|>


<commit_before>/**
 * Copyright 2013-2021 the original author or authors from the JHipster project.
 *
 * This file is part of the JHipster project, see https://www.jhipster.tech/
 * for more information.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/* eslint-disable consistent-return */
const chalk = require('chalk');
const _ = require('lodash');

const BaseBlueprintGenerator = require('../generator-base-blueprint');
const writeFiles = require('./files').writeFiles;
const prettierConfigFiles = require('./files').prettierConfigFiles;
const constants = require('../generator-constants');
const packagejs = require('../../package.json');
const dependabotPackagejs = require('./templates/package.json');
const prompts = require('./prompts');

let useBlueprints;

module.exports = class extends BaseBlueprintGenerator {
  constructor(args, opts) {
    super(args, opts);

    this.option('skip-build', {
      desc: 'Skips building the application',
      type: Boolean,
      defaults: false,
    });
  }

  // Public API method used by the getter and also by Blueprints
  _initializing() {
    return {
      validateFromCli() {
        this.checkInvocationFromCLI();
      },
      sayHello() {
        this.log(chalk.white('⬢ Welcome to the JHipster Init ⬢'));
      },
      getConfig() {
        this.jhipsterVersion = packagejs.version;
        const configuration = this.config;

        this.projectName = configuration.get('projectName');
        this.baseName = configuration.get('baseName');
        this.prettierDefaultIndent = configuration.get('prettierDefaultIndent');
        this.prettierJavaIndent = configuration.get('prettierJavaIndent');

        this.dasherizedBaseName = _.kebabCase(this.baseName);
        this.humanizedBaseName = _.startCase(this.baseName);
        this.dependencies = packagejs.dependencies;
        this.dependabotDependencies = dependabotPackagejs.devDependencies;
      },
      initConstant() {
        this.NODE_VERSION = constants.NODE_VERSION;
      },
    };
  }

  get initializing() {
    if (useBlueprints) return;
    return this._initializing();
  }

  // Public API method used by the getter and also by Blueprints
  _prompting() {
    return {
      askProjectName: prompts.askProjectName,
      askBaseName: prompts.askBaseName,
      askPrettierDefaultIndent: prompts.askPrettierDefaultIndent,
      askPrettierJavaIndent: prompts.askPrettierJavaIndent,
    };
  }

  get prompting() {
    if (useBlueprints) return;
    return this._prompting();
  }

  // Public API method used by the getter and also by Blueprints
  _configuring() {
    return {
      setup() {
        this.jhipsterConfig.jhipsterVersion = packagejs.version;
        this.jhipsterConfig.projectName = this.projectName;
        this.jhipsterConfig.baseName = this.baseName;
        this.jhipsterConfig.prettierDefaultIndent = this.prettierDefaultIndent;
        this.jhipsterConfig.prettierJavaIndent = this.prettierJavaIndent;

        this.dasherizedBaseName = _.kebabCase(this.baseName);
        this.humanizedBaseName = _.startCase(this.baseName);
      },
    };
  }

  get configuring() {
    if (useBlueprints) return;
    return this._configuring();
  }

  _writing() {
    return {
      writePrettierConfig() {
        // Prettier configuration needs to be the first written files - all subgenerators considered - for prettier transform to work
        return this.writeFilesToDisk(prettierConfigFiles);
      },
      ...writeFiles(),
      ...super._missingPostWriting(),
    };
  }

  get writing() {
    if (useBlueprints) return;
    return this._writing();
  }

  // Public API method used by the getter and also by Blueprints
  _install() {
    return {
      // Initialize git repository before package manager install for commit hooks
      initGitRepo() {
        if (!this.options.skipGit) {
          if (this.gitInstalled || this.isGitInstalled()) {
            const gitDir = this.gitExec('rev-parse --is-inside-work-tree', { trace: false }).stdout;
            // gitDir has a line break to remove (at least on windows)
            if (gitDir && gitDir.trim() === 'true') {
              this.gitInitialized = true;
            } else {
              const shellStr = this.gitExec('init', { trace: false });
              this.gitInitialized = shellStr.code === 0;
              if (this.gitInitialized) this.log(chalk.green.bold('Git repository initialized.'));
              else this.warning(`Failed to initialize Git repository.\n ${shellStr.stderr}`);
            }
          } else {
            this.warning('Git repository could not be initialized, as Git is not installed on your system');
          }
        }
      },
    };
  }

  get install() {
    if (useBlueprints) return;
    return this._install();
  }

  _end() {
    return {
      /** Initial commit to git repository after package manager install for package-lock.json */
      gitCommit() {
        if (!this.options.skipGit && this.isGitInstalled()) {
          if (this.gitInitialized) {
            this.debug('Committing files to git');
            const done = this.async();
            this.gitExec('log --oneline -n 1 -- .', { trace: false }, (code, commits) => {
              if (code !== 0 || !commits || !commits.trim()) {
                // if no files in Git from current folder then we assume that this is initial application generation
                this.gitExec('add .', { trace: false }, code => {
                  if (code === 0) {
                    let commitMsg = `Initial version of ${this.jhipsterConfig.baseName} generated by generator-jhipster@${this.jhipsterConfig.jhipsterVersion}`;
                    if (this.jhipsterConfig.blueprints && this.jhipsterConfig.blueprints.length > 0) {
                      const bpInfo = this.jhipsterConfig.blueprints.map(bp => `${bp.name}@${bp.version}`).join(', ');
                      commitMsg += ` with blueprints ${bpInfo}`;
                    }
                    this.gitExec(`commit -m "${commitMsg}" -- .`, { trace: false }, code => {
                      if (code === 0) {
                        this.log(chalk.green.bold(`Application successfully committed to Git from ${process.cwd()}.`));
                      } else {
                        this.log(chalk.red.bold(`Application commit to Git failed from ${process.cwd()}. Try to commit manually.`));
                      }
                      done();
                    });
                  } else {
                    this.warning(
                      `The generated application could not be committed to Git, because ${chalk.bold('git add')} command failed.`
                    );
                    done();
                  }
                });
              } else {
                // if found files in Git from current folder then we assume that this is application regeneration
                // if there are changes in current folder then inform user about manual commit needed
                this.gitExec('diff --name-only .', { trace: false }, (code, diffs) => {
                  if (code === 0 && diffs && diffs.trim()) {
                    this.log(
                      `Found commits in Git from ${process.cwd()}. So we assume this is application regeneration. Therefore automatic Git commit is not done. You can do Git commit manually.`
                    );
                  }
                  done();
                });
              }
            });
          } else {
            this.warning('The generated application could not be committed to Git, as a Git repository could not be initialized.');
          }
        }
      },

      afterRunHook() {
        try {
          const modules = this.getModuleHooks();
          if (modules.length > 0) {
            this.log(`\n${chalk.bold.green('Running post run module hooks\n')}`);
            // run through all post app creation module hooks
            this.callHooks('app', 'post', {
              appConfig: this.configOptions,
              force: this.options.force,
            });
          }
        } catch (err) {
          this.log(`\n${chalk.bold.red('Running post run module hooks failed. No modification done to the generated app.')}`);
          this.debug('Error:', err);
        }
        this.log(
          chalk.green(
            `\nIf you find JHipster useful consider sponsoring the project ${chalk.yellow('https://www.jhipster.tech/sponsors/')}`
          )
        );
      },
    };
  }

  get end() {
    if (useBlueprints) return;
    return this._end();
  }
};
<commit_msg>Replace useBlueprints by this.useBlueprints<commit_after>/**
 * Copyright 2013-2021 the original author or authors from the JHipster project.
 *
 * This file is part of the JHipster project, see https://www.jhipster.tech/
 * for more information.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/* eslint-disable consistent-return */
const chalk = require('chalk');
const _ = require('lodash');

const BaseBlueprintGenerator = require('../generator-base-blueprint');
const writeFiles = require('./files').writeFiles;
const prettierConfigFiles = require('./files').prettierConfigFiles;
const constants = require('../generator-constants');
const packagejs = require('../../package.json');
const dependabotPackagejs = require('./templates/package.json');
const prompts = require('./prompts');

module.exports = class extends BaseBlueprintGenerator {
  constructor(args, opts) {
    super(args, opts);

    this.option('skip-build', {
      desc: 'Skips building the application',
      type: Boolean,
      defaults: false,
    });
  }

  // Public API method used by the getter and also by Blueprints
  _initializing() {
    return {
      validateFromCli() {
        this.checkInvocationFromCLI();
      },
      sayHello() {
        this.log(chalk.white('⬢ Welcome to the JHipster Init ⬢'));
      },
      getConfig() {
        this.jhipsterVersion = packagejs.version;
        const configuration = this.config;

        this.projectName = configuration.get('projectName');
        this.baseName = configuration.get('baseName');
        this.prettierDefaultIndent = configuration.get('prettierDefaultIndent');
        this.prettierJavaIndent = configuration.get('prettierJavaIndent');

        this.dasherizedBaseName = _.kebabCase(this.baseName);
        this.humanizedBaseName = _.startCase(this.baseName);
        this.dependencies = packagejs.dependencies;
        this.dependabotDependencies = dependabotPackagejs.devDependencies;
      },
      initConstant() {
        this.NODE_VERSION = constants.NODE_VERSION;
      },
    };
  }

  get initializing() {
    if (this.useBlueprints) return;
    return this._initializing();
  }

  // Public API method used by the getter and also by Blueprints
  _prompting() {
    return {
      askProjectName: prompts.askProjectName,
      askBaseName: prompts.askBaseName,
      askPrettierDefaultIndent: prompts.askPrettierDefaultIndent,
      askPrettierJavaIndent: prompts.askPrettierJavaIndent,
    };
  }

  get prompting() {
    if (this.useBlueprints) return;
    return this._prompting();
  }

  // Public API method used by the getter and also by Blueprints
  _configuring() {
    return {
      setup() {
        this.jhipsterConfig.jhipsterVersion = packagejs.version;
        this.jhipsterConfig.projectName = this.projectName;
        this.jhipsterConfig.baseName = this.baseName;
        this.jhipsterConfig.prettierDefaultIndent = this.prettierDefaultIndent;
        this.jhipsterConfig.prettierJavaIndent = this.prettierJavaIndent;

        this.dasherizedBaseName = _.kebabCase(this.baseName);
        this.humanizedBaseName = _.startCase(this.baseName);
      },
    };
  }

  get configuring() {
    if (this.useBlueprints) return;
    return this._configuring();
  }

  _writing() {
    return {
      writePrettierConfig() {
        // Prettier configuration needs to be the first written files - all subgenerators considered - for prettier transform to work
        return this.writeFilesToDisk(prettierConfigFiles);
      },
      ...writeFiles(),
      ...super._missingPostWriting(),
    };
  }

  get writing() {
    if (this.useBlueprints) return;
    return this._writing();
  }

  // Public API method used by the getter and also by Blueprints
  _install() {
    return {
      // Initialize git repository before package manager install for commit hooks
      initGitRepo() {
        if (!this.options.skipGit) {
          if (this.gitInstalled || this.isGitInstalled()) {
            const gitDir = this.gitExec('rev-parse --is-inside-work-tree', { trace: false }).stdout;
            // gitDir has a line break to remove (at least on windows)
            if (gitDir && gitDir.trim() === 'true') {
              this.gitInitialized = true;
            } else {
              const shellStr = this.gitExec('init', { trace: false });
              this.gitInitialized = shellStr.code === 0;
              if (this.gitInitialized) this.log(chalk.green.bold('Git repository initialized.'));
              else this.warning(`Failed to initialize Git repository.\n ${shellStr.stderr}`);
            }
          } else {
            this.warning('Git repository could not be initialized, as Git is not installed on your system');
          }
        }
      },
    };
  }

  get install() {
    if (this.useBlueprints) return;
    return this._install();
  }

  _end() {
    return {
      /** Initial commit to git repository after package manager install for package-lock.json */
      gitCommit() {
        if (!this.options.skipGit && this.isGitInstalled()) {
          if (this.gitInitialized) {
            this.debug('Committing files to git');
            const done = this.async();
            this.gitExec('log --oneline -n 1 -- .', { trace: false }, (code, commits) => {
              if (code !== 0 || !commits || !commits.trim()) {
                // if no files in Git from current folder then we assume that this is initial application generation
                this.gitExec('add .', { trace: false }, code => {
                  if (code === 0) {
                    let commitMsg = `Initial version of ${this.jhipsterConfig.baseName} generated by generator-jhipster@${this.jhipsterConfig.jhipsterVersion}`;
                    if (this.jhipsterConfig.blueprints && this.jhipsterConfig.blueprints.length > 0) {
                      const bpInfo = this.jhipsterConfig.blueprints.map(bp => `${bp.name}@${bp.version}`).join(', ');
                      commitMsg += ` with blueprints ${bpInfo}`;
                    }
                    this.gitExec(`commit -m "${commitMsg}" -- .`, { trace: false }, code => {
                      if (code === 0) {
                        this.log(chalk.green.bold(`Application successfully committed to Git from ${process.cwd()}.`));
                      } else {
                        this.log(chalk.red.bold(`Application commit to Git failed from ${process.cwd()}. Try to commit manually.`));
                      }
                      done();
                    });
                  } else {
                    this.warning(
                      `The generated application could not be committed to Git, because ${chalk.bold('git add')} command failed.`
                    );
                    done();
                  }
                });
              } else {
                // if found files in Git from current folder then we assume that this is application regeneration
                // if there are changes in current folder then inform user about manual commit needed
                this.gitExec('diff --name-only .', { trace: false }, (code, diffs) => {
                  if (code === 0 && diffs && diffs.trim()) {
                    this.log(
                      `Found commits in Git from ${process.cwd()}. So we assume this is application regeneration. Therefore automatic Git commit is not done. You can do Git commit manually.`
                    );
                  }
                  done();
                });
              }
            });
          } else {
            this.warning('The generated application could not be committed to Git, as a Git repository could not be initialized.');
          }
        }
      },

      afterRunHook() {
        try {
          const modules = this.getModuleHooks();
          if (modules.length > 0) {
            this.log(`\n${chalk.bold.green('Running post run module hooks\n')}`);
            // run through all post app creation module hooks
            this.callHooks('app', 'post', {
              appConfig: this.configOptions,
              force: this.options.force,
            });
          }
        } catch (err) {
          this.log(`\n${chalk.bold.red('Running post run module hooks failed. No modification done to the generated app.')}`);
          this.debug('Error:', err);
        }
        this.log(
          chalk.green(
            `\nIf you find JHipster useful consider sponsoring the project ${chalk.yellow('https://www.jhipster.tech/sponsors/')}`
          )
        );
      },
    };
  }

  get end() {
    if (this.useBlueprints) return;
    return this._end();
  }
};
<|endoftext|>


<commit_before>var isentiaGameApp = angular.module('isentiaGameApp', ['ui.router']);

//route
isentiaGameApp.config(function($stateProvider, $urlRouterProvider){
	$stateProvider
		.state('home', {
			url: '/',
			views : {
				'content': {
				templateUrl: 'templates/main.html',
				controller: 'MainController'
				}
			}
		});
		$urlRouterProvider.otherwise("/");
})

//controller
isentiaGameApp.controller('MainController', function($scope, $filter, $interval){
	$scope.gameSuccess = false;
	$scope.totalMovesCount = localStorage.getItem("savedGameMoves") ? parseInt(localStorage.getItem("savedGameMoves")) : 0;
	$scope.isDraggable = false;
	$scope.dragElem = null;

	var savedCountdown = localStorage.getItem("savedTimerValue");
	$scope.counter = 0;
	$scope.initialCountdown =   savedCountdown && savedCountdown != 0 ? parseInt(savedCountdown) : 0;
	$scope.showTimer =  savedCountdown && savedCountdown != 0 ? true : false;
	$scope.countdown = $scope.initialCountdown;

	$scope.imageParts = [
	{arrIndex:"01", imgSrc: "img/parts/1.jpg"},
	{arrIndex:"02", imgSrc: "img/parts/2.jpg"},
	{arrIndex:"03", imgSrc: "img/parts/3.jpg"},
	{arrIndex:"04", imgSrc: "img/parts/4.jpg"},
	{arrIndex:"05", imgSrc: "img/parts/5.jpg"},
	{arrIndex:"06", imgSrc: "img/parts/6.jpg"},
	{arrIndex:"07", imgSrc: "img/parts/7.jpg"},
	{arrIndex:"08", imgSrc: "img/parts/8.jpg"},
	{arrIndex:"09", imgSrc: "img/parts/9.jpg"}];

	$scope.colsLength = $scope.imageParts.length;

	$scope.puzzleKey = ["01", "02", "03", "04", "05", "06", "07", "08", "09"];
	$scope.rowsLength = 3;

	$scope.shuffleArray = function (array) {
		for (var i = array.length - 1; i > 0; i--) {
			var j = Math.floor(Math.random() * (i + 1));
			var temp = array[i];
			array[i] = array[j];
			array[j] = temp;
		}
		return array;
	}

	$scope.getSavedArray = function(imgState){
		var imgStateArray = imgState.split(',');
		var returnArray = [];
		for (var i = 0; i < imgStateArray.length; i++){
			var found = $filter('filter')($scope.imageParts, {arrIndex: imgStateArray[i]}, true);
			returnArray.push(found[0]);
		}
		return returnArray;
	}

	var savedImgStates = localStorage.getItem("savedGameState");

	$scope.randomImageParts = savedImgStates && savedImgStates.length > 0 ? $scope.getSavedArray(savedImgStates) : $scope.shuffleArray($scope.imageParts);

	$scope.startGame = function (){
		$scope.isDraggable = true;
		$scope.showTimer = true;
		$scope.startTimer($scope.initialCountdown);
	}
	$scope.isGameOver = function() {
		$scope.totalMovesCount = $scope.totalMovesCount + 1;
		localStorage.setItem("savedGameMoves", $scope.totalMovesCount);

		var cols = document.querySelectorAll('#puzzle li');
		var puzzleArray = [];
		for (var i = 0; i < $scope.colsLength; i++) {
			puzzleArray.push(cols[i].children[0].getAttribute('data-img-index'));
		};

		localStorage.setItem("savedGameState", puzzleArray);

		var originKey = $scope.puzzleKey.join();
		var userKey = puzzleArray.join();

		if (originKey === userKey) {
			$scope.gameSuccess = true;
			localStorage.removeItem("savedGameState");
			localStorage.removeItem("savedGameMoves");
			localStorage.removeItem("savedTimerValue");
			$scope.stopTimer();
			localStorage.setItem("savedTimerValue", 0);
		}
		$scope.$apply();

	};

	$scope.dragStartHandler = function (e) {
		if ($scope.isDraggable == false){
			return false;
		}
		$scope.dragElem = this;
		e.dataTransfer.effectAllowed = 'move';
		e.dataTransfer.setData('text/html', this.innerHTML);
	};

	$scope.dragOverHandler = function (e) {
		e.preventDefault();
		e.stopPropagation();
		e.dataTransfer.dropEffect = 'move';
	};

	$scope.dragLeaveHandler = function (e) {
	};

	$scope.dragDropHandler = function (e) {
		if ($scope.isDraggable == false){
			return false;
		}
		e.preventDefault();
		e.stopPropagation();
		if ($scope.dragElem.innerHTML != this.innerHTML) {
			$scope.dragElem.innerHTML = this.innerHTML;
			this.innerHTML = e.dataTransfer.getData('text/html');
			$scope.isGameOver();
		}

	};

})

//directive
isentiaGameApp.directive('draggable', function () {
  return {
    restrict: 'A',
    link: function (scope, element, attrs) {
	  element[0].addEventListener('dragstart', scope.dragStartHandler, false);
      element[0].addEventListener('dragover', scope.dragOverHandler, false);
      element[0].addEventListener('dragleave', scope.dragLeaveHandler, false);
      element[0].addEventListener('drop', scope.dragDropHandler, false);
    }
  }
});

//filter
isentiaGameApp.filter('secondsToDateTime', [function() {
    return function(seconds) {
        return new Date(1970, 0, 1).setSeconds(seconds);
    };
}])

<commit_msg>timer logic in controller<commit_after>var isentiaGameApp = angular.module('isentiaGameApp', ['ui.router']);

//route
isentiaGameApp.config(function($stateProvider, $urlRouterProvider){
	$stateProvider
		.state('home', {
			url: '/',
			views : {
				'content': {
				templateUrl: 'templates/main.html',
				controller: 'MainController'
				}
			}
		});
		$urlRouterProvider.otherwise("/");
})

//controller
isentiaGameApp.controller('MainController', function($scope, $filter, $interval){
	$scope.gameSuccess = false;
	$scope.totalMovesCount = localStorage.getItem("savedGameMoves") ? parseInt(localStorage.getItem("savedGameMoves")) : 0;
	$scope.isDraggable = false;
	$scope.dragElem = null;

	var savedCountdown = localStorage.getItem("savedTimerValue");
	$scope.counter = 0;
	$scope.initialCountdown =   savedCountdown && savedCountdown != 0 ? parseInt(savedCountdown) : 0;
	$scope.showTimer =  savedCountdown && savedCountdown != 0 ? true : false;
	$scope.countdown = $scope.initialCountdown;

	$scope.imageParts = [
	{arrIndex:"01", imgSrc: "img/parts/1.jpg"},
	{arrIndex:"02", imgSrc: "img/parts/2.jpg"},
	{arrIndex:"03", imgSrc: "img/parts/3.jpg"},
	{arrIndex:"04", imgSrc: "img/parts/4.jpg"},
	{arrIndex:"05", imgSrc: "img/parts/5.jpg"},
	{arrIndex:"06", imgSrc: "img/parts/6.jpg"},
	{arrIndex:"07", imgSrc: "img/parts/7.jpg"},
	{arrIndex:"08", imgSrc: "img/parts/8.jpg"},
	{arrIndex:"09", imgSrc: "img/parts/9.jpg"}];

	$scope.colsLength = $scope.imageParts.length;

	$scope.puzzleKey = ["01", "02", "03", "04", "05", "06", "07", "08", "09"];
	$scope.rowsLength = 3;

	$scope.shuffleArray = function (array) {
		for (var i = array.length - 1; i > 0; i--) {
			var j = Math.floor(Math.random() * (i + 1));
			var temp = array[i];
			array[i] = array[j];
			array[j] = temp;
		}
		return array;
	}

	$scope.getSavedArray = function(imgState){
		var imgStateArray = imgState.split(',');
		var returnArray = [];
		for (var i = 0; i < imgStateArray.length; i++){
			var found = $filter('filter')($scope.imageParts, {arrIndex: imgStateArray[i]}, true);
			returnArray.push(found[0]);
		}
		return returnArray;
	}

	var savedImgStates = localStorage.getItem("savedGameState");

	$scope.randomImageParts = savedImgStates && savedImgStates.length > 0 ? $scope.getSavedArray(savedImgStates) : $scope.shuffleArray($scope.imageParts);

	$scope.startGame = function (){
		$scope.isDraggable = true;
		$scope.showTimer = true;
		$scope.startTimer($scope.initialCountdown);
	}
	$scope.isGameOver = function() {
		$scope.totalMovesCount = $scope.totalMovesCount + 1;
		localStorage.setItem("savedGameMoves", $scope.totalMovesCount);

		var cols = document.querySelectorAll('#puzzle li');
		var puzzleArray = [];
		for (var i = 0; i < $scope.colsLength; i++) {
			puzzleArray.push(cols[i].children[0].getAttribute('data-img-index'));
		};

		localStorage.setItem("savedGameState", puzzleArray);

		var originKey = $scope.puzzleKey.join();
		var userKey = puzzleArray.join();

		if (originKey === userKey) {
			$scope.gameSuccess = true;
			localStorage.removeItem("savedGameState");
			localStorage.removeItem("savedGameMoves");
			localStorage.removeItem("savedTimerValue");
			$scope.stopTimer();
			localStorage.setItem("savedTimerValue", 0);
		}
		$scope.$apply();

	};

	$scope.startTimer = function(initialCountdown){
		var startTime = new Date();
		intervalId = $interval(function(){
			var actualTime = new Date();
			$scope.counter = Math.floor((actualTime - startTime) / 1000);
				$scope.countdown = initialCountdown + $scope.counter;
				localStorage.setItem("savedTimerValue", $scope.countdown);
		}, 1000);
	};
	$scope.stopTimer = function(){
		$interval.cancel(intervalId);
	};

	$scope.dragStartHandler = function (e) {
		if ($scope.isDraggable == false){
			return false;
		}
		$scope.dragElem = this;
		e.dataTransfer.effectAllowed = 'move';
		e.dataTransfer.setData('text/html', this.innerHTML);
	};

	$scope.dragOverHandler = function (e) {
		e.preventDefault();
		e.stopPropagation();
		e.dataTransfer.dropEffect = 'move';
	};

	$scope.dragLeaveHandler = function (e) {
	};

	$scope.dragDropHandler = function (e) {
		if ($scope.isDraggable == false){
			return false;
		}
		e.preventDefault();
		e.stopPropagation();
		if ($scope.dragElem.innerHTML != this.innerHTML) {
			$scope.dragElem.innerHTML = this.innerHTML;
			this.innerHTML = e.dataTransfer.getData('text/html');
			$scope.isGameOver();
		}

	};

})

//directive
isentiaGameApp.directive('draggable', function () {
  return {
    restrict: 'A',
    link: function (scope, element, attrs) {
	  element[0].addEventListener('dragstart', scope.dragStartHandler, false);
      element[0].addEventListener('dragover', scope.dragOverHandler, false);
      element[0].addEventListener('dragleave', scope.dragLeaveHandler, false);
      element[0].addEventListener('drop', scope.dragDropHandler, false);
    }
  }
});

//filter
isentiaGameApp.filter('secondsToDateTime', [function() {
    return function(seconds) {
        return new Date(1970, 0, 1).setSeconds(seconds);
    };
}])

<|endoftext|>


<commit_before>/**
 * @module ogs.vgl
 */

/**
 * Create a new instance of class camera
 *
 * @class
 * @returns {vglModule.camera}
 */
vglModule.camera = function() {

  if (!(this instanceof vglModule.camera)) {
    return new vglModule.camera();
  }
  vglModule.groupNode.call(this);

  /** @private */
  var m_viewAngle = 30;

  /** @private */
  var m_position = vec3.create([ 0.0, 0.0, 0.0 ]);

  /** @private */
  var m_focalPoint = vec3.create([ 0.0, 0.0, -5.0 ]);

  /** @private */
  var m_centerOrRotation = vec3.create([ 0.0, 0.0, 0.0 ]);

  /** @private */
  var m_viewUp = vec3.create([ 0.0, 1.0, 0.0 ]);

  /** @private */
  var m_right = vec3.create([ 1.0, 0.0, 0.0 ]);

  /** @private */
  var m_near = 0.1;

  /** @private */
  var m_far = 10000.0;

  /** @private */
  var m_viewAspect = 1.0;

  /** @private */
  var m_directionOfProjection = vec3.createFrom(0.0, 0.0, -1.0);

  /** @private */
  var m_viewMatrix = mat4.create();

  /** @private */
  var m_projectionMatrix = mat4.create();

  /** @private */
  var m_computeModelViewMatrixTime = ogs.vgl.timestamp();

  /** @private */
  var m_computeProjectMatrixTime = ogs.vgl.timestamp();

  /**
   * Set position of the camera
   */
  this.setPosition = function(x, y, z) {
    m_position = vec3.create([ x, y, z ]);
    this.modified();
  };

  /**
   * Get position of the camera
   */
  this.position = function() {
    return m_position;
  };

  /**
   * Set focal point of the camera
   */
  this.setFocalPoint = function(x, y, z) {
    m_focalPoint = vec3.create([ x, y, z ]);
    this.modified();
  };

  /**
   * Get focal point of the camera
   */
  this.focalPoint = function() {
    return m_focalPoint;
  };

  /**
   * Set view-up direction of the camera
   */
  this.setViewUpDirection = function(x, y, z) {
    m_viewUp = vec3.create([ x, y, z ]);
    this.modified();
  };

  /**
   * Get clipping range of the camera
   */
  this.getClippingRange = function() {
    return [m_near, m_far];
  }

  /**
   * Set clipping range of the camera
   */
  this.setClippingRange = function(near, far) {
    m_near = near;
    m_far = far;
    this.modified();
  }

  /**
   * Get view aspect
   */
  this.viewAspect = function() {
    return m_viewAspect;
  };

  /**
   * Set view aspect
   */
  this.setViewAspect = function(aspect) {
    m_viewAspect = aspect;
    this.modified();
  };

  /**
   *
   */
  this.computeDirectionOfProjection = function() {
    vec3.subtract(m_focalPoint, m_position, m_directionOfProjection);
    vec3.normalize(m_directionOfProjection);
  }

  /**
   * Move camera closer or further away from the scene
   */
  this.zoom = function(dz) {
    // Since our direction vector is changed, we need to first
    // calculate this new direction
    var lastPosition = vec3.createFrom(m_position[0], m_position[1],
                                       m_position[2]);

    var deltaX = m_directionOfProjection[0] * dz;
    var deltaY = m_directionOfProjection[1] * dz;
    var deltaZ = m_directionOfProjection[2] * dz;

    m_position[0] += deltaX;
    m_position[1] += deltaY;
    m_position[2] += deltaZ;

    this.modified();
    // TODO: If the distance between focal point and the camera position
    // goes really low then we run into issues
  };

  /**
   * Move camera sideways
   */
  this.pan = function(dx, dy, dz) {
    m_position[0] += dx;
    m_position[1] += dy;
    m_position[2] += dz;

    m_focalPoint[0] += dx;
    m_focalPoint[1] += dy
    m_focalPoint[2] += dz;

    this.modified();
  };

  /**
   * Compute camera coordinate axes
   */
  this.computeOrthogonalAxes = function() {
    var mat = this.computeViewMatrix();
    m_viewUp[0] = mat[4];
    m_viewUp[1] = mat[5];
    m_viewUp[2] = mat[6];

    m_right[0] = mat[0];
    m_right[1] = mat[1];
    m_right[2] = mat[2];
  };

  /**
   * Rotate camera around center of rotation
   * @param dx Rotation around vertical axis in degrees
   * @param dy Rotation around horizontal axis in degrees
   */
  this.rotate = function(dx, dy) {
    dx = dx * (3.14 / 180.0)
    dy = dy * (3.14 / 180.0)

    var mat = mat4.create();
    mat4.identity(mat);

    var invtrans = new vec3.create();
    invtrans[0] = -m_centerOrRotation[0];
    invtrans[1] = -m_centerOrRotation[1];
    invtrans[2] = -m_centerOrRotation[2];

    mat4.translate(mat, m_centerOrRotation, mat);
    mat4.rotate(mat, dx, m_viewUp, mat);
    mat4.rotate(mat, dy, m_right, mat);
    mat4.translate(mat, invtrans, mat);

    mat4.multiplyVec3(mat, m_position, m_position);
    mat4.multiplyVec3(mat, m_focalPoint, m_focalPoint);

    mat4.identity(mat);
    mat4.rotate(mat, dx, m_viewUp, mat);
    mat4.multiplyVec3(mat, m_right);
    vec3.normalize(m_right);

    mat4.identity(mat);
    mat4.rotate(mat, dy, m_right, mat);
    mat4.multiplyVec3(mat, m_viewUp);
    vec3.normalize(m_viewUp);

    this.computeDirectionOfProjection();

    this.modified();
  }

  /**
   * Compute camera view matrix
   */
  this.computeViewMatrix = function() {
    if (m_computeModelViewMatrixTime.getMTime() < this.getMTime()) {
      mat4.lookAt(m_position, m_focalPoint, m_viewUp, m_viewMatrix);
      m_computeModelViewMatrixTime.modified();
    }
    return m_viewMatrix;
  };

  /**
   * Return view-matrix for the camera This method does not compute the
   * view-matrix for the camera. It is assumed that a call to computeViewMatrix
   * has been made earlier.
   *
   * @returns {mat4}
   */
  this.viewMatrix = function() {
    return this.computeViewMatrix();
  };

  /**
   * Compute camera projection matrix
   */
  this.computeProjectionMatrix = function() {
    if (m_computeProjectMatrixTime.getMTime() < this.getMTime()) {
      mat4.identity(m_projectionMatrix);
      mat4.perspective(m_viewAngle, m_viewAspect, m_near, m_far, m_projectionMatrix);
      m_computeProjectMatrixTime.modified();
    }

    return m_projectionMatrix;
  };

  /**
   * Return camera projection matrix This method does not compute the
   * projection-matrix for the camera. It is assumed that a call to
   * computeProjectionMatrix has been made earlier.
   *
   * @returns {mat4}
   */
  this.projectionMatrix = function() {
    return this.computeProjectionMatrix();
  };

  return this;
};

inherit(vglModule.camera, vglModule.groupNode);
<commit_msg>Added notes<commit_after>/**
 * @module ogs.vgl
 */

/**
 * Create a new instance of class camera
 *
 * @class
 * @returns {vglModule.camera}
 */
vglModule.camera = function() {

  if (!(this instanceof vglModule.camera)) {
    return new vglModule.camera();
  }
  vglModule.groupNode.call(this);

  /** @private */
  var m_viewAngle = 30;

  /** @private */
  var m_position = vec3.create([ 0.0, 0.0, 0.0 ]);

  /** @private */
  var m_focalPoint = vec3.create([ 0.0, 0.0, -5.0 ]);

  /** @private */
  var m_centerOrRotation = vec3.create([ 0.0, 0.0, 0.0 ]);

  /** @private */
  var m_viewUp = vec3.create([ 0.0, 1.0, 0.0 ]);

  /** @private */
  var m_right = vec3.create([ 1.0, 0.0, 0.0 ]);

  /** @private */
  var m_near = 0.1;

  /** @private */
  var m_far = 10000.0;

  /** @private */
  var m_viewAspect = 1.0;

  /** @private */
  var m_directionOfProjection = vec3.createFrom(0.0, 0.0, -1.0);

  /** @private */
  var m_viewMatrix = mat4.create();

  /** @private */
  var m_projectionMatrix = mat4.create();

  /** @private */
  var m_computeModelViewMatrixTime = ogs.vgl.timestamp();

  /** @private */
  var m_computeProjectMatrixTime = ogs.vgl.timestamp();

  /**
   * Set position of the camera
   */
  this.setPosition = function(x, y, z) {
    m_position = vec3.create([ x, y, z ]);
    this.modified();
  };

  /**
   * Get position of the camera
   */
  this.position = function() {
    return m_position;
  };

  /**
   * Set focal point of the camera
   */
  this.setFocalPoint = function(x, y, z) {
    m_focalPoint = vec3.create([ x, y, z ]);
    this.modified();
  };

  /**
   * Get focal point of the camera
   */
  this.focalPoint = function() {
    return m_focalPoint;
  };

  /**
   * Set view-up direction of the camera
   */
  this.setViewUpDirection = function(x, y, z) {
    m_viewUp = vec3.create([ x, y, z ]);
    this.modified();
  };

  /**
   * Get clipping range of the camera
   */
  this.getClippingRange = function() {
    return [m_near, m_far];
  }

  /**
   * Set clipping range of the camera
   */
  this.setClippingRange = function(near, far) {
    m_near = near;
    m_far = far;
    this.modified();
  }

  /**
   * Get view aspect
   */
  this.viewAspect = function() {
    return m_viewAspect;
  };

  /**
   * Set view aspect
   */
  this.setViewAspect = function(aspect) {
    m_viewAspect = aspect;
    this.modified();
  };

  /**
   *
   */
  this.computeDirectionOfProjection = function() {
    vec3.subtract(m_focalPoint, m_position, m_directionOfProjection);
    vec3.normalize(m_directionOfProjection);
  }

  /**
   * Move camera closer or further away from the scene
   */
  this.zoom = function(dz) {
    // Since our direction vector is changed, we need to first
    // calculate this new direction
    var lastPosition = vec3.createFrom(m_position[0], m_position[1],
                                       m_position[2]);

    var deltaX = m_directionOfProjection[0] * dz;
    var deltaY = m_directionOfProjection[1] * dz;
    var deltaZ = m_directionOfProjection[2] * dz;

    m_position[0] += deltaX;
    m_position[1] += deltaY;
    m_position[2] += deltaZ;

    this.modified();
    // TODO: If the distance between focal point and the camera position
    // goes really low then we run into issues
  };

  /**
   * Move camera sideways
   */
  this.pan = function(dx, dy, dz) {
    m_position[0] += dx;
    m_position[1] += dy;
    m_position[2] += dz;

    m_focalPoint[0] += dx;
    m_focalPoint[1] += dy
    m_focalPoint[2] += dz;

    this.modified();
  };

  /**
   * Compute camera coordinate axes
   */
  this.computeOrthogonalAxes = function() {
    var mat = this.computeViewMatrix();
    m_viewUp[0] = mat[4];
    m_viewUp[1] = mat[5];
    m_viewUp[2] = mat[6];

    m_right[0] = mat[0];
    m_right[1] = mat[1];
    m_right[2] = mat[2];
  };

  /**
   * Rotate camera around center of rotation
   * @param dx Rotation around vertical axis in degrees
   * @param dy Rotation around horizontal axis in degrees
   */
  this.rotate = function(dx, dy) {
    dx = dx * (3.14 / 180.0)
    dy = dy * (3.14 / 180.0)

    var mat = mat4.create();
    mat4.identity(mat);

    var invtrans = new vec3.create();
    invtrans[0] = -m_centerOrRotation[0];
    invtrans[1] = -m_centerOrRotation[1];
    invtrans[2] = -m_centerOrRotation[2];

    mat4.translate(mat, m_centerOrRotation, mat);
    mat4.rotate(mat, dx, m_viewUp, mat);
    mat4.rotate(mat, dy, m_right, mat);
    mat4.translate(mat, invtrans, mat);

    mat4.multiplyVec3(mat, m_position, m_position);
    mat4.multiplyVec3(mat, m_focalPoint, m_focalPoint);

    // Update view up vector
    mat4.identity(mat);
    mat4.rotate(mat, dx, m_viewUp, mat);
    mat4.multiplyVec3(mat, m_right);
    vec3.normalize(m_right);

    // Update right vector
    mat4.identity(mat);
    mat4.rotate(mat, dy, m_right, mat);
    mat4.multiplyVec3(mat, m_viewUp);
    vec3.normalize(m_viewUp);

    this.computeDirectionOfProjection();

    this.modified();
  }

  /**
   * Compute camera view matrix
   */
  this.computeViewMatrix = function() {
    if (m_computeModelViewMatrixTime.getMTime() < this.getMTime()) {
      mat4.lookAt(m_position, m_focalPoint, m_viewUp, m_viewMatrix);
      m_computeModelViewMatrixTime.modified();
    }
    return m_viewMatrix;
  };

  /**
   * Return view-matrix for the camera This method does not compute the
   * view-matrix for the camera. It is assumed that a call to computeViewMatrix
   * has been made earlier.
   *
   * @returns {mat4}
   */
  this.viewMatrix = function() {
    return this.computeViewMatrix();
  };

  /**
   * Compute camera projection matrix
   */
  this.computeProjectionMatrix = function() {
    if (m_computeProjectMatrixTime.getMTime() < this.getMTime()) {
      mat4.identity(m_projectionMatrix);
      mat4.perspective(m_viewAngle, m_viewAspect, m_near, m_far, m_projectionMatrix);
      m_computeProjectMatrixTime.modified();
    }

    return m_projectionMatrix;
  };

  /**
   * Return camera projection matrix This method does not compute the
   * projection-matrix for the camera. It is assumed that a call to
   * computeProjectionMatrix has been made earlier.
   *
   * @returns {mat4}
   */
  this.projectionMatrix = function() {
    return this.computeProjectionMatrix();
  };

  return this;
};

inherit(vglModule.camera, vglModule.groupNode);
<|endoftext|>


<commit_before><commit_msg>Showing shovel only when it is player's turn.<commit_after><|endoftext|>


<commit_before>/**
 * Created with JetBrains WebStorm.
 * User: mschwartz
 * Date: 6/7/13
 * Time: 5:05 PM
 */
/*
 * CommonJS require 1.1 implementation
 */

/*global require, builtin */

(function() {
    var rhino = builtin.rhino,
        File = java.io.File
        FileInputStream = java.io.FileInputStream,
        BufferedInputStream = java.io.BufferedInputStream,
        ByteArrayOutputStream = java.io.ByteArrayOutputStream;

    /**
     * @private
     */

    // thanks to ringojs for this one
    function resolveFile( path ) {
        var file = path instanceof File ? path : new File(String(path));
        return file.isAbsolute() ? file : file.getAbsoluteFile();
    }

    var fs = {
        isFile : function( path ) {
            var file = resolveFile(path);
            return file.isFile();
        },

        isDir : function( path ) {
            var file = resolveFile(path);
            return file.isDirectory();
        },

        realpath : function( path ) {
            var file = resolveFile(path);
            return file.exists() ? String(file.getCanonicalPath()) : false;
        },

        readFile : function( path ) {
            var file = resolveFile(path),
                body = new ByteArrayOutputStream(),
                stream = new BufferedInputStream(new FileInputStream(file)),
                buf = java.lang.reflect.Array.newInstance(java.lang.Byte.TYPE, 1024),
                count;

            while ( (count = stream.read(buf)) > -1 ) {
                body.write(buf, 0, count);
            }
            stream.close();
            return String(body.toString());
        }
    };

    function realpath(path) {
        var f = new File(path);
        return String(f.getAbsolutePath().toString());
    }

    function locateFile(module) {
        var extension,
            pkg;

        function tryFile(path) {
            var tryPath = fs.realpath(path);
            if (tryPath) {
                if (fs.isFile(tryPath)) {
                    return tryPath;
                }
                else if (fs.isDir(tryPath)) {
                    if (!tryPath.endsWith('/')) {
                        tryPath += '/';
                    }
                    tryPath += 'index.js';
                }
                if (fs.isFile(tryPath)) {
                    return tryPath;
                }
                tryPath = tryPath.replace(/index.js$/, 'bower.json');
                if (fs.isFile(tryPath)) {
                    try {
                        pkg = JSON.parse(fs.readFile(tryPath));
                        if (decaf.isString(pkg.main)) {
                            tryPath = tryPath.replace(/bower.json$/, pkg.main);
                            if (fs.isFile(tryPath)) {
                                return tryPath;
                            }
                        }
                    }
                    catch (e) {
                    }
                }
                tryPath = tryPath.replace(/bower.json$/, 'package.json');
                if (fs.isFile(tryPath)) {
                    try {
                        pkg = JSON.parse(fs.readFile(tryPath));
                        if (decaf.isString(pkg.main)) {
                            tryPath = tryPath.replace(/package.json$/, pkg.main);
                            if (fs.isFile(tryPath)) {
                                return tryPath;
                            }
                        }
                    }
                    catch (e) {
                    }
                }
            }
            tryPath = fs.realpath(require.fsPath + path);
            if (tryPath) {
                if (fs.isFile(tryPath)) {
                    return tryPath;
                }
                if (fs.isDir(tryPath)) {
                    if (!tryPath.endsWith('/')) {
                        tryPath += '/';
                    }
                    tryPath += 'index.js';
                    if (fs.isFile(tryPath)) {
                        return tryPath;
                    }
                    tryPath = tryPath.replace(/index.js$/, 'bower.json');
                    if (fs.isFile(tryPath)) {
                        try {
                            pkg = JSON.parse(fs.readFile(tryPath));
                            if (decaf.isString(pkg.main)) {
                                tryPath = tryPath.replace(/bower.json$/, pkg.main);
                                if (fs.isFile(tryPath)) {
                                    return tryPath;
                                }
                            }
                        }
                        catch (e) {
                        }
                    }
                    tryPath = tryPath.replace(/bower.json$/, 'package.json');
                    if (fs.isFile(tryPath)) {
                        try {
                            pkg = JSON.parse(fs.readFile(tryPath));
                            if (decaf.isString(pkg.main)) {
                                tryPath = tryPath.replace(/package.json$/, pkg.main);
                                if (fs.isFile(tryPath)) {
                                    return tryPath;
                                }
                            }
                        }
                        catch (e) {
                        }
                    }
                }
            }
            return false;
        }

        var found;
        if (module[0] === '/' || module.substr(0, 2) === './' || module.substr(0, 3) === '../' || module === '..') {
            var relpath = module[0] === '/' ? module : realpath(require.fsPath + module);
            found = tryFile(relpath) || tryFile(relpath + '.js');
            if (found) {
                return found;
            }
            for (extension in require.extensions) {
                found = tryFile(module + '.' + extension);
                if (found) {
                    return found;
                }
            }
        }
        else {
            var paths = require.paths;
            for (var i = 0, len = paths.length; i < len; i++) {
                var path = paths[i];
                if (path.substr(path.length - 1, 1) != '/') {
                    path += '/';
                }
                path += module;
                found = tryFile(path) || tryFile(path + '.js');
                if (found) {
                    return found;
                }
                for (extension in require.extensions) {
                    found = tryFile(path + '.' + extension);
                    if (found) {
                        return found;
                    }
                }
            }
        }
        throw new Error('Could not locate require file ' + module);
    }

    function loadFile(modulePath) {
        var contents = fs.readFile(modulePath);
        var extension = modulePath.indexOf('.') !== -1 ? modulePath.substr(modulePath.lastIndexOf('.')+1) : '';

        if (require.extensions[extension]) {
            contents = require.extensions[extension](contents, modulePath);
        }
        return contents;
    }

    /**
     * @global
     * @param module
     * @returns {*}
     */
    global.require = function(module) {
        if (module.substr(0, 8) === 'builtin/' || module.substr(0, 8) === 'builtin.') {
            return builtin[module.substr(8)];
        }
        var modulePath = locateFile(module);
        if (require.cache[modulePath]) {
            return require.cache[modulePath].exports;
        }
        var content = loadFile(modulePath);
        require.dirStack.push(require.fsPath);
        var fsPath = modulePath.split('/');
        fsPath.pop();
        require.fsPath = fsPath.join('/') + '/';

        // works
//        var exports = require.cache[modulePath] = {};
//        var script = [
//            '(function() {',
//            '	var exports = {}', //  module.exports;',
//            '	var module = {',
//            '		id: "' + module + '",',
//            '       fsPath: "' + require.fsPath + '",',
//            '		url: "' + modulePath + '",',
//            '       exports: null',
//            '	};',
//            content,
//            '	return module.exports || exports;',
//            '}())'
//        ].join('\n');
//        require.modulePath = modulePath;
//        require.cache[modulePath] = rhino.runScript(script, modulePath, 0);

        var exports = require.cache[modulePath] = {
            id: module,
            url: modulePath,
            exports: {}
        };

        var script = [
            '(function() {',
            '   var module = global.require.getCached("' + modulePath + '");',
            '   var exports = module.exports;',
            content,
            '	return module.exports;',
            '}())'
        ].join('\n');
        require.modulePath = modulePath;

        rhino.runScript(script, modulePath, 0, global);

        require.fsPath = require.dirStack.pop();
        require.modulePath = null;
        return require.cache[modulePath].exports;
    };

    require.getCached = function(path) {
        return require.cache[path];
    };

    require.isRequiredFile = function(fn) {
        return require.modulePath === fn || (require.cache[fn] ? true : false);
    };

    require.main = this;
    require.dirStack = [];
    require.fsPath = '';
    require.cache = {};

    /**
     * @memberOf global.require
     * @type {Array}
     */
    require.paths = [
        'bower_components',
        'bower_components/decaf/modules',
        'node_modules',
        'modules',
        '/usr/local/decaf',
        '/usr/local/decaf/modules',
        './'
    ];

    /**
     *  An object used to extend the way [require][#require] loads modules.
     *
     *  Use a file extension as key and a function as value. The function should
     *  accept a `Resource` object as argument and return either a string to be
     *  used as JavaScript module source or an object which will be directly
     *  returned by `require`.
     *
     *  For example, the following one-liner will enable `require()` to load .hbs
     *  files as HoganJS templates:
     *
     *     require.extensions['.hbs'] = function(r) { return Hogan.compile(new File(r).readAll()); }
     *
     * @memberOf global.require
     */
    require.extensions = {};

}());
<commit_msg>require remember content<commit_after>/**
 * Created with JetBrains WebStorm.
 * User: mschwartz
 * Date: 6/7/13
 * Time: 5:05 PM
 */
/*
 * CommonJS require 1.1 implementation
 */

/*global require, builtin */

(function() {
    var rhino = builtin.rhino,
        File = java.io.File,
        FileInputStream = java.io.FileInputStream,
        BufferedInputStream = java.io.BufferedInputStream,
        ByteArrayOutputStream = java.io.ByteArrayOutputStream;

    /**
     * @private
     */

        // thanks to ringojs for this one
    function resolveFile( path ) {
        var file = path instanceof File ? path : new File(String(path));
        return file.isAbsolute() ? file : file.getAbsoluteFile();
    }

    var fs = {
        isFile : function( path ) {
            var file = resolveFile(path);
            return file.isFile();
        },

        isDir : function( path ) {
            var file = resolveFile(path);
            return file.isDirectory();
        },

        realpath : function( path ) {
            var file = resolveFile(path);
            return file.exists() ? String(file.getCanonicalPath()) : false;
        },

        readFile : function( path ) {
            var file = resolveFile(path),
                body = new ByteArrayOutputStream(),
                stream = new BufferedInputStream(new FileInputStream(file)),
                buf = java.lang.reflect.Array.newInstance(java.lang.Byte.TYPE, 1024),
                count;

            while ((count = stream.read(buf)) > -1) {
                body.write(buf, 0, count);
            }
            stream.close();
            return String(body.toString());
        }
    };

    function realpath( path ) {
        var f = new File(path);
        return String(f.getAbsolutePath().toString());
    }

    function locateFile( module ) {
        var extension,
            pkg;

        function tryFile( path ) {
            var tryPath = fs.realpath(path);
            if (tryPath) {
                if (fs.isFile(tryPath)) {
                    return tryPath;
                }
                else if (fs.isDir(tryPath)) {
                    if (!tryPath.endsWith('/')) {
                        tryPath += '/';
                    }
                    tryPath += 'index.js';
                }
                if (fs.isFile(tryPath)) {
                    return tryPath;
                }
                tryPath = tryPath.replace(/index.js$/, 'bower.json');
                if (fs.isFile(tryPath)) {
                    try {
                        pkg = JSON.parse(fs.readFile(tryPath));
                        if (decaf.isString(pkg.main)) {
                            tryPath = tryPath.replace(/bower.json$/, pkg.main);
                            if (fs.isFile(tryPath)) {
                                return tryPath;
                            }
                        }
                    }
                    catch (e) {
                    }
                }
                tryPath = tryPath.replace(/bower.json$/, 'package.json');
                if (fs.isFile(tryPath)) {
                    try {
                        pkg = JSON.parse(fs.readFile(tryPath));
                        if (decaf.isString(pkg.main)) {
                            tryPath = tryPath.replace(/package.json$/, pkg.main);
                            if (fs.isFile(tryPath)) {
                                return tryPath;
                            }
                        }
                    }
                    catch (e) {
                    }
                }
            }
            tryPath = fs.realpath(require.fsPath + path);
            if (tryPath) {
                if (fs.isFile(tryPath)) {
                    return tryPath;
                }
                if (fs.isDir(tryPath)) {
                    if (!tryPath.endsWith('/')) {
                        tryPath += '/';
                    }
                    tryPath += 'index.js';
                    if (fs.isFile(tryPath)) {
                        return tryPath;
                    }
                    tryPath = tryPath.replace(/index.js$/, 'bower.json');
                    if (fs.isFile(tryPath)) {
                        try {
                            pkg = JSON.parse(fs.readFile(tryPath));
                            if (decaf.isString(pkg.main)) {
                                tryPath = tryPath.replace(/bower.json$/, pkg.main);
                                if (fs.isFile(tryPath)) {
                                    return tryPath;
                                }
                            }
                        }
                        catch (e) {
                        }
                    }
                    tryPath = tryPath.replace(/bower.json$/, 'package.json');
                    if (fs.isFile(tryPath)) {
                        try {
                            pkg = JSON.parse(fs.readFile(tryPath));
                            if (decaf.isString(pkg.main)) {
                                tryPath = tryPath.replace(/package.json$/, pkg.main);
                                if (fs.isFile(tryPath)) {
                                    return tryPath;
                                }
                            }
                        }
                        catch (e) {
                        }
                    }
                }
            }
            return false;
        }

        var found;
        if (module[0] === '/' || module.substr(0, 2) === './' || module.substr(0, 3) === '../' || module === '..') {
            var relpath = module[0] === '/' ? module : realpath(require.fsPath + module);
            found = tryFile(relpath) || tryFile(relpath + '.js');
            if (found) {
                return found;
            }
            for (extension in require.extensions) {
                found = tryFile(module + '.' + extension);
                if (found) {
                    return found;
                }
            }
        }
        else {
            var paths = require.paths;
            for (var i = 0, len = paths.length; i < len; i++) {
                var path = paths[i];
                if (path.substr(path.length - 1, 1) != '/') {
                    path += '/';
                }
                path += module;
                found = tryFile(path) || tryFile(path + '.js');
                if (found) {
                    return found;
                }
                for (extension in require.extensions) {
                    found = tryFile(path + '.' + extension);
                    if (found) {
                        return found;
                    }
                }
            }
        }
        throw new Error('Could not locate require file ' + module);
    }

    function loadFile( modulePath ) {
        var contents = fs.readFile(modulePath);
        var extension = modulePath.indexOf('.') !== -1 ? modulePath.substr(modulePath.lastIndexOf('.') + 1) : '';

        if (require.extensions[extension]) {
            contents = require.extensions[extension](contents, modulePath);
        }
        return contents;
    }

    /**
     * @global
     * @param module
     * @returns {*}
     */
    global.require = function( module ) {
        if (module.substr(0, 8) === 'builtin/' || module.substr(0, 8) === 'builtin.') {
            return builtin[module.substr(8)];
        }
        var modulePath = locateFile(module);
        if (require.cache[modulePath]) {
            return require.cache[modulePath].exports;
        }
        var content = loadFile(modulePath);
        require.dirStack.push(require.fsPath);
        var fsPath = modulePath.split('/');
        fsPath.pop();
        require.fsPath = fsPath.join('/') + '/';

        // works
//        var exports = require.cache[modulePath] = {};
//        var script = [
//            '(function() {',
//            '	var exports = {}', //  module.exports;',
//            '	var module = {',
//            '		id: "' + module + '",',
//            '       fsPath: "' + require.fsPath + '",',
//            '		url: "' + modulePath + '",',
//            '       exports: null',
//            '	};',
//            content,
//            '	return module.exports || exports;',
//            '}())'
//        ].join('\n');
//        require.modulePath = modulePath;
//        require.cache[modulePath] = rhino.runScript(script, modulePath, 0);

        var exports = require.cache[modulePath] = {
            id      : module,
            url     : modulePath,
            content : content,
            exports : {}
        };

        var script = [
            '(function() {',
            '   var module = global.require.getCached("' + modulePath + '");',
            '   var exports = module.exports;',
            content,
            '   return module.exports;',
            '}())'
        ].join('\n');
        require.modulePath = modulePath;

        rhino.runScript(script, modulePath, 0, global);

        require.fsPath = require.dirStack.pop();
        require.modulePath = null;
        return require.cache[modulePath].exports;
    };

    require.getCached = function( path ) {
        return require.cache[path];
    };

    require.getContent = function(path) {
        var modulePath = locateFile(module);
        require(modulePath);
        if (!require.cache[modulePath]) {
            throw new Error("Can't get content for " + module + ' (' + modulePath + ')');
        }
        return require.cache[modulePath];
    };

    require.isRequiredFile = function( fn ) {
        return require.modulePath === fn || (require.cache[fn] ? true : false);
    };

    require.main = this;
    require.dirStack = [];
    require.fsPath = '';
    require.cache = {};

    /**
     * @memberOf global.require
     * @type {Array}
     */
    require.paths = [
        'bower_components',
        'bower_components/decaf/modules',
        'node_modules',
        'modules',
        '/usr/local/decaf',
        '/usr/local/decaf/modules',
        './'
    ];

    /**
     *  An object used to extend the way [require][#require] loads modules.
     *
     *  Use a file extension as key and a function as value. The function should
     *  accept a `Resource` object as argument and return either a string to be
     *  used as JavaScript module source or an object which will be directly
     *  returned by `require`.
     *
     *  For example, the following one-liner will enable `require()` to load .hbs
     *  files as HoganJS templates:
     *
     *     require.extensions['.hbs'] = function(r) { return Hogan.compile(new File(r).readAll()); }
     *
     * @memberOf global.require
     */
    require.extensions = {};

}());
<|endoftext|>