<commit_before>var $json = [{
        'link': 'http://data.gov.tw/wise_search?nodetype=metadataset',
        'img': '',
        'figcaption': 'Government',
        'tag': ['layout', 'blog'],
        'note': 'connect api',
        'points': ['project', 'layout'],
        'ref': 'WiSe search'
    }, {
        'link': './layout/bandWebsite/bandWebsite.html',
        'img': './layout/bandWebsite/bandWebsite.jpg',
        'figcaption': 'Band Website',
        'tag': ['layout', 'blog'],
        'note': 'design the page with photoshop, and praceice psd to layout',
        'points': ['photoshop', 'layout'],
        'ref': 'six reversion'
    }, {
        'link': './layout/letterpress/letterpress.html',
        'img': './layout/letterpress/letterpress.jpg',
        'figcaption': 'letterpress',
        'tag': ['layout', 'blog'],
        'note': 'design the page with photoshop, and praceice psd to layout',
        'points': ['photoshop', 'layout'],
        'ref': 'six reversion'
    }, {
        'link': './designs/light_bulb.html',
        'img': './designs/light_bulb.png',
        'figcaption': 'Light Bulb',
        'tag': ['element', 'css'],
        'note': 'use html to draw the bulb div basic position involved css use animation alternate for the animation',
        'points': ['position: absolute, relative', ' @keyframes, animation',
            'transform: translateX(px) rotate(deg)'
        ],
        'ref': 'http://codepen.io/Simentesempre/pen/raoERY',
    }, {
        'link': './designs/flipCard.html',
        'img': './designs/flip_card.png',
        'figcaption': 'Flip Card',
        'tag': ['element', 'css'],
        'note': '3d perspective use div card to control the animation perspective to set the distance of crad(box) rotateX and roateY to transition two cards',
        'points': ['perspective ', ' transition, pseudo:hover',
            'transform: rotateX  roateY'
        ],
        'ref': 'https://desandro.github.io/3dtransforms/docs/card-flip.html',

    }, {
        'link': './layout/collapse.html',
        'img': './layout/collapse.png',
        'figcaption': 'Collapse',
        'tag': ['layout', 'css', 'javascript'],
        'note': '...',
        'points': ['transform-origin ', ' setTimeout',
            'animate : queue - false'
        ],
        'ref': 'ch3',

    }

];
$(document).ready(function() {
    //for each article
    for (var i in $json) {
        var $link = $json[i].link;
        var $img = $json[i].img;
        var $figcaption = $json[i].figcaption;
        var $note = $json[i].note;
        var $points = $json[i].points;
        var $ref = $json[i].ref;
        var $divimg = $('
', { class: 'snapshot' });
        // var $figure = $('
', { 'data-link': $link })
        var $iframe = $('', { 'data-link': $link, 'src': $link });
        // var $img = $('', { src: $img, alt: $figcaption });
        // var $data = $('
' + $figcaption + '
');
        var $data = $('
' + $figcaption + '
');
        // $divimg.append($figure.append($iframe).append($data));
        $divimg.append($iframe).append($data);
        var $divdes = $('
').addClass('description');
        $divdes.append($('
Note
')).append($('
' + $note + '
'));
        $divdes.append($('
Coding Point
'));
        var $codeUl = $('
');
        for (var point in $points) {
            $codeUl.append($('
' + $points[point] + '
'));
        }
        $divdes.append(($('').append($codeUl)));
        $divdes.append('
Reference
').append('
' + $ref + '
');
        ($('
').append($divimg).append($divdes)).appendTo('section');

    }
    // $('div.snapshot')
    $('div.snapshot')
        .on('mouseover', function(event) {
            event.preventDefault();
            /* Act on the event */
            $(this).css('cursor', 'pointer');

        })
        .on('click', function(event) {
            event.preventDefault();
            /* Act on the event */
            console.log($(this).find('iframe').data('link'));
            window.open($(this).find('iframe').data('link'));
        });
});
<commit_msg>add RWD to works<commit_after>var $json = [{
        'link': 'http://data.gov.tw/wise_search?nodetype=metadataset',
        'figcaption': 'Government',
        'tag': ['layout', 'blog'],
        'note': 'connect api',
        'points': ['project', 'layout'],
        'ref': 'WiSe search'
    }, {
        'link': './layout/bandWebsite/bandWebsite.html',
        'figcaption': 'Band Website',
        'tag': ['layout', 'blog'],
        'note': 'design the page with photoshop, and praceice psd to layout',
        'points': ['photoshop', 'layout'],
        'ref': 'six reversion'
    }, {
        'link': './layout/RWD/index.html',
        'figcaption': 'RWD',
        'tag': ['layout', 'RWD'],
        'note': 'desing RWD page',
        'points': ['RWD', 'layout'],
        'ref': 'book'
    }, {
        'link': './layout/letterpress/letterpress.html',
        'figcaption': 'letterpress',
        'tag': ['layout', 'blog'],
        'note': 'design the page with photoshop, and praceice psd to layout',
        'points': ['photoshop', 'layout'],
        'ref': 'six reversion'
    }, {
        'link': './designs/light_bulb.html',
        'figcaption': 'Light Bulb',
        'tag': ['element', 'css'],
        'note': 'use html to draw the bulb div basic position involved css use animation alternate for the animation',
        'points': ['position: absolute, relative', ' @keyframes, animation',
            'transform: translateX(px) rotate(deg)'
        ],
        'ref': 'http://codepen.io/Simentesempre/pen/raoERY',
    }, {
        'link': './designs/flipCard.html',
        'figcaption': 'Flip Card',
        'tag': ['element', 'css'],
        'note': '3d perspective use div card to control the animation perspective to set the distance of crad(box) rotateX and roateY to transition two cards',
        'points': ['perspective ', ' transition, pseudo:hover',
            'transform: rotateX  roateY'
        ],
        'ref': 'https://desandro.github.io/3dtransforms/docs/card-flip.html',

    }, {
        'link': './layout/collapse.html',
        'figcaption': 'Collapse',
        'tag': ['layout', 'css', 'javascript'],
        'note': '...',
        'points': ['transform-origin ', ' setTimeout',
            'animate : queue - false'
        ],
        'ref': 'ch3',

    }

];
$(document).ready(function() {
    //for each article
    for (var i in $json) {
        var $link = $json[i].link;
        var $img = $json[i].img;
        var $figcaption = $json[i].figcaption;
        var $note = $json[i].note;
        var $points = $json[i].points;
        var $ref = $json[i].ref;
        var $divimg = $('
', { class: 'snapshot' });
        // var $figure = $('
', { 'data-link': $link })
        var $iframe = $('', { 'data-link': $link, 'src': $link });
        // var $img = $('', { src: $img, alt: $figcaption });
        // var $data = $('
' + $figcaption + '
');
        var $data = $('
' + $figcaption + '
');
        // $divimg.append($figure.append($iframe).append($data));
        $divimg.append($iframe).append($data);
        var $divdes = $('
').addClass('description');
        $divdes.append($('
Note
')).append($('
' + $note + '
'));
        $divdes.append($('
Coding Point
'));
        var $codeUl = $('
');
        for (var point in $points) {
            $codeUl.append($('
' + $points[point] + '
'));
        }
        $divdes.append(($('').append($codeUl)));
        $divdes.append('
Reference
').append('
' + $ref + '
');
        ($('
').append($divimg).append($divdes)).appendTo('section');

    }
    // $('div.snapshot')
    $('div.snapshot')
        .on('mouseover', function(event) {
            event.preventDefault();
            /* Act on the event */
            $(this).css('cursor', 'pointer');

        })
        .on('click', function(event) {
            event.preventDefault();
            /* Act on the event */
            console.log($(this).find('iframe').data('link'));
            window.open($(this).find('iframe').data('link'));
        });
});
<|endoftext|>


<commit_before>'use strict';

var Promise = global.Promise || require('promise');

var glob       = require('glob'),
    Handlebars = require('handlebars'),
    fs         = require('graceful-fs'),
    path       = require('path'),
    semver     = require('semver'),
    utils      = require('./utils');

module.exports = ExpressHandlebars;

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

function ExpressHandlebars(config) {
    config || (config = {});

    if ('handlebars'  in config) { this.handlebars  = config.handlebars;  }
    if ('extname'     in config) { this.extname     = config.extname;     }
    if ('layoutsDir'  in config) { this.layoutsDir  = config.layoutsDir;  }
    if ('partialsDir' in config) { this.partialsDir = config.partialsDir; }

    if (this.extname.charAt(0) !== '.') {
        this.extname = '.' + this.extname;
    }

    this.defaultLayout = config.defaultLayout;
    this.helpers       = config.helpers;

    this.handlebarsVersion =
            ExpressHandlebars.getHandlebarsSemver(this.handlebars);

    this.compiled    = {};
    this.precompiled = {};

    this.engine = this.renderView.bind(this);
}

ExpressHandlebars._fsCache = {};

ExpressHandlebars.getHandlebarsSemver = function (handlebars) {
    var version = handlebars.VERSION || '';

    // Makes sure the Handlebars version is a valid semver.
    if (version && !semver.valid(version)) {
        version = version.replace(/(\d\.\d)\.(\D.*)/, '$1.0-$2');
    }

    return version;
};

ExpressHandlebars.prototype.handlebars  = Handlebars;
ExpressHandlebars.prototype.extname     = '.handlebars';
ExpressHandlebars.prototype.layoutsDir  = 'views/layouts/';
ExpressHandlebars.prototype.partialsDir = 'views/partials/';

ExpressHandlebars.prototype.compileTemplate = function (template, options) {
    options || (options = {});

    var compiler = options.precompiled ? 'precompile' : 'compile',
        compile  = this.handlebars[compiler];

    return compile(template);
};

ExpressHandlebars.prototype.getTemplate = function (filePath, options) {
    filePath = path.resolve(filePath);
    options || (options = {});

    var precompiled = options.precompiled,
        cache       = precompiled ? this.precompiled : this.compiled,
        template    = options.cache && cache[filePath];

    if (template) {
        return template;
    }

    // Optimistically cache template promise to reduce file system I/O, but
    // remove from cache if there was a problem.
    template = cache[filePath] = this._getFile(filePath, options)
        .then(function (file) {
            return this.compileTemplate(file, options);
        }.bind(this));

    return template.catch(function (err) {
        delete cache[filePath];
        throw err;
    });
};

ExpressHandlebars.prototype.getPartials = function (options) {
    options || (options = {});

    var partialsDirs = Array.isArray(this.partialsDir) ?
            this.partialsDir : [this.partialsDir];

    partialsDirs = partialsDirs.map(function (dir) {
        return this.getTemplates(dir, options);
    }, this);

    return Promise.all(partialsDirs).then(function (dirs) {
        var getPartialName = this._getPartialName.bind(this);

        return dirs.reduce(function (partials, templates) {
            Object.keys(templates).forEach(function (filePath) {
                partials[getPartialName(filePath)] = templates[filePath];
            });

            return partials;
        }, {});
    }.bind(this));
};

ExpressHandlebars.prototype.getTemplates = function (dirPath, options) {
    options || (options = {});

    return this._getDir(dirPath, options).then(function (filePaths) {
        var templates = filePaths.map(function (filePath) {
            return this.getTemplate(path.join(dirPath, filePath), options);
        }, this);

        return Promise.all(templates).then(function (templates) {
            return filePaths.reduce(function (map, filePath, i) {
                map[filePath] = templates[i];
                return map;
            }, {});
        });
    }.bind(this));
};

ExpressHandlebars.prototype.render = function (filePath, context, options) {
    options || (options = {});

    // Force `precompiled` to `false` since we're rendering to HTML.
    if (options.precompiled) {
        options = utils.extend({}, options, {precompiled: false});
    }

    return Promise.all([
        this.getTemplate(filePath, options),
        options.partials || this.getPartials(options)
    ]).then(function (templates) {
        var template = templates[0],
            partials = templates[1],
            data     = options.data;

        var helpers = options.helpers ||
                utils.extend({}, this.handlebars.helpers, this.helpers);

        return this._renderTemplate(template, context, {
            data    : data,
            helpers : helpers,
            partials: partials
        });
    }.bind(this));
};

ExpressHandlebars.prototype.renderView = function (viewPath, options, callback) {
    var context = options,
        data    = options.data;

    var helpers = utils.extend({},
            this.handlebars.helpers, this.helpers, options.helpers);

    // Pluck-out ExpressHandlebars-specific options.
    options = {
        cache      : options.cache,
        layout     : 'layout' in options ? options.layout : this.defaultLayout,
        precompiled: false
    };

    // Extend `options` with Handlebars-specific rendering options.
    utils.extend(options, {
        data    : data,
        helpers : helpers,
        partials: this.getPartials(options)
    });

    this.render(viewPath, context, options)
        .then(function (body) {
            var layoutPath = this._resolveLayoutPath(options.layout);

            if (layoutPath) {
                context = utils.extend({}, context, {body: body});
                return this.render(layoutPath, context, options);
            }
        }.bind(this))
        .then(utils.passValue(callback))
        .catch(utils.passError(callback));
};

ExpressHandlebars.prototype._getDir = function (dirPath, options) {
    dirPath = path.resolve(dirPath);

    var cache = ExpressHandlebars._fsCache,
        dir   = options.cache && cache[dirPath];

    if (dir) {
        return dir.then(function (dir) {
            return dir.concat();
        });
    }

    var pattern = '**/*' + this.extname;

    // Optimistically cache dir promise to reduce file system I/O, but remove
    // from cache if there was a problem.
    dir = cache[dirPath] = new Promise(function (resolve, reject) {
        glob(pattern, {cwd: dirPath}, function (err, dir) {
            if (err) {
                reject(err);
            } else {
                resolve(dir);
            }
        });
    });

    return dir.catch(function (err) {
        delete cache[dirPath];
        throw err;
    }).then(function (dir) {
        return dir.concat();
    });
};

ExpressHandlebars.prototype._getFile = function (filePath, options) {
    filePath = path.resolve(filePath);

    var cache = ExpressHandlebars._fsCache,
        file  = options.cache && cache[filePath];

    if (file) {
        return file;
    }

    // Optimistically cache file promise to reduce file system I/O, but remove
    // from cache if there was a problem.
    file = cache[filePath] = new Promise(function (resolve, reject) {
        fs.readFile(filePath, 'utf8', function (err, file) {
            if (err) {
                reject(err);
            } else {
                resolve(file);
            }
        });
    });

    return file.catch(function (err) {
        delete cache[filePath];
        throw err;
    });
};

ExpressHandlebars.prototype._getPartialName = function (filePath) {
    var extRegex = new RegExp(this.extname + '$'),
        name     = filePath.replace(extRegex, ''),
        version  = this.handlebarsVersion;

    // Fixes a Handlebars bug in versions prior to 1.0.rc.2 which caused
    // partials with "/"s in their name to not be found.
    // https://github.com/wycats/handlebars.js/pull/389
    if (version && !semver.satisfies(version, '>=1.0.0-rc.2')) {
        name = name.replace('/', '.');
    }

    return name;
};

ExpressHandlebars.prototype._renderTemplate = function (template, context, options) {
    return template(context, options);
};

ExpressHandlebars.prototype._resolveLayoutPath = function (layoutPath) {
    if (!layoutPath) {
        return null;
    }

    if (!path.extname(layoutPath)) {
        layoutPath += this.extname;
    }

    if (layoutPath.charAt(0) !== '/') {
        layoutPath = path.join(this.layoutsDir, layoutPath);
    }

    return layoutPath;
};
<commit_msg>Rearrange Promise then/catch calls<commit_after>'use strict';

var Promise = global.Promise || require('promise');

var glob       = require('glob'),
    Handlebars = require('handlebars'),
    fs         = require('graceful-fs'),
    path       = require('path'),
    semver     = require('semver'),
    utils      = require('./utils');

module.exports = ExpressHandlebars;

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

function ExpressHandlebars(config) {
    config || (config = {});

    if ('handlebars'  in config) { this.handlebars  = config.handlebars;  }
    if ('extname'     in config) { this.extname     = config.extname;     }
    if ('layoutsDir'  in config) { this.layoutsDir  = config.layoutsDir;  }
    if ('partialsDir' in config) { this.partialsDir = config.partialsDir; }

    if (this.extname.charAt(0) !== '.') {
        this.extname = '.' + this.extname;
    }

    this.defaultLayout = config.defaultLayout;
    this.helpers       = config.helpers;

    this.handlebarsVersion =
            ExpressHandlebars.getHandlebarsSemver(this.handlebars);

    this.compiled    = {};
    this.precompiled = {};

    this.engine = this.renderView.bind(this);
}

ExpressHandlebars._fsCache = {};

ExpressHandlebars.getHandlebarsSemver = function (handlebars) {
    var version = handlebars.VERSION || '';

    // Makes sure the Handlebars version is a valid semver.
    if (version && !semver.valid(version)) {
        version = version.replace(/(\d\.\d)\.(\D.*)/, '$1.0-$2');
    }

    return version;
};

ExpressHandlebars.prototype.handlebars  = Handlebars;
ExpressHandlebars.prototype.extname     = '.handlebars';
ExpressHandlebars.prototype.layoutsDir  = 'views/layouts/';
ExpressHandlebars.prototype.partialsDir = 'views/partials/';

ExpressHandlebars.prototype.compileTemplate = function (template, options) {
    options || (options = {});

    var compiler = options.precompiled ? 'precompile' : 'compile',
        compile  = this.handlebars[compiler];

    return compile(template);
};

ExpressHandlebars.prototype.getTemplate = function (filePath, options) {
    filePath = path.resolve(filePath);
    options || (options = {});

    var precompiled = options.precompiled,
        cache       = precompiled ? this.precompiled : this.compiled,
        template    = options.cache && cache[filePath];

    if (template) {
        return template;
    }

    // Optimistically cache template promise to reduce file system I/O, but
    // remove from cache if there was a problem.
    template = cache[filePath] = this._getFile(filePath, options)
        .then(function (file) {
            return this.compileTemplate(file, options);
        }.bind(this));

    return template.catch(function (err) {
        delete cache[filePath];
        throw err;
    });
};

ExpressHandlebars.prototype.getPartials = function (options) {
    options || (options = {});

    var partialsDirs = Array.isArray(this.partialsDir) ?
            this.partialsDir : [this.partialsDir];

    partialsDirs = partialsDirs.map(function (dir) {
        return this.getTemplates(dir, options);
    }, this);

    return Promise.all(partialsDirs).then(function (dirs) {
        var getPartialName = this._getPartialName.bind(this);

        return dirs.reduce(function (partials, templates) {
            Object.keys(templates).forEach(function (filePath) {
                partials[getPartialName(filePath)] = templates[filePath];
            });

            return partials;
        }, {});
    }.bind(this));
};

ExpressHandlebars.prototype.getTemplates = function (dirPath, options) {
    options || (options = {});

    return this._getDir(dirPath, options).then(function (filePaths) {
        var templates = filePaths.map(function (filePath) {
            return this.getTemplate(path.join(dirPath, filePath), options);
        }, this);

        return Promise.all(templates).then(function (templates) {
            return filePaths.reduce(function (map, filePath, i) {
                map[filePath] = templates[i];
                return map;
            }, {});
        });
    }.bind(this));
};

ExpressHandlebars.prototype.render = function (filePath, context, options) {
    options || (options = {});

    // Force `precompiled` to `false` since we're rendering to HTML.
    if (options.precompiled) {
        options = utils.extend({}, options, {precompiled: false});
    }

    return Promise.all([
        this.getTemplate(filePath, options),
        options.partials || this.getPartials(options)
    ]).then(function (templates) {
        var template = templates[0],
            partials = templates[1],
            data     = options.data;

        var helpers = options.helpers ||
                utils.extend({}, this.handlebars.helpers, this.helpers);

        return this._renderTemplate(template, context, {
            data    : data,
            helpers : helpers,
            partials: partials
        });
    }.bind(this));
};

ExpressHandlebars.prototype.renderView = function (viewPath, options, callback) {
    var context = options,
        data    = options.data;

    var helpers = utils.extend({},
            this.handlebars.helpers, this.helpers, options.helpers);

    // Pluck-out ExpressHandlebars-specific options.
    options = {
        cache      : options.cache,
        layout     : 'layout' in options ? options.layout : this.defaultLayout,
        precompiled: false
    };

    // Extend `options` with Handlebars-specific rendering options.
    utils.extend(options, {
        data    : data,
        helpers : helpers,
        partials: this.getPartials(options)
    });

    this.render(viewPath, context, options)
        .then(function (body) {
            var layoutPath = this._resolveLayoutPath(options.layout);

            if (layoutPath) {
                context = utils.extend({}, context, {body: body});
                return this.render(layoutPath, context, options);
            }
        }.bind(this))
        .then(utils.passValue(callback))
        .catch(utils.passError(callback));
};

ExpressHandlebars.prototype._getDir = function (dirPath, options) {
    dirPath = path.resolve(dirPath);

    var cache = ExpressHandlebars._fsCache,
        dir   = options.cache && cache[dirPath];

    if (dir) {
        return dir.then(function (dir) {
            return dir.concat();
        });
    }

    var pattern = '**/*' + this.extname;

    // Optimistically cache dir promise to reduce file system I/O, but remove
    // from cache if there was a problem.
    dir = cache[dirPath] = new Promise(function (resolve, reject) {
        glob(pattern, {cwd: dirPath}, function (err, dir) {
            if (err) {
                reject(err);
            } else {
                resolve(dir);
            }
        });
    });

    return dir.then(function (dir) {
        return dir.concat();
    }).catch(function (err) {
        delete cache[dirPath];
        throw err;
    });
};

ExpressHandlebars.prototype._getFile = function (filePath, options) {
    filePath = path.resolve(filePath);

    var cache = ExpressHandlebars._fsCache,
        file  = options.cache && cache[filePath];

    if (file) {
        return file;
    }

    // Optimistically cache file promise to reduce file system I/O, but remove
    // from cache if there was a problem.
    file = cache[filePath] = new Promise(function (resolve, reject) {
        fs.readFile(filePath, 'utf8', function (err, file) {
            if (err) {
                reject(err);
            } else {
                resolve(file);
            }
        });
    });

    return file.catch(function (err) {
        delete cache[filePath];
        throw err;
    });
};

ExpressHandlebars.prototype._getPartialName = function (filePath) {
    var extRegex = new RegExp(this.extname + '$'),
        name     = filePath.replace(extRegex, ''),
        version  = this.handlebarsVersion;

    // Fixes a Handlebars bug in versions prior to 1.0.rc.2 which caused
    // partials with "/"s in their name to not be found.
    // https://github.com/wycats/handlebars.js/pull/389
    if (version && !semver.satisfies(version, '>=1.0.0-rc.2')) {
        name = name.replace('/', '.');
    }

    return name;
};

ExpressHandlebars.prototype._renderTemplate = function (template, context, options) {
    return template(context, options);
};

ExpressHandlebars.prototype._resolveLayoutPath = function (layoutPath) {
    if (!layoutPath) {
        return null;
    }

    if (!path.extname(layoutPath)) {
        layoutPath += this.extname;
    }

    if (layoutPath.charAt(0) !== '/') {
        layoutPath = path.join(this.layoutsDir, layoutPath);
    }

    return layoutPath;
};
<|endoftext|>


<commit_before>/**
 * Library methods for test tasks
 *
 * @author Nikhil Modak
 */

'use strict';

var through = require('through2').obj;
var karma = require('karma').server;
var http = require('http');

module.exports = function (gulp, gutil) {

  function proxy() {
    var proxyServer = http.createServer(function (req, res) {
      res.writeHead(200);
      res.end('\n');
    });

    return {
      start: function () {
        proxyServer.listen(9615);
        return through();
      },
      stop: function () {
        var stream = through(
          function (data, enc, callback) {
            this.push(data);
            callback();
          },
          function (data) {
            proxyServer.close();
            this.emit('end', data);
          }
        );
        return stream;
      }
    };
  }

  return {
    karma: function (cb) {
      var p = proxy();
      var opts = {
        configFile: process.cwd() + '/karma.conf.js'
      };

      if (gutil.env.hasOwnProperty('auto-watch')) {
        opts.autoWatch = gutil.env['auto-watch'];
      }

      if (gutil.env.hasOwnProperty('browsers')) {
        opts.browsers = gutil.env.browsers;
      }

      if (gutil.env.hasOwnProperty('colors')) {
        opts.colors = gutil.env.colors;
      }

      if (gutil.env.hasOwnProperty('log-level')) {
        opts.logLevel = gutil.env['log-level'];
      }

      if (gutil.env.hasOwnProperty('port')) {
        opts.port = gutil.env.port;
      }

      if (gutil.env.hasOwnProperty('reporters')) {
        opts.reporters = gutil.env.reporters;
      }

      if (gutil.env.hasOwnProperty('runner-port')) {
        opts.runnerPort = gutil.env.runnerPort;
      }

      if (gutil.env.hasOwnProperty('single-run')) {
        opts.singleRun = gutil.env['single-run'];
      }

      karma.start(opts, function (err) {
        p.stop();
        if (err === 0) {
          cb();
        } else {
          cb(new Error('One or more tests failed!'));
        }
      });
    }
  };
};
<commit_msg>LIA-48449 Split browsers for testing.<commit_after>/**
 * Library methods for test tasks
 *
 * @author Nikhil Modak
 */

'use strict';

var through = require('through2').obj;
var karma = require('karma').server;
var http = require('http');

module.exports = function (gulp, gutil) {

  function proxy() {
    var proxyServer = http.createServer(function (req, res) {
      res.writeHead(200);
      res.end('\n');
    });

    return {
      start: function () {
        proxyServer.listen(9615);
        return through();
      },
      stop: function () {
        var stream = through(
          function (data, enc, callback) {
            this.push(data);
            callback();
          },
          function (data) {
            proxyServer.close();
            this.emit('end', data);
          }
        );
        return stream;
      }
    };
  }

  return {
    karma: function (cb) {
      var p = proxy();
      var opts = {
        configFile: process.cwd() + '/karma.conf.js'
      };

      if (gutil.env.hasOwnProperty('auto-watch')) {
        opts.autoWatch = gutil.env['auto-watch'];
      }

      if (gutil.env.hasOwnProperty('browsers')) {
        opts.browsers = gutil.env.browsers.split(',');
      }

      if (gutil.env.hasOwnProperty('colors')) {
        opts.colors = gutil.env.colors;
      }

      if (gutil.env.hasOwnProperty('log-level')) {
        opts.logLevel = gutil.env['log-level'];
      }

      if (gutil.env.hasOwnProperty('port')) {
        opts.port = gutil.env.port;
      }

      if (gutil.env.hasOwnProperty('reporters')) {
        opts.reporters = gutil.env.reporters;
      }

      if (gutil.env.hasOwnProperty('runner-port')) {
        opts.runnerPort = gutil.env.runnerPort;
      }

      if (gutil.env.hasOwnProperty('single-run')) {
        opts.singleRun = gutil.env['single-run'];
      }

      karma.start(opts, function (err) {
        p.stop();
        if (err === 0) {
          cb();
        } else {
          cb(new Error('One or more tests failed!'));
        }
      });
    }
  };
};
<|endoftext|>


<commit_before>/* --- AUTOGENERATED FILE -----------------------------
* If you make changes to this file delete this comment.
* Otherwise the file may be overwritten in the future.
* --------------------------------------------------- */

const { regexMatchLocs } = require('../lib/matching/regexMatch');
const { mergeLocMatchGroups } = require('../lib/matching/utils');

const allSetSrc = {
  type: 'website',
  url: 'https://resources.allsetlearning.com/chinese/grammar/ASG6TB4J',
  name: 'AllSet Chinese Grammar Wiki',
};

module.exports = {
  id: 'expressingThatsAllWithEryi',
  name: 'Subj. + Verb + Obj. + 而已',
  description:
    '而已 expresses that something is merely what it is. It is like saying "it\'s only a test, that\'s all." 而已 is put at the end of the sentence to emphasis that something is just what it is.',
  sources: [allSetSrc],
  match: sentence => {
    const text = sentence.original;
    return mergeLocMatchGroups([regexMatchLocs(text, /(而已)/)]);
  },
  examples: [
    {
      zh: '他只是开个玩笑而已，不要当真。',
      en: "He's just making a joke, that's all, don't take it seriously",
      src: allSetSrc,
    },
    {
      zh: '这次会议没有达成具体的方案，仅仅是在这个问题上达成了共识而已。',
      en:
        "This conference hasn't reached a concrete plan, it's just been able to answer one question and that's all",
      src: allSetSrc,
    },
  ],
};
<commit_msg>removing eryi regen comment<commit_after>const { regexMatchLocs } = require('../lib/matching/regexMatch');
const { mergeLocMatchGroups } = require('../lib/matching/utils');

const allSetSrc = {
  type: 'website',
  url: 'https://resources.allsetlearning.com/chinese/grammar/ASG6TB4J',
  name: 'AllSet Chinese Grammar Wiki',
};

module.exports = {
  id: 'expressingThatsAllWithEryi',
  name: 'Subj. + Verb + Obj. + 而已',
  description:
    '而已 expresses that something is merely what it is. It is like saying "it\'s only a test, that\'s all." 而已 is put at the end of the sentence to emphasis that something is just what it is.',
  sources: [allSetSrc],
  match: sentence => {
    const text = sentence.original;
    return mergeLocMatchGroups([regexMatchLocs(text, /(而已)/)]);
  },
  examples: [
    {
      zh: '他只是开个玩笑而已，不要当真。',
      en: "He's just making a joke, that's all, don't take it seriously",
      src: allSetSrc,
    },
    {
      zh: '这次会议没有达成具体的方案，仅仅是在这个问题上达成了共识而已。',
      en:
        "This conference hasn't reached a concrete plan, it's just been able to answer one question and that's all",
      src: allSetSrc,
    },
  ],
};
<|endoftext|>


<commit_before>import Rx from 'rx'

function transposeVTree(vTree) {
  if (typeof vTree.data === `object` && vTree.data.static) {
    return Rx.Observable.just(vTree)
  } else if (!vTree) {
    return null
  } else if (typeof vTree.subscribe === `function`) {
    return vTree.flatMapLatest(transposeVTree)
  } else if (typeof vTree === `object`) {
    if (vTree.children && vTree.children.length > 0) {
      return Rx.Observable.combineLatest(
        vTree.children.map(transposeVTree).filter(x => !!x),
        (...children) => ({
          sel: vTree.sel,
          data: vTree.data,
          text: vTree.text,
          elm: vTree.elm,
          key: vTree.key,
          children,
        })
      )
    }
    return Rx.Observable.just(vTree)
  } else {
    throw new Error(`Unhandled vTree Value`)
  }
}

export {transposeVTree}
<commit_msg>fix(transposition): fix `null` value children<commit_after>import Rx from 'rx'

function transposeVTree(vTree) {
  if (!vTree) {
    return null
  } else if (typeof vTree.data === `object` && vTree.data.static) {
    return Rx.Observable.just(vTree)
  } else if (typeof vTree.subscribe === `function`) {
    return vTree.flatMapLatest(transposeVTree)
  } else if (typeof vTree === `object`) {
    if (vTree.children && vTree.children.length > 0) {
      return Rx.Observable.combineLatest(
        vTree.children.map(transposeVTree).filter(x => x !== null),
        (...children) => ({
          sel: vTree.sel,
          data: vTree.data,
          text: vTree.text,
          elm: vTree.elm,
          key: vTree.key,
          children,
        })
      )
    }
    return Rx.Observable.just(vTree)
  } else {
    throw new Error(`Unhandled vTree Value`)
  }
}

export {transposeVTree}
<|endoftext|>


<commit_before>const puppeteer = require('puppeteer');
var url = 'file://' + __dirname + '/index.html';

(async () => {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();
  page.on('console', msg => console.log(msg.text()));
  await Promise.all([
    page.exposeFunction('travixPrint', s => process.stdout.write(s)),
    page.exposeFunction('travixPrintln', s => process.stdout.write(s + '\n')),
    page.exposeFunction('travixExit', code => process.exit(code)),
  ]);
  await page.goto(url);
  await browser.close();
})();<commit_msg>A little hint<commit_after>const puppeteer = require('puppeteer');
var url = 'file://' + __dirname + '/index.html';

(async () => {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();
  page.on('console', msg => console.log(msg.text()));
  await Promise.all([
    page.exposeFunction('travixPrint', s => process.stdout.write(s)),
    page.exposeFunction('travixPrintln', s => process.stdout.write(s + '\n')),
    page.exposeFunction('travixExit', code => process.exit(code)),
  ]);
  await page.evaluateOnNewDocument(() => console.log(window.navigator.userAgent)); // print user agent as a hint that we are running in a browser
  await page.goto(url);
  await browser.close();
})();<|endoftext|>


<commit_before>
var ttest = require('ttest');
var summary = require('summary');

function Commonality(top) {
  this._top = top;

  this.nodelist = null;
}
module.exports = Commonality;

Commonality.prototype.collect = function (nodelist) {
  this.parent = new FeatureSummary();
  this.node = new FeatureSummary();

  this.nodelist = nodelist;

  for (var i = 0, l = nodelist.length; i < l; i++) {
    this.node.collect(nodelist[i]);

    var parent = nodelist[i];
    while(parent !== this._top && (parent = parent.parent)) {
      this.parent.collect(parent);
    }
  }
};

var ttest_options = {
  alpha: 0.01,
  alternative: "greater"
};

Commonality.prototype.tagnameReducer = function () {
  var names = Object.keys(this.node.tagname);

  // Find the tagname collection there quickly assumed to have the
  // highest density mean
  var maxmean = 0;
  var maxtagname = null;
  for (var i = 0, l = names.length; i < l; i++) {
    var mean = summary(this.node.tagname[names[i]]).mean();
    if (mean > maxmean) {
      maxtagname = names[i];
      maxmean = mean;
    }
  }
  var maxdataset = this.node.tagname[maxtagname];

  for (var n = 0, r = names.length; n < r; n++) {
    if (names[n] == maxtagname) continue;

    // Check if the maxdataset mean is greater than the current tagname
    console.log('testing ' + maxtagname + ' against ' + names[n], ttest(maxdataset, this.node.tagname[names[n]], ttest_options).pValue());
    if (ttest(maxdataset, this.node.tagname[names[n]], ttest_options).valid()) {

      for (var p = 0, t = this.nodelist.length; p < t; p++) {
        if (this.nodelist[p].tagname === names[n]) {
          this.nodelist[p].remove();
        }
      }
    }
  }
};

//
// Collects features and bind them to the node density
//
function FeatureSummary() {
  this.type = {
    'fragment': [],
    'element': [],
    'text': []
  };
  this.tagname = {
    // $tagname : [$density]
  };
  this.attribute = {
    // $attrname: { $value: [$density] }
  };
}

FeatureSummary.prototype._appendAttribute = function (attrobject, attrvalue, node) {
  if (attrobject.hasOwnProperty( attrvalue )) {
    attrobject[ attrvalue ].push(node.density);
  } else {
    attrobject[ attrvalue ] = [node.density];
  }
};

FeatureSummary.prototype.collect = function (node) {
  this.type[node.type].push(node.density);

  if (node.type === 'element') {
    if (this.tagname.hasOwnProperty(node.tagname)) {
      this.tagname[node.tagname].push(node.density);
    } else {
      this.tagname[node.tagname] = [node.density];
    }

    var attrnames = Object.keys(node.attr);
    var attrobject = null;
    var attrname = null;
    for (var i = 0, l = attrnames.length; i < l; i++) {
      attrname = attrnames[i];

      if (this.attribute.hasOwnProperty( attrname )) {
        attrobject = this.attribute[ attrname ];
      } else {
        attrobject = this.attribute[ attrname ] = {};
      }

      if (attrname === 'class') {
        for (var n = 0, r = node.classes.length; n < r; n++) {
          this._appendAttribute(attrobject, node.classes[n], node);
        }
      } else {
        this._appendAttribute(attrobject, node.attr[ attrname ], node);
      }
    }
  }
};
<commit_msg>[fix] t-test valid check<commit_after>
var ttest = require('ttest');
var summary = require('summary');

function Commonality(top) {
  this._top = top;

  this.nodelist = null;
}
module.exports = Commonality;

Commonality.prototype.collect = function (nodelist) {
  this.parent = new FeatureSummary();
  this.node = new FeatureSummary();

  this.nodelist = nodelist;

  for (var i = 0, l = nodelist.length; i < l; i++) {
    this.node.collect(nodelist[i]);

    var parent = nodelist[i];
    while(parent !== this._top && (parent = parent.parent)) {
      this.parent.collect(parent);
    }
  }
};

var ttest_options = {
  alpha: 0.01,
  alternative: "greater"
};

Commonality.prototype.tagnameReducer = function () {
  var names = Object.keys(this.node.tagname);

  // Find the tagname collection there quickly assumed to have the
  // highest density mean
  var maxmean = 0;
  var maxtagname = null;
  for (var i = 0, l = names.length; i < l; i++) {
    var mean = summary(this.node.tagname[names[i]]).mean();
    if (mean > maxmean) {
      maxtagname = names[i];
      maxmean = mean;
    }
  }
  var maxdataset = this.node.tagname[maxtagname];

  for (var n = 0, r = names.length; n < r; n++) {
    if (names[n] == maxtagname) continue;

    // Check if the maxdataset mean is greater than the current tagname
    console.log('testing ' + maxtagname + ' against ' + names[n], ttest(maxdataset, this.node.tagname[names[n]], ttest_options).pValue());
    if (ttest(maxdataset, this.node.tagname[names[n]], ttest_options).valid() === false) {

      for (var p = 0, t = this.nodelist.length; p < t; p++) {
        if (this.nodelist[p].tagname === names[n]) {
          this.nodelist[p].remove();
        }
      }
    }
  }
};

//
// Collects features and bind them to the node density
//
function FeatureSummary() {
  this.type = {
    'fragment': [],
    'element': [],
    'text': []
  };
  this.tagname = {
    // $tagname : [$density]
  };
  this.attribute = {
    // $attrname: { $value: [$density] }
  };
}

FeatureSummary.prototype._appendAttribute = function (attrobject, attrvalue, node) {
  if (attrobject.hasOwnProperty( attrvalue )) {
    attrobject[ attrvalue ].push(node.density);
  } else {
    attrobject[ attrvalue ] = [node.density];
  }
};

FeatureSummary.prototype.collect = function (node) {
  this.type[node.type].push(node.density);

  if (node.type === 'element') {
    if (this.tagname.hasOwnProperty(node.tagname)) {
      this.tagname[node.tagname].push(node.density);
    } else {
      this.tagname[node.tagname] = [node.density];
    }

    var attrnames = Object.keys(node.attr);
    var attrobject = null;
    var attrname = null;
    for (var i = 0, l = attrnames.length; i < l; i++) {
      attrname = attrnames[i];

      if (this.attribute.hasOwnProperty( attrname )) {
        attrobject = this.attribute[ attrname ];
      } else {
        attrobject = this.attribute[ attrname ] = {};
      }

      if (attrname === 'class') {
        for (var n = 0, r = node.classes.length; n < r; n++) {
          this._appendAttribute(attrobject, node.classes[n], node);
        }
      } else {
        this._appendAttribute(attrobject, node.attr[ attrname ], node);
      }
    }
  }
};
<|endoftext|>


<commit_before>/**
 * Module dependencies.
 */
var Request = require('./request')
  , Response = require('./response')
  , flatten = require('utils-flatten');

/**
 * Creates an instance of `Test`.
 *
 * @constructor
 * @api protected
 */
function Test(callbacks) {
  this._callbacks = flatten(callbacks);
}

/**
 * Register a callback to be invoked when request is prepared.
 *
 * @param {Function} cb
 * @return {Test} for chaining
 * @api public
 */
Test.prototype.req = function(cb) {
  this._req = cb;
  return this;
};

/**
 * Register a callback to be invoked when response is prepared.
 *
 * @param {Function} cb
 * @return {Test} for chaining
 * @api public
 */
Test.prototype.res = function(cb) {
  this._res = cb;
  return this;
};

Test.prototype.render = function(cb) {
  this._render = cb;
  return this;
};

/**
 * Register a callback to be invoked when handler `end()`s response.
 *
 * @param {Function} cb
 * @return {Test} for chaining
 * @api public
 */
Test.prototype.end = function(cb) {
  this._end = cb;
  return this;
};

/**
 * Register a callback to be invoked when handler calls `next()`.
 *
 * @param {Function} cb
 * @return {Test} for chaining
 * @api public
 */
Test.prototype.next = function(cb) {
  this._next = cb;
  return this;
};

/**
 * Dispatch mock request to handler.
 *
 * @api public
 */
Test.prototype.dispatch = function(err) {
  var self = this
    , req = new Request()
    , before = this._req;

  function ready() {
    var res = new Response(
      function onrender(layout) {
        if (!self._render) { throw new Error('res#render should not be called'); }
        self._render.call(this, res, layout);
      },
      function() {
        if (!self._end) { throw new Error('res#end should not be called'); }
        self._end.call(this, res);
      });

    if (self._res) { self._res(res); }

    function next(err) {
      if (!self._next) { throw new Error('next should not be called'); }
      self._next.call(this, err);
    }

    var i = 0;
    function callbacks(err) {
      var fn = self._callbacks[i++];
      if (!fn) { return next(err); }
      try {
        if (err) {
          if (fn.length < 4) { return callbacks(err); }
          fn(err, req, res, callbacks);
        } else {
          if (fn.length < 4) { return fn(req, res, callbacks); }
          callbacks();
        }
      } catch (err) {
        // NOTE: Route handlers are not expected to throw exceptions.  So, in
        //       the context of a unit test, exceptions are re-thrown, rather
        //       than being caught and passed to `next`.
        throw err;
      }
    }
    callbacks();
  }

  if (before && before.length == 2) {
    before(req, ready);
  } else if (before) {
    before(req);
    ready();
  } else {
    ready();
  }
};

/**
 * Expose `Test`.
 */
module.exports = Test;
<commit_msg>Support error dispatching.<commit_after>/**
 * Module dependencies.
 */
var Request = require('./request')
  , Response = require('./response')
  , flatten = require('utils-flatten');

/**
 * Creates an instance of `Test`.
 *
 * @constructor
 * @api protected
 */
function Test(callbacks) {
  this._callbacks = flatten(callbacks);
}

/**
 * Register a callback to be invoked when request is prepared.
 *
 * @param {Function} cb
 * @return {Test} for chaining
 * @api public
 */
Test.prototype.req = function(cb) {
  this._req = cb;
  return this;
};

/**
 * Register a callback to be invoked when response is prepared.
 *
 * @param {Function} cb
 * @return {Test} for chaining
 * @api public
 */
Test.prototype.res = function(cb) {
  this._res = cb;
  return this;
};

Test.prototype.render = function(cb) {
  this._render = cb;
  return this;
};

/**
 * Register a callback to be invoked when handler `end()`s response.
 *
 * @param {Function} cb
 * @return {Test} for chaining
 * @api public
 */
Test.prototype.end = function(cb) {
  this._end = cb;
  return this;
};

/**
 * Register a callback to be invoked when handler calls `next()`.
 *
 * @param {Function} cb
 * @return {Test} for chaining
 * @api public
 */
Test.prototype.next = function(cb) {
  this._next = cb;
  return this;
};

/**
 * Dispatch mock request to handler.
 *
 * @api public
 */
Test.prototype.dispatch = function(err) {
  var self = this
    , req = new Request()
    , before = this._req;

  function ready() {
    var res = new Response(
      function onrender(layout) {
        if (!self._render) { throw new Error('res#render should not be called'); }
        self._render.call(this, res, layout);
      },
      function() {
        if (!self._end) { throw new Error('res#end should not be called'); }
        self._end.call(this, res);
      });

    if (self._res) { self._res(res); }

    function next(err) {
      if (!self._next) { throw new Error('next should not be called'); }
      self._next.call(this, err);
    }

    var i = 0;
    function callbacks(err) {
      var fn = self._callbacks[i++];
      if (!fn) { return next(err); }
      try {
        if (err) {
          if (fn.length < 4) { return callbacks(err); }
          fn(err, req, res, callbacks);
        } else {
          if (fn.length < 4) { return fn(req, res, callbacks); }
          callbacks();
        }
      } catch (err) {
        // NOTE: Route handlers are not expected to throw exceptions.  So, in
        //       the context of a unit test, exceptions are re-thrown, rather
        //       than being caught and passed to `next`.
        throw err;
      }
    }
    callbacks(err);
  }

  if (before && before.length == 2) {
    before(req, ready);
  } else if (before) {
    before(req);
    ready();
  } else {
    ready();
  }
};

/**
 * Expose `Test`.
 */
module.exports = Test;
<|endoftext|>


<commit_before>var Algorithm = require("./abstract")("RSA-OAEP")
  , RSA       = require("./shared/RSA")
  , forge     = require("node-forge")
  , types     = Algorithm.types
  , public    = types.public.usage
  , private   = types.private.usage;

//attached shared RSA
RSA(Algorithm);

Algorithm.checkParams = checkParams;

public.encrypt = createEncrypt;
private.decrypt = createDecrypt;

module.exports = Algorithm;

function createEncrypt(Key){
  return function RSA_OAEP_ENCRYPT(alg,buf){
    return new Buffer(Key.publicKey.encrypt(buf.toString("binary"), "RSA-OAEP"),"binary");
  };
}

function createDecrypt(Key){
  return function RSA_OAEP_DECRYPT(alg,buf){
    return new Buffer(Key.privateKey.decrypt(buf.toString("binary"), "RSA-OAEP"),"binary");
  };
}

function checkParams(format, algorithm, usages){
  //if (!(algorithm.hash && (algorithm.hash.name === "SHA-256")))
    //throw new Error("Unsupported or missing hash name");
  //if (!Buffer.isBuffer(algorithm.publicExponent))
    //throw new Error("algorithm.publicExponent not a Buffer source");

}
<commit_msg>Add hash parameter to forge decrypt.<commit_after>var Algorithm = require("./abstract")("RSA-OAEP")
  , RSA       = require("./shared/RSA")
  , forge     = require("node-forge")
  , types     = Algorithm.types
  , public    = types.public.usage
  , private   = types.private.usage;

//attached shared RSA
RSA(Algorithm);

Algorithm.checkParams = checkParams;

public.encrypt = createEncrypt;
private.decrypt = createDecrypt;

module.exports = Algorithm;

function createEncrypt(Key){
  return function RSA_OAEP_ENCRYPT(alg,buf){
    return new Buffer(Key.publicKey.encrypt(buf.toString("binary"), "RSA-OAEP"),"binary");
  };
}

function createDecrypt(Key){
  return function RSA_OAEP_DECRYPT(alg,buf){
    return new Buffer(Key.privateKey.decrypt(buf.toString("binary"), "RSA-OAEP", {
      md: forge.md[alg.hash.name.toLowerCase().replace('-','')].create()
    }),"binary");
  };
}

function checkParams(format, algorithm, usages){
  const ALLOWED_HASH_ALGORITHMS = ['SHA-1', 'SHA-256', 'SHA-384', 'SHA-512'];

  if (!algorithm.hash) {
    algorith.hash = {name: 'SHA-1'}
  } else if(!ALLOWED_HASH_ALGORITHMS.indexOf(algorithm.hash.name)){
    throw new Error("Unsupported or missing hash name");
  }

  if (!Buffer.isBuffer(algorithm.publicExponent))
    throw new Error("algorithm.publicExponent not a Buffer source");

}
<|endoftext|>


<commit_before>module.exports = function Comments(keepSpecialComments, keepBreaks, lineBreak) {
  var comments = [];

  return {
    // Strip special comments (/*! ... */) by replacing them by __CSSCOMMENT__ marker
    // for further restoring. Plain comments are removed. It's done by scanning datq using
    // String#indexOf scanning instead of regexps to speed up the process.
    escape: function(data) {
      var tempData = [];
      var nextStart = 0;
      var nextEnd = 0;
      var cursor = 0;

      for (; nextEnd < data.length; ) {
        nextStart = data.indexOf('/*', nextEnd);
        nextEnd = data.indexOf('*/', nextStart + 2);
        if (nextStart == -1 || nextEnd == -1)
          break;

        tempData.push(data.substring(cursor, nextStart));
        if (data[nextStart + 2] == '!') {
          // in case of special comments, replace them with a placeholder
          comments.push(data.substring(nextStart, nextEnd + 2));
          tempData.push('__CSSCOMMENT__');
        }
        cursor = nextEnd + 2;
      }

      return tempData.length > 0 ?
        tempData.join('') + data.substring(cursor, data.length) :
        data;
    },

    restore: function(data) {
      var commentsCount = comments.length;
      var breakSuffix = keepBreaks ? lineBreak : '';

      return data.replace(new RegExp('__CSSCOMMENT__(' + lineBreak + '| )?', 'g'), function() {
        switch (keepSpecialComments) {
          case '*':
            return comments.shift() + breakSuffix;
          case 1:
            return comments.length == commentsCount ?
              comments.shift() + breakSuffix :
              '';
          case 0:
            return '';
        }
      });
    }
  };
};
<commit_msg>Fix typos.<commit_after>module.exports = function Comments(keepSpecialComments, keepBreaks, lineBreak) {
  var comments = [];

  return {
    // Strip special comments (/*! ... */) by replacing them by __CSSCOMMENT__ marker
    // for further restoring. Plain comments are removed. It's done by scanning data using
    // String#indexOf scanning instead of regexps to speed up the process.
    escape: function(data) {
      var tempData = [];
      var nextStart = 0;
      var nextEnd = 0;
      var cursor = 0;

      for (; nextEnd < data.length; ) {
        nextStart = data.indexOf('/*', nextEnd);
        nextEnd = data.indexOf('*/', nextStart + 2);
        if (nextStart == -1 || nextEnd == -1)
          break;

        tempData.push(data.substring(cursor, nextStart));
        if (data[nextStart + 2] == '!') {
          // in case of special comments, replace them with a placeholder
          comments.push(data.substring(nextStart, nextEnd + 2));
          tempData.push('__CSSCOMMENT__');
        }
        cursor = nextEnd + 2;
      }

      return tempData.length > 0 ?
        tempData.join('') + data.substring(cursor, data.length) :
        data;
    },

    restore: function(data) {
      var commentsCount = comments.length;
      var breakSuffix = keepBreaks ? lineBreak : '';

      return data.replace(new RegExp('__CSSCOMMENT__(' + lineBreak + '| )?', 'g'), function() {
        switch (keepSpecialComments) {
          case '*':
            return comments.shift() + breakSuffix;
          case 1:
            return comments.length == commentsCount ?
              comments.shift() + breakSuffix :
              '';
          case 0:
            return '';
        }
      });
    }
  };
};
<|endoftext|>


<commit_before>import React, { Component } from 'react';
import {
  ScrollView,
  TouchableHighlight,
  StyleSheet,
  Image,
  Text,
  TextInput,
  View,
  Platform
} from 'react-native';

import { Navigation } from 'react-native-navigation';
import Icon from 'react-native-vector-icons/MaterialIcons';
import StarRating from 'react-native-star-rating';
import MapView from 'react-native-maps';
import Modal from 'react-native-modal'
import ImagePicker from 'react-native-image-picker';

import Location from '../../helpers/Location';

const SHOW_DURATION = 300;
const HIDE_DURATION = 250;

const INITIAL_LAT = 37.78825;
const INITIAL_LON =-122.4324;
const INITIAL_LAT_DELTA = 0.0922;
const INITIAL_LON_DELTA = 0.0421;

class SpotDetail extends Component {

  state = {
    isMapModalVisible: false,
    imageAnimationType: 'fadeInDown',
    contentAnimationType: 'fadeInRight',
    animationDuration: SHOW_DURATION,

    name: "",
    description: "",
    currentAddress: '?',
    mapRegion: {
      latitude: INITIAL_LAT,
      longitude: INITIAL_LON,
      latitudeDelta: INITIAL_LAT_DELTA,
      longitudeDelta: INITIAL_LON_DELTA
    }
  };

  constructor(props) {
    super(props);
    this.props.navigator.setOnNavigatorEvent(this.onNavigatorEvent.bind(this));

    this.props.navigator.setTitle({
      title: 'Add a spot'
    });
    this.props.navigator.setButtons({
      rightButtons: [{
        icon: globalIconMap['send'],
        id: 'add_spot'
      }]
    });

  }

  componentDidMount() {
    navigator.geolocation.getCurrentPosition(
        (pos) => {
          let mapRegion = {latitudeDelta: INITIAL_LAT_DELTA, longitudeDelta: INITIAL_LON_DELTA};
          mapRegion.latitude = pos.coords.latitude;
          mapRegion.longitude = pos.coords.longitude;
          this.setState({mapRegion});
          this._updateAddress();
        },
        (error) => console.log(JSON.stringify(error)),
        {enableHighAccuracy: true, timeout: 20000, maximumAge: 1000}
    );
  }

  onNavigatorEvent(event) {
    if (event.id === 'backPress') {
      this.setState({
        imageAnimationType: 'fadeOutUp',
        contentAnimationType: 'fadeOutRight',
        animationDuration: HIDE_DURATION
      });
      this.props.navigator.pop();
    }
  }

  _chooseLocation() {
    this.setState({ isMapModalVisible: true });
  }

  _chooseLocationDone() {
    this.setState({ isMapModalVisible: false });
  }

  _updateAddress() {
    Location.getAddress(this.state.mapRegion.latitude, this.state.mapRegion.longitude,
        (err, result) => {
          if (result) {
            let address = (result.streetName ? (result.streetName + ", ") : "")
                + result.city + ", "
                + result.administrativeLevels.level1short + ".";
            this.setState({currentAddress: address});
          }
        }
    );
  }

  _addPicture() {
    var options = {
      title: 'Add picture',
      takePhotoButtonTitle: 'Camera',
      chooseFromLibraryButtonTitle: 'Galery',
      mediaType: 'photo',
      maxWidth: 1280,
      maxHeight: 720,
      quality: 0.9,
      storageOptions: {
        skipBackup: true,
        path: 'images'
      }
    };
    ImagePicker.showImagePicker(options, (response) => {
      if (response.didCancel) {
        console.log('User cancelled image picker');
      } else if (response.error) {
        console.log('ImagePicker Error: ', response.error);
      } else {
        let source = { uri: response.uri };
        this.setState({
          avatarSource: source
        });
      }
    });
  }

  _onMapRegionChange(mapRegion) {
    this.setState({ mapRegion });
  }

  render() {
    return (
        <ScrollView style={styles.container}>
          <View style={styles.formRow}>
            <Icon style={styles.formRowIcon} name="home" size={24} color="#555" />

            <View style={styles.formRowContent}>
              <Text style={styles.formRowTitle}>Name*</Text>
              <View style={styles.formRowContent}>
                <TextInput
                    style={styles.input}
                    placeholder="Ex: Valkaria airport"
                    placeholderTextColor="#888"
                    keyboardAppearance="dark"
                    underlineColorAndroid="#555"
                    returnKeyType="next"
                    editable={true}
                    multiline={false}
                    spellCheck={false}
                    numberOfLines={1}
                    maxLength={70} />
              </View>
            </View>
          </View>

          <View style={styles.formRow}>
            <Icon style={styles.formRowIcon} name="location-on" size={24} color="#555" />
            <View style={styles.formRowContent}>
              <Text style={styles.formRowTitle}>Location*</Text>
              <Text style={styles.address}>{this.state.currentAddress}</Text>
              <View>
                <MapView
                    style={styles.mapPreview}
                    region={this.state.mapRegion}
                    onRegionChange={this._onMapRegionChange.bind(this)}/>
                <View
                  style={styles.mapOverlay}>
                  <Icon.Button name="my-location" backgroundColor="#2974aa"  color="#FFF" onPress={this._chooseLocation.bind(this)}>Change location</Icon.Button>
                </View>
              </View>
            </View>
          </View>

          <View style={styles.formRow}>
            <Icon style={styles.formRowIcon} name="photo-camera" size={24} color="#555" />
            <View style={styles.notStretchRowContent}>
              <Text style={styles.formRowTitle}>Pictures</Text>
              <TouchableHighlight style={styles.pictureFrame} underlayColor="#EEE" onPress={this._addPicture.bind(this)}>
                <View>
                  <Icon name="add-a-photo" size={24} color="#555" />
                  <Text>Add</Text>
                </View>
              </TouchableHighlight>
              <Image style={styles.pictureFrame} source={this.state.avatarSource} />
            </View>
          </View>

          <View style={styles.formRow}>
            <Icon style={styles.formRowIcon} name="description" size={24} color="#555" />
            <View style={styles.formRowContent}>
              <Text style={styles.formRowTitle}>Description</Text>
              <View style={styles.formRowContent}>
                <TextInput
                    style={styles.input}
                    placeholder="Ex: Best take off is facing east. Watch out for fire ants!"
                    placeholderTextColor="#888"
                    keyboardAppearance="dark"
                    underlineColorAndroid="#555"
                    returnKeyType="next"
                    editable={true}
                    multiline={true}
                    spellCheck={false}
                    numberOfLines={3}
                    maxLength={1000} />
              </View>

            </View>
          </View>

          <View style={styles.formRow}>
            <Icon style={styles.formRowIcon} name="star" size={24} color="#555" />
            <View style={styles.notStretchRowContent}>
              <Text style={styles.formRowTitle}>Ratings</Text>
              <StarRating
                  maxStars={5}
                  starSize={28}
                  starColor={"#555"}
                  emptyStarColor={"#555"}
                  halfStar={'star-half-full'}
                  emptyStar={'star-o'}
                  fullStar={'star'}
                  iconSet={'FontAwesome'}
                  rating={2.5}/>
              <Text style={styles.ratings_section_count}>5 reviews</Text>
            </View>
          </View>

          <Modal
              isVisible={this.state.isMapModalVisible}
              onBackButtonPress={this._chooseLocationDone.bind(this)}
              onModalHide={this._updateAddress.bind(this)}>
            <View style={styles.modalStyle}>
              <MapView
                  style={styles.fullMap}
                  region={this.state.mapRegion}
                  onRegionChange={this._onMapRegionChange.bind(this)}/>
              <View style={styles.fullMapCenterMarker}>
                <Icon name="location-on" size={32} color="#C11" />
              </View>
              <View style={styles.fullMapDoneButton}>
                <Icon.Button name="my-location" backgroundColor="#2974aa"  color="#FFF" onPress={this._chooseLocationDone.bind(this)}>Change location</Icon.Button>
              </View>
            </View>
          </Modal>
        </ScrollView>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: "#fff",
    flexDirection: 'column',
    paddingTop: 4,
    paddingBottom: 32
  },
  formRow: {
    flexDirection: 'row',
    marginLeft: 16,
    marginRight: 16,
    marginTop: 16,
  },
  formRowIcon: {
    marginRight:24,
  },
  formRowContent: {
    flexDirection: 'column',
    flex: 1
  },
  notStretchRowContent: {
    flexDirection: 'column'
  },
  formRowTitle: {
    marginTop: 4,
    marginBottom: 4,
    fontSize: 12
  },
  mapPreview: {
    height: 100,
  },
  modalStyle: {
    flex: 1,
    flexDirection: 'column',
    alignItems: 'center',
    justifyContent: 'flex-end',
  },
  fullMap: {
    flex: 1,
    position: 'absolute',
    top: 0,
    bottom: 0,
    left: 0,
    right: 0,
  },
  fullMapCenterMarker: {
    position: 'absolute',
    top: 0,
    bottom: 0,
    left: 0,
    right: 0,
    flex: 1,
    flexDirection: 'column',
    justifyContent: 'center',
    alignItems: 'center',
  },
  fullMapDoneButton: {
    marginBottom: 32,
    flexDirection: 'row'
  },
  mapOverlay: {
    flex: 1,
    height: 100,
    position: 'absolute',
    top: 0,
    left: 0,
    right: 0,
    backgroundColor: 'rgba(255, 255, 255, 0.35)',
    justifyContent: 'center',
    alignItems: 'center'
  },
  address: {
    textAlign: 'left',
    color: "#333"
  },
  pictureFrame: {
    width: 75,
    height: 75,
    borderColor: "#555",
    borderWidth: 1,
    borderRadius: 4,
    justifyContent: 'center',
    alignItems: 'center'
  },
  input: {
    marginTop: -8,
    color: "#333",
  },

  image: {
    height: 190
  },
  imageContainer: {
    position: 'absolute',
    top: 0,
    left: 0,
    right: 0,
  },
  action_button: {
    margin: 4
  }
});

export default SpotDetail;<commit_msg>Validating Spot data before saving; some ui fixes<commit_after>import React, { Component } from 'react';
import {
  ScrollView,
  TouchableHighlight,
  StyleSheet,
  Image,
  Text,
  TextInput,
  Alert,
  View,
  Platform
} from 'react-native';

import { Navigation } from 'react-native-navigation';
import Icon from 'react-native-vector-icons/MaterialIcons';
import MapView from 'react-native-maps';
import Modal from 'react-native-modal'
import ImagePicker from 'react-native-image-picker';
import Parse from 'parse/react-native';

import Location from '../../helpers/Location';

const SHOW_DURATION = 300;
const HIDE_DURATION = 250;

const INITIAL_LAT = 37.78825;
const INITIAL_LON =-122.4324;
const INITIAL_LAT_DELTA = 0.0922;
const INITIAL_LON_DELTA = 0.0421;

class SpotDetail extends Component {

  state = {
    isMapModalVisible: false,
    imageAnimationType: 'fadeInDown',
    contentAnimationType: 'fadeInRight',
    animationDuration: SHOW_DURATION,

    name: "",
    description: "",
    currentAddress: '?',
    picture: null,
    mapRegion: {
      latitude: INITIAL_LAT,
      longitude: INITIAL_LON,
      latitudeDelta: INITIAL_LAT_DELTA,
      longitudeDelta: INITIAL_LON_DELTA
    }
  };

  constructor(props) {
    super(props);
    this.props.navigator.setOnNavigatorEvent(this.onNavigatorEvent.bind(this));

    this.props.navigator.setTitle({
      title: 'New paramotor spot'
    });
    this.props.navigator.setButtons({
      rightButtons: [{
        icon: globalIconMap['send'],
        title: 'save',
        id: 'save_spot'
      }]
    });

  }

  componentDidMount() {
    navigator.geolocation.getCurrentPosition(
        (pos) => {
          let mapRegion = {latitudeDelta: INITIAL_LAT_DELTA, longitudeDelta: INITIAL_LON_DELTA};
          mapRegion.latitude = pos.coords.latitude;
          mapRegion.longitude = pos.coords.longitude;
          this.setState({mapRegion});
          this._updateAddress();
        },
        (error) => console.log(JSON.stringify(error)),
        {enableHighAccuracy: true, timeout: 20000, maximumAge: 1000}
    );
  }

  onNavigatorEvent(event) {
    if (event.id === 'backPress') {
      this.setState({
        imageAnimationType: 'fadeOutUp',
        contentAnimationType: 'fadeOutRight',
        animationDuration: HIDE_DURATION
      });
      this.props.navigator.pop();
    } else if (event.id === 'save_spot') {
      this._save();
    }
  }

  _chooseLocation() {
    this.setState({ isMapModalVisible: true });
  }

  _chooseLocationDone() {
    this.setState({ isMapModalVisible: false });
  }

  _onMapRegionChange(mapRegion) {
    this.setState({ mapRegion });
  }

  _updateAddress() {
    Location.getAddress(this.state.mapRegion.latitude, this.state.mapRegion.longitude,
        (err, result) => {
          if (result) {
            let address = (result.streetName ? result.streetName + ", " : "")
                + (result.city ? result.city + ", " : "")
                + (result.administrativeLevels.level1short ? result.administrativeLevels.level1short + "." : "");
            this.setState({currentAddress: (address || "?")});
          }
        }
    );
  }

  _addPicture() {
    const options = {
      title: 'Add picture',
      takePhotoButtonTitle: 'Use camera',
      chooseFromLibraryButtonTitle: 'Pick from gallery',
      mediaType: 'photo',
      maxWidth: 1280,
      maxHeight: 720,
      quality: 0.9,
      storageOptions: {
        skipBackup: true,
        path: 'images'
      }
    };
    ImagePicker.showImagePicker(options, (response) => {
      if (response.didCancel) {
        console.log('User cancelled image picker');
      } else if (response.error) {
        console.log('ImagePicker Error: ', response.error);
      } else {
        let source = { uri: response.uri };
        this.setState({
          picture: source
        });
      }
    });
  }

  _save() {
    if (!this._validateData()) {
      return;
    }
  }

  _validateData() {
    let error;
    if (!this.state.name || this.state.name.length < 5) {
      error = "The name must be at least 5 characters."
    }
    if (!this.state.mapRegion || !this.state.mapRegion.latitude || !this.state.mapRegion.longitude) {
      error = "The current location cannot be identified. Please use the map to select a location."
    }
    if (error) {
      Alert.alert('Oops', error, [{text: 'Got it'}]);
    }
    return !error;
  }

  render() {
    return (
        <ScrollView style={styles.container}>
          <View style={styles.formRow}>
            <Icon style={styles.formRowIcon} name="info-outline" size={24} color="#555" />

            <View style={styles.formRowContent}>
              <Text style={styles.formRowTitle}>Name*</Text>
              <View style={styles.formRowContent}>
                <TextInput
                    style={styles.input}
                    placeholder="Ex: Valkaria airport"
                    placeholderTextColor="#888"
                    keyboardAppearance="dark"
                    underlineColorAndroid="#555"
                    returnKeyType="next"
                    editable={true}
                    multiline={false}
                    spellCheck={false}
                    numberOfLines={1}
                    maxLength={70}
                    onChangeText={(name) => this.setState({name})} />
              </View>
            </View>
          </View>

          <View style={styles.formRow}>
            <Icon style={styles.formRowIcon} name="location-on" size={24} color="#555" />
            <View style={styles.formRowContent}>
              <Text style={styles.formRowTitle}>Location*</Text>
              <Text style={styles.address}>{this.state.currentAddress}</Text>
              <View>
                <MapView
                    style={styles.mapPreview}
                    region={this.state.mapRegion}
                    onRegionChange={this._onMapRegionChange.bind(this)}/>
                <View
                  style={styles.mapOverlay}>
                  <Icon.Button name="my-location" backgroundColor="#2974aa"  color="#FFF" onPress={this._chooseLocation.bind(this)}>Change location</Icon.Button>
                </View>
              </View>
            </View>
          </View>

          <View style={styles.formRow}>
            <Icon style={styles.formRowIcon} name="photo-camera" size={24} color="#555" />
            <View style={styles.notStretchRowContent}>
              <Text style={styles.formRowTitle}>Pictures</Text>
              <View style={{flexDirection: 'row'}}>
                <Image style={styles.pictureFrame} source={this.state.picture} />
                <TouchableHighlight style={styles.pictureFrame} underlayColor="#EEE" onPress={this._addPicture.bind(this)}>
                  <View>
                    <Icon name="add-a-photo" size={24} color="#555" />
                    <Text>Add</Text>
                  </View>
                </TouchableHighlight>
              </View>
            </View>
          </View>

          <View style={styles.formRow}>
            <Icon style={styles.formRowIcon} name="description" size={24} color="#555" />
            <View style={styles.formRowContent}>
              <Text style={styles.formRowTitle}>Description</Text>
              <View style={styles.formRowContent}>
                <TextInput
                    style={styles.input}
                    placeholder="Ex: Best take off is facing east. Watch out for fire ants!"
                    placeholderTextColor="#888"
                    keyboardAppearance="dark"
                    underlineColorAndroid="#555"
                    returnKeyType="next"
                    editable={true}
                    multiline={true}
                    spellCheck={false}
                    numberOfLines={3}
                    maxLength={1000}
                    onChangeText={(description) => this.setState({description})} />
              </View>

            </View>
          </View>

          <Modal
              isVisible={this.state.isMapModalVisible}
              onBackButtonPress={this._chooseLocationDone.bind(this)}
              onModalHide={this._updateAddress.bind(this)}>
            <View style={styles.modalStyle}>
              <MapView
                  style={styles.fullMap}
                  region={this.state.mapRegion}
                  onRegionChange={this._onMapRegionChange.bind(this)}/>
              <View style={styles.fullMapCenterMarker}>
                <Icon name="location-on" size={32} color="#C11" />
              </View>
              <View style={styles.fullMapDoneButton}>
                <Icon.Button name="my-location" backgroundColor="#2974aa"  color="#FFF" onPress={this._chooseLocationDone.bind(this)}>Change location</Icon.Button>
              </View>
            </View>
          </Modal>
        </ScrollView>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: "#fff",
    flexDirection: 'column',
    paddingTop: 4,
    paddingBottom: 32
  },
  formRow: {
    flexDirection: 'row',
    marginLeft: 16,
    marginRight: 16,
    marginTop: 16,
  },
  formRowIcon: {
    marginRight:24,
  },
  formRowContent: {
    flexDirection: 'column',
    flex: 1
  },
  notStretchRowContent: {
    flexDirection: 'column'
  },
  formRowTitle: {
    marginTop: 4,
    marginBottom: 4,
    fontSize: 12
  },
  mapPreview: {
    height: 100,
  },
  modalStyle: {
    flex: 1,
    flexDirection: 'column',
    alignItems: 'center',
    justifyContent: 'flex-end',
  },
  fullMap: {
    flex: 1,
    position: 'absolute',
    top: 0,
    bottom: 0,
    left: 0,
    right: 0,
  },
  fullMapCenterMarker: {
    position: 'absolute',
    top: 0,
    bottom: 0,
    left: 0,
    right: 0,
    flex: 1,
    flexDirection: 'column',
    justifyContent: 'center',
    alignItems: 'center',
  },
  fullMapDoneButton: {
    marginBottom: 32,
    flexDirection: 'row'
  },
  mapOverlay: {
    flex: 1,
    height: 100,
    position: 'absolute',
    top: 0,
    left: 0,
    right: 0,
    backgroundColor: 'rgba(255, 255, 255, 0.35)',
    justifyContent: 'center',
    alignItems: 'center'
  },
  address: {
    textAlign: 'left',
    color: "#333"
  },
  pictureFrame: {
    width: 75,
    height: 75,
    marginRight: 8,
    borderColor: "#555",
    borderWidth: 1,
    borderRadius: 4,
    justifyContent: 'center',
    alignItems: 'center'
  },
  input: {
    marginTop: -8,
    color: "#333",
  }
});

export default SpotDetail;<|endoftext|>


<commit_before>/**---------------------------------------------------------------------------------------------------------------------
 * tgi-spec/lib/tgi-spec.test.js
 */
spec.test('lib/tgi-spec', 'Spec Constructor Function', function (callback) {
  callback({log: 'TEST_SPEC.shit tgi-spec/lib/tgi-spec.test.js'});
  var test = spec;
  test.heading('Spec', function () {
    test.paragraph('We are spec!');
    test.example('code with no errors', undefined, function () {
      // Hello World
    });
    test.example('code with expected return value', true, function () {
      return true;
    });
    test.example('errors can be returned', Error('wrong'), function () {
      return Error('wrong');
    });
    test.example('errors can be thrown', Error('wrong'), function () {
      throw Error('wrong');
    });
    test.example('expectedValue can be asynchronous', spec.asyncResults(42), function (callback) {
      setTimeout(function () {
        callback(42);
      }, 0);
    });
  });
});
<commit_msg>close to fin<commit_after>/**---------------------------------------------------------------------------------------------------------------------
 * tgi-spec/lib/tgi-spec.test.js
 */
spec.test('lib/tgi-spec', 'Spec Constructor Function', function (callback) {
  callback({log: 'TEST_SPEC.shit tgi-spec/lib/tgi-spec.test.js'});
  var test = spec;
  test.heading('TGI SPEC', function () {
    test.paragraph('Javascript test and spec documentation framework.');
    test.heading('METHODS', function () {
      test.heading('example(text, results, testFunction)', function () {
        test.paragraph('The example function provides a test description, expected outcome and funtion to invoke for test.');
        test.example('code with no errors', undefined, function () {
          // Hello World
        });
        test.example('code with expected return value', true, function () {
          return true;
        });
        test.example('errors can be returned', Error('wrong'), function () {
          return Error('wrong');
        });
        test.example('errors can be thrown', Error('wrong'), function () {
          throw Error('wrong');
        });
        test.example('expectedValue can be asynchronous', spec.asyncResults(42), function (callback) {
          setTimeout(function () {
            callback(42);
          }, 0);
        });
      });
    });
  });
});
<|endoftext|>


<commit_before>'use strict';

const sample = require('lodash.sample');
const fs = require('fs');
const ms = require('ms');
const cache = require('./cache');
const search = require('./search');
const platform = require('./platform');
const messages = require('./messages');
const parser = require('./parser');
const render = require('./render');
const index = require('./index');
const exit = process.exit;

exports.list = (singleColumn) => {
  let os = platform.getPreferredPlatformFolder();
  index.commandsFor(os, (commands) => {
    printPages(commands, singleColumn);
  });
};

exports.listAll = (singleColumn) => {
  index.commands((commands) => {
    printPages(commands, singleColumn);
  });
};

exports.get = (commands, options) => {
  printBestPage(commands.join('-'), options);
};

exports.random = () => {
  let os = platform.getPreferredPlatformFolder();
  index.commandsFor(os, (pages) => {
    if (pages.length === 0) {
      console.error(messages.emptyCache());
      exit(1);
    }
    let page = sample(pages);
    console.log('PAGE', page);
    printBestPage(page);
  });
};

exports.randomExample = () => {
  let os = platform.getPreferredPlatformFolder();
  index.commandsFor(os, (pages) => {
    if (pages.length === 0) {
      console.error(messages.emptyCache());
      exit(1);
    }
    let page = sample(pages);
    console.log('PAGE', page);
    printBestPage(page, {randomExample: true});
  });
};

exports.render = (file) => {
  // Reading the file
  fs.readFile(file, 'utf8', (err, content) => {
    if (err) {
      console.error(err);
      exit(1);
    }
    // Getting the shortindex first to populate the shortindex var
    index.getShortIndex(() => {
      renderContent(content, {});
    });
  });
};

exports.clearCache = () => {
  cache.clear(() => {
    console.log('Done');
  });
};

exports.updateCache = () => {
  console.log('Updating...');
  return new Promise(function(resolve, reject) {
    cache.update((err) => {
      if (err) {
        console.error(err);
        exit(1);
        reject(err);
      } else {
        console.log('Done');
        resolve();
      }
    });
  });
};

exports.updateIndex = () => {
  console.log('Creating index...');
  search.createIndex()
    .then(() => {
      console.log('Done');
    })
    .catch((err) => {
      console.error(err);
    });
};

exports.search = (keywords) => {
  search.getResults(keywords.join(' '))
    .then((results) => {
      search.printResults(results);
    })
    .catch((err) => {
      console.error(err);
    });
};

function printPages(pages, singleColumn) {
  if (pages.length === 0) {
    console.error(messages.emptyCache());
    exit(1);
  }
  checkStale();
  let endOfLine = require('os').EOL;
  let delimiter = singleColumn ? endOfLine : ', ';
  console.log('\n' + pages.join(delimiter));
}

function printBestPage(command, options) {
  // TODO: replace with default parameter if Node v4 support dropped.
  options = options || {};
  /* eslint-disable */ // To allow not checking for err
  // Trying to get the page from cache first
  cache.getPage(command, (err, content) => {
  /* eslint-enable */
    if (!content) {
      // If not found, try to update
      console.log('Page not found. Updating cache ..');
      cache.update((err) => {
        if (err) {
          console.error(err);
          exit(1);
        }
        console.log('Creating index...');
        search.createIndex()
          .then(() => {
            console.log('Done');
            // And then, try to check in cache again
            cache.getPage(command, (err, content2) => {
              if (err) {
                console.error(err);
                exit(1);
              }
              if (!content2) {
                console.error(messages.notFound());
                exit(1);
              } else {
                checkStale();
                renderContent(content2, options);
              }
            });
          })
          .catch((err) => {
            console.error(err);
          });
      });
    } else { // If found in first try, render it
      checkStale();
      renderContent(content, options);
    }
  });
}

function renderContent(content, options) {
  if (options.markdown) {
    return console.log(content);
  }
  let page = parser.parse(content);
  if (options && options.randomExample === true) {
    page.examples = [sample(page.examples)];
  }
  let output = render.toANSI(page);
  console.log(output);
}

function checkStale() {
  cache.lastUpdated((err, stats) => {
    if (err) {
      console.error(err);
      exit(1);
    }
    if (stats.mtime < Date.now() - ms('30d')) {
      console.warn('Cache is out of date, you should run "tldr --update"');
    }
  });
}
<commit_msg>Using node default params<commit_after>'use strict';

const sample = require('lodash.sample');
const fs = require('fs');
const ms = require('ms');
const cache = require('./cache');
const search = require('./search');
const platform = require('./platform');
const messages = require('./messages');
const parser = require('./parser');
const render = require('./render');
const index = require('./index');
const exit = process.exit;

exports.list = (singleColumn) => {
  let os = platform.getPreferredPlatformFolder();
  index.commandsFor(os, (commands) => {
    printPages(commands, singleColumn);
  });
};

exports.listAll = (singleColumn) => {
  index.commands((commands) => {
    printPages(commands, singleColumn);
  });
};

exports.get = (commands, options) => {
  printBestPage(commands.join('-'), options);
};

exports.random = () => {
  let os = platform.getPreferredPlatformFolder();
  index.commandsFor(os, (pages) => {
    if (pages.length === 0) {
      console.error(messages.emptyCache());
      exit(1);
    }
    let page = sample(pages);
    console.log('PAGE', page);
    printBestPage(page);
  });
};

exports.randomExample = () => {
  let os = platform.getPreferredPlatformFolder();
  index.commandsFor(os, (pages) => {
    if (pages.length === 0) {
      console.error(messages.emptyCache());
      exit(1);
    }
    let page = sample(pages);
    console.log('PAGE', page);
    printBestPage(page, {randomExample: true});
  });
};

exports.render = (file) => {
  // Reading the file
  fs.readFile(file, 'utf8', (err, content) => {
    if (err) {
      console.error(err);
      exit(1);
    }
    // Getting the shortindex first to populate the shortindex var
    index.getShortIndex(() => {
      renderContent(content);
    });
  });
};

exports.clearCache = () => {
  cache.clear(() => {
    console.log('Done');
  });
};

exports.updateCache = () => {
  console.log('Updating...');
  return new Promise(function(resolve, reject) {
    cache.update((err) => {
      if (err) {
        console.error(err);
        exit(1);
        reject(err);
      } else {
        console.log('Done');
        resolve();
      }
    });
  });
};

exports.updateIndex = () => {
  console.log('Creating index...');
  search.createIndex()
    .then(() => {
      console.log('Done');
    })
    .catch((err) => {
      console.error(err);
    });
};

exports.search = (keywords) => {
  search.getResults(keywords.join(' '))
    .then((results) => {
      search.printResults(results);
    })
    .catch((err) => {
      console.error(err);
    });
};

function printPages(pages, singleColumn) {
  if (pages.length === 0) {
    console.error(messages.emptyCache());
    exit(1);
  }
  checkStale();
  let endOfLine = require('os').EOL;
  let delimiter = singleColumn ? endOfLine : ', ';
  console.log('\n' + pages.join(delimiter));
}

function printBestPage(command, options={}) {
  /* eslint-disable */ // To allow not checking for err
  // Trying to get the page from cache first
  cache.getPage(command, (err, content) => {
  /* eslint-enable */
    if (!content) {
      // If not found, try to update
      console.log('Page not found. Updating cache ..');
      cache.update((err) => {
        if (err) {
          console.error(err);
          exit(1);
        }
        console.log('Creating index...');
        search.createIndex()
          .then(() => {
            console.log('Done');
            // And then, try to check in cache again
            cache.getPage(command, (err, content2) => {
              if (err) {
                console.error(err);
                exit(1);
              }
              if (!content2) {
                console.error(messages.notFound());
                exit(1);
              } else {
                checkStale();
                renderContent(content2, options);
              }
            });
          })
          .catch((err) => {
            console.error(err);
          });
      });
    } else { // If found in first try, render it
      checkStale();
      renderContent(content, options);
    }
  });
}

function renderContent(content, options) {
  if (options.markdown) {
    return console.log(content);
  }
  let page = parser.parse(content);
  if (options && options.randomExample === true) {
    page.examples = [sample(page.examples)];
  }
  let output = render.toANSI(page);
  console.log(output);
}

function checkStale() {
  cache.lastUpdated((err, stats) => {
    if (err) {
      console.error(err);
      exit(1);
    }
    if (stats.mtime < Date.now() - ms('30d')) {
      console.warn('Cache is out of date, you should run "tldr --update"');
    }
  });
}
<|endoftext|>