<commit_before>#!/usr/bin/env node

var argv = require('optimist')
    .usage('\nUpdate AWS security groups with cloudfront IP\'s.\n\nUsage: $0 arg1..argn')
    .demand(1)
    .describe('arg1..argn', 'One or more security group ID\'s')
    .demand('r')
    .alias('r', 'region')
    .describe('r', 'The AWS Region (i.e. eu-west-1, etc)')
    .alias('k', 'accesskey')
    .describe('k', 'The AWS Access key; omit to retrieve from default AWS config')
    .alias('s', 'secret')
    .describe('s', 'The AWS Access key secret; omit to retrieve from default AWS config')
    .demand('p')
    .alias('p', 'port')
    .default('p', [80])
    .describe('p', 'The ports to open for Cloudfront')
    .boolean('u')
    .alias('u', 'update')
    .default('u', false)
    .describe('u', 'set flag to actually update the security groups')
    .boolean('force')
    .default('force', false)
    .describe('force', 'skip interactive and confirmation questions')
    .argv;

var Seq = require('seq');
var AWS = require('aws-sdk');
var RL = require('readline').createInterface({
    input: process.stdin,
    output: process.stdout
});
RL.proceed = function(success,error) {
    this.question('Proceed?',function(answer) {
        console.log(answer);
        if (answer == 'Y' || answer == 'y' || answer == 'YES' || answer == 'yes') {
             success();
        } else {
            error();
        }
    });
};

if (argv.port.constructor !== Array) {
    argv.port = [argv.port];
}

// Set your region and further aws credentials for uture requests
AWS.config.update({
    region: argv.region,
    accessKeyId: argv.accesskey,
    secretAccessKey: argv.secret
});
var EC2 = new AWS.EC2({apiVersion: '2015-10-01', maxRetries: 2});

Seq()
    .seq(function () {
        var _self = this;
        this.vars.cloudFrontIps = [];
        this.vars.securityGroupIds = argv._;
        this.vars.securityGroups = [];
        this.vars.ports = argv.port;
        this.vars.dryrun = !argv.update;
        this.vars.hasError = false;
        this.vars.force = argv.force;

        console.log('');
        console.log('Update AWS security groups %s with cloudfront IP\'s for ports %s', this.vars.securityGroupIds.join(', '), this.vars.ports.join(', '));
        console.log(this.vars.dryrun ? 'Running in DRYRUN mode' : 'Running in UPDATE mode');
        console.log('');

        if (!this.vars.force) {
            RL.proceed(function() {
                _self();
            }, function() {
                _self('aborted');
            });
        } else {
            _self();
        }

    })
    // load cloudfront ips
    .seq(function () {
        var _self = this;
        var request = require("request");
        request('https://ip-ranges.amazonaws.com/ip-ranges.json', function (error, response, body) {
            if (!error && response.statusCode == 200) {
                var awsIps = JSON.parse(response.body);
                for (var prefixIndex in awsIps.prefixes) {
                    var prefix = awsIps.prefixes[prefixIndex];
                    if (prefix.service == 'CLOUDFRONT') {
                        _self.vars.cloudFrontIps.push(prefix.ip_prefix);
                    }
                }
                console.log('loaded AWS Cloudfront IPs:' + _self.vars.cloudFrontIps.join(', '));
                _self();
            } else {
                _self("Couldn't load AWS IPS");
            }
        })
    })
    // load security groups
    .empty()
    .par(function () {
        var _self = this;
        var params = {
            DryRun: false,
            GroupIds: _self.vars.securityGroupIds
        };
        EC2.describeSecurityGroups(params, function (err, data) {
            if (err) {
                _self(err);
            }
            for (var j in data.SecurityGroups) {
                var securityGroup = data.SecurityGroups[j];
                securityGroup.hasIngressPermission = function (protocol, ip, fromPort, toPort) {
                    for (var j in this.IpPermissions) {
                        var ipPermissions = this.IpPermissions[j];
                        if (ipPermissions.IpProtocol == protocol && ipPermissions.FromPort == fromPort && ipPermissions.ToPort == toPort) {
                            for (var k in ipPermissions.IpRanges) {
                                if (ipPermissions.IpRanges[k].CidrIp == ip) {
                                    return true;
                                }
                            }
                        }
                    }
                    return false;
                };
                _self.vars.securityGroups.push(securityGroup);
                console.log('loaded description of security group ' + securityGroup.GroupId);
            }
            _self(null, _self.vars.securityGroups);
        });
    })
    .flatten()
    .seqFilter(function (securityGroup) {
        var _self = this;
        var rulesAdded = 0;
        var groupID = securityGroup.GroupId;
        console.log('\nupdating security group %s with %d ip ranges', groupID,_self.vars.cloudFrontIps.length);

        var params = {
            DryRun: this.vars.dryrun,
            GroupId: groupID,
            IpPermissions: []
        };
        // add allowances for each ports
        for (var pI in this.vars.ports) {
            var port = this.vars.ports[pI];
            console.log('adding %d rules for security group %s for port %d', _self.vars.cloudFrontIps.length,groupID, port);
            var permissions = {
                FromPort: port,
                ToPort: port,
                IpProtocol: 'TCP',
                IpRanges: []
            };
            for (var ipPrefix in _self.vars.cloudFrontIps) {
                if (securityGroup.hasIngressPermission('tcp', _self.vars.cloudFrontIps[ipPrefix], port, port)) {
                    // skip ingress permission
                } else {
                    permissions.IpRanges.push({
                        CidrIp: _self.vars.cloudFrontIps[ipPrefix]
                    });
                    console.log('adding rule to security group: ALLOW TCP for port %s to IP Range %s', port, _self.vars.cloudFrontIps[ipPrefix]);
                    rulesAdded++;
                }
            }
            if (permissions.IpRanges.length > 0) {
                params.IpPermissions.push(permissions);
            }
        }
        if (rulesAdded > 0) {
            console.log("Adding %d rules to security group %s", rulesAdded, groupID);

            var apply = function() {
                EC2.authorizeSecurityGroupIngress(params, function (err, data) {
                    if (err) {
                        if (err.code != 'DryRunOperation') {
                            console.error('Error: %s', err.message);
                            _self.vars.hasError = true;
                            _self();
                        } else {
                            // dryrun
                            console.log('skipped - dryrun mode; ' + err.message);
                            _self();
                        }
                    } else {
                        console.log('OK');
                        _self();
                    }
                });
            };

            if (!this.vars.force) {
                RL.proceed(function() {
                    apply();
                }, function() {
                    _self();
                });
            } else {
                apply();
            }

        } else {
            console.log('nothing to do for security group %s, all ip ranges present.', groupID);
            this();
        }
    }).seq(function () {
        if (this.vars.hasError) {
            this('An error occurred');
        } else {
            console.log('');
            console.log('done.');
            RL.close();
        }
    }).catch(function (err) {
        console.error(err.stack ? err.stack : err);
        RL.close();
    });

// end
<commit_msg>short circuit sequence on sdk error<commit_after>#!/usr/bin/env node

var argv = require('optimist')
    .usage('\nUpdate AWS security groups with cloudfront IP\'s.\n\nUsage: $0 arg1..argn')
    .demand(1)
    .describe('arg1..argn', 'One or more security group ID\'s')
    .demand('r')
    .alias('r', 'region')
    .describe('r', 'The AWS Region (i.e. eu-west-1, etc)')
    .alias('k', 'accesskey')
    .describe('k', 'The AWS Access key; omit to retrieve from default AWS config')
    .alias('s', 'secret')
    .describe('s', 'The AWS Access key secret; omit to retrieve from default AWS config')
    .demand('p')
    .alias('p', 'port')
    .default('p', [80])
    .describe('p', 'The ports to open for Cloudfront')
    .boolean('u')
    .alias('u', 'update')
    .default('u', false)
    .describe('u', 'set flag to actually update the security groups')
    .boolean('force')
    .default('force', false)
    .describe('force', 'skip interactive and confirmation questions')
    .argv;

var Seq = require('seq');
var AWS = require('aws-sdk');
var RL = require('readline').createInterface({
    input: process.stdin,
    output: process.stdout
});
RL.proceed = function(success,error) {
    this.question('Proceed?',function(answer) {
        console.log(answer);
        if (answer == 'Y' || answer == 'y' || answer == 'YES' || answer == 'yes') {
             success();
        } else {
            error();
        }
    });
};

if (argv.port.constructor !== Array) {
    argv.port = [argv.port];
}

// Set your region and further aws credentials for uture requests
AWS.config.update({
    region: argv.region,
    accessKeyId: argv.accesskey,
    secretAccessKey: argv.secret
});
var EC2 = new AWS.EC2({apiVersion: '2015-10-01', maxRetries: 2});

Seq()
    .seq(function () {
        var _self = this;
        this.vars.cloudFrontIps = [];
        this.vars.securityGroupIds = argv._;
        this.vars.securityGroups = [];
        this.vars.ports = argv.port;
        this.vars.dryrun = !argv.update;
        this.vars.hasError = false;
        this.vars.force = argv.force;

        console.log('');
        console.log('Update AWS security groups %s with cloudfront IP\'s for ports %s', this.vars.securityGroupIds.join(', '), this.vars.ports.join(', '));
        console.log(this.vars.dryrun ? 'Running in DRYRUN mode' : 'Running in UPDATE mode');
        console.log('');

        if (!this.vars.force) {
            RL.proceed(function() {
                _self();
            }, function() {
                _self('aborted');
            });
        } else {
            _self();
        }

    })
    // load cloudfront ips
    .seq(function () {
        var _self = this;
        var request = require("request");
        request('https://ip-ranges.amazonaws.com/ip-ranges.json', function (error, response, body) {
            if (!error && response.statusCode == 200) {
                var awsIps = JSON.parse(response.body);
                for (var prefixIndex in awsIps.prefixes) {
                    var prefix = awsIps.prefixes[prefixIndex];
                    if (prefix.service == 'CLOUDFRONT') {
                        _self.vars.cloudFrontIps.push(prefix.ip_prefix);
                    }
                }
                console.log('loaded AWS Cloudfront IPs:' + _self.vars.cloudFrontIps.join(', '));
                _self();
            } else {
                _self("Couldn't load AWS IPS");
            }
        })
    })
    // load security groups
    .empty()
    .par(function () {
        var _self = this;
        var params = {
            DryRun: false,
            GroupIds: _self.vars.securityGroupIds
        };
        EC2.describeSecurityGroups(params, function (err, data) {
            if (err) {
                return _self(err);
            }
            for (var j in data.SecurityGroups) {
                var securityGroup = data.SecurityGroups[j];
                securityGroup.hasIngressPermission = function (protocol, ip, fromPort, toPort) {
                    for (var j in this.IpPermissions) {
                        var ipPermissions = this.IpPermissions[j];
                        if (ipPermissions.IpProtocol == protocol && ipPermissions.FromPort == fromPort && ipPermissions.ToPort == toPort) {
                            for (var k in ipPermissions.IpRanges) {
                                if (ipPermissions.IpRanges[k].CidrIp == ip) {
                                    return true;
                                }
                            }
                        }
                    }
                    return false;
                };
                _self.vars.securityGroups.push(securityGroup);
                console.log('loaded description of security group ' + securityGroup.GroupId);
            }
            _self(null, _self.vars.securityGroups);
        });
    })
    .flatten()
    .seqFilter(function (securityGroup) {
        var _self = this;
        var rulesAdded = 0;
        var groupID = securityGroup.GroupId;
        console.log('\nupdating security group %s with %d ip ranges', groupID,_self.vars.cloudFrontIps.length);

        var params = {
            DryRun: this.vars.dryrun,
            GroupId: groupID,
            IpPermissions: []
        };
        // add allowances for each ports
        for (var pI in this.vars.ports) {
            var port = this.vars.ports[pI];
            console.log('adding %d rules for security group %s for port %d', _self.vars.cloudFrontIps.length,groupID, port);
            var permissions = {
                FromPort: port,
                ToPort: port,
                IpProtocol: 'TCP',
                IpRanges: []
            };
            for (var ipPrefix in _self.vars.cloudFrontIps) {
                if (securityGroup.hasIngressPermission('tcp', _self.vars.cloudFrontIps[ipPrefix], port, port)) {
                    // skip ingress permission
                } else {
                    permissions.IpRanges.push({
                        CidrIp: _self.vars.cloudFrontIps[ipPrefix]
                    });
                    console.log('adding rule to security group: ALLOW TCP for port %s to IP Range %s', port, _self.vars.cloudFrontIps[ipPrefix]);
                    rulesAdded++;
                }
            }
            if (permissions.IpRanges.length > 0) {
                params.IpPermissions.push(permissions);
            }
        }
        if (rulesAdded > 0) {
            console.log("Adding %d rules to security group %s", rulesAdded, groupID);

            var apply = function() {
                EC2.authorizeSecurityGroupIngress(params, function (err, data) {
                    if (err) {
                        if (err.code != 'DryRunOperation') {
                            console.error('Error: %s', err.message);
                            _self.vars.hasError = true;
                            _self();
                        } else {
                            // dryrun
                            console.log('skipped - dryrun mode; ' + err.message);
                            _self();
                        }
                    } else {
                        console.log('OK');
                        _self();
                    }
                });
            };

            if (!this.vars.force) {
                RL.proceed(function() {
                    apply();
                }, function() {
                    _self();
                });
            } else {
                apply();
            }

        } else {
            console.log('nothing to do for security group %s, all ip ranges present.', groupID);
            this();
        }
    }).seq(function () {
        if (this.vars.hasError) {
            this('An error occurred');
        } else {
            console.log('');
            console.log('done.');
            RL.close();
        }
    }).catch(function (err) {
        console.error(err.stack ? err.stack : err);
        RL.close();
    });

// end
<|endoftext|>


<commit_before>/**
  Copyright 2018 LNFWebsite
  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
      http://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.
**/

// * These are global variables that are utilized in the rest of the script
// * They exist for data that must persist for the script to work

if ($(window).width() <= 600) {
  var placeholder = "Search, Paste URL...";
  var loadingPlaceholder = "Loading...";
}
else {
  var placeholder = "Search, drag and drop video, or paste its URL...";
  var loadingPlaceholder = "Loading video data from YouTube...";
}
$("#inputBox").attr("placeholder", placeholder);

var faviconPause = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACIAAAAiCAMAAAANmfvwAAAA/1BMVEUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD64ociAAAAVHRSTlMAAQIDBAUGBwgJCgsPEBIUFxgbHh8iIyUrMDU/QEdKS09QUlZbXF5fYWZpb3F1e4aJmJ6go6WmqrK0tb7Aw8XHyM/R09XX2drg4unr7e/x8/X3+ftnm6MTAAABGklEQVQ4jYXTx1YCQRBG4TvCYKO2iglzxJwVA5gFs4LA//7P4mLIM9PeZfV3Tm26oC+vf9BTYu7wrib93hzMDkSCoaOG2tX2B0PA21FvjbU+YR4UquB3i5GPsJDK6Y4YjBTSU7JNbqOFdNkSG3FCWghEqhFPfhIA7EmSatYYY9JXUsYYY0wmMOsAXlWS9EbLN9cH5B1gRi6icWDbTVaACzc5AcpuUgQqblL6nzwDJTcpAOducgxsuskSMOUmY4D37SKvAAS/tj5hrbWjBSlrrbU2G5BlAPyaYvtsXstyPJlvbuU6Tpy2BP5LtLjvOsrh1yjxmKIrvxgW+QS9rdZ7QXWRUP5upQO+csmwALzprXy5Uimd5SYj3+P7A3jQxmKOfWTQAAAAAElFTkSuQmCC";
var faviconPlay = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACIAAAAiCAMAAAANmfvwAAABDlBMVEUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABxUYW9AAAAWXRSTlMAAQIDBAUGCAkRFBUZGhscHiAhJyorLzI0ODo7PUZMTlBVVldYWVtcXV5hZHB1foKDiIuPlZiboKKlpqirr7CytcDDyMrMzs/R09Xa3N7g4ubp7e/x9/n7/Ud7aO4AAAE3SURBVBgZlcFpOxtRAIbhZ8YgltBaopZEHanamtKgtYaSklJ0xPL+/z8iGedMZq5MPrhv3mlgslzZ2aksT/aTbfpQsYMpun24UMr5OGneN3XZ9EjoO1KGA5+Yd6pMxx5OVT1sY31STwUifqg3jaF8TWn/fdo+y1oFCv+UUqLtXpahxSs/KeGOlrwcQ2TwhxJGgWU5Bit/ptgSsCfHEJu9l7ULXMkxdPgbL4r8AR7kGJLmFQmBphxD0pQiTeCvHEPC/IMiV8C+HENs7LesX8CaHIOVqyr2FZiQY4j4K8/q+Ah4TVmGtplbJYQeLRuyvgAjp0pZp63/SW/Ogtx3pT0GRErqqYh1oh6OcIKGMl0GxHKXylAfJCHYV5effaQthEoJ5+jiL94odl3yyTRc3KrV67Wt4jDv8wr7Zt73xzlZAQAAAABJRU5ErkJggg==";

var popup;
var searchClose = false;
var hotkeySearchClose = false;

var videoId;

var videos = [];
var videoCounter = 0;
var videoIteration = 0;

var videoErrorIds = [];

var videosBeforeShuffle = [];
var addedVideosWhileShuffled = [];

var baseAutoplayVideoId = false;
var autoplayList = false;
var autoplayVideos = [];
var autoplayVideoIteration = -1;

var quickSearchQuery;
var quickSearchVideos = [];
var quickSearchVideosIteration = 0;

var inBoxSearch = false;
var searchResultsIteration = 0;
var searchResultsNameStorage = [];

var stationServer;
var stationSocket;
var stationRemote = false;
var stationTxQuiet = false;
var stationUserId;

var zenMode = false;
var sideBySide = false;

var videoPaused;
//this var is for addVideo knowing whether to loop to next video or not
var videoPlaying;
var backRestart;
var backRestartTimer;

var progressTimer;

var playlistPlayNext;
var playlistRepeat;
var playlistShuffle;
var playlistAutoplay;

var dataPlayer;
var radioDataPlayer;
var searchDataPlayer;
<commit_msg>not sure what this was ever used for, but not needed<commit_after>/**
  Copyright 2018 LNFWebsite
  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
      http://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.
**/

// * These are global variables that are utilized in the rest of the script
// * They exist for data that must persist for the script to work

if ($(window).width() <= 600) {
  var placeholder = "Search, Paste URL...";
  var loadingPlaceholder = "Loading...";
}
else {
  var placeholder = "Search, drag and drop video, or paste its URL...";
  var loadingPlaceholder = "Loading video data from YouTube...";
}
$("#inputBox").attr("placeholder", placeholder);

var faviconPause = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACIAAAAiCAMAAAANmfvwAAAA/1BMVEUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD64ociAAAAVHRSTlMAAQIDBAUGBwgJCgsPEBIUFxgbHh8iIyUrMDU/QEdKS09QUlZbXF5fYWZpb3F1e4aJmJ6go6WmqrK0tb7Aw8XHyM/R09XX2drg4unr7e/x8/X3+ftnm6MTAAABGklEQVQ4jYXTx1YCQRBG4TvCYKO2iglzxJwVA5gFs4LA//7P4mLIM9PeZfV3Tm26oC+vf9BTYu7wrib93hzMDkSCoaOG2tX2B0PA21FvjbU+YR4UquB3i5GPsJDK6Y4YjBTSU7JNbqOFdNkSG3FCWghEqhFPfhIA7EmSatYYY9JXUsYYY0wmMOsAXlWS9EbLN9cH5B1gRi6icWDbTVaACzc5AcpuUgQqblL6nzwDJTcpAOducgxsuskSMOUmY4D37SKvAAS/tj5hrbWjBSlrrbU2G5BlAPyaYvtsXstyPJlvbuU6Tpy2BP5LtLjvOsrh1yjxmKIrvxgW+QS9rdZ7QXWRUP5upQO+csmwALzprXy5Uimd5SYj3+P7A3jQxmKOfWTQAAAAAElFTkSuQmCC";
var faviconPlay = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACIAAAAiCAMAAAANmfvwAAABDlBMVEUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABxUYW9AAAAWXRSTlMAAQIDBAUGCAkRFBUZGhscHiAhJyorLzI0ODo7PUZMTlBVVldYWVtcXV5hZHB1foKDiIuPlZiboKKlpqirr7CytcDDyMrMzs/R09Xa3N7g4ubp7e/x9/n7/Ud7aO4AAAE3SURBVBgZlcFpOxtRAIbhZ8YgltBaopZEHanamtKgtYaSklJ0xPL+/z8iGedMZq5MPrhv3mlgslzZ2aksT/aTbfpQsYMpun24UMr5OGneN3XZ9EjoO1KGA5+Yd6pMxx5OVT1sY31STwUifqg3jaF8TWn/fdo+y1oFCv+UUqLtXpahxSs/KeGOlrwcQ2TwhxJGgWU5Bit/ptgSsCfHEJu9l7ULXMkxdPgbL4r8AR7kGJLmFQmBphxD0pQiTeCvHEPC/IMiV8C+HENs7LesX8CaHIOVqyr2FZiQY4j4K8/q+Ah4TVmGtplbJYQeLRuyvgAjp0pZp63/SW/Ogtx3pT0GRErqqYh1oh6OcIKGMl0GxHKXylAfJCHYV5effaQthEoJ5+jiL94odl3yyTRc3KrV67Wt4jDv8wr7Zt73xzlZAQAAAABJRU5ErkJggg==";

var popup;
var searchClose = false;
var hotkeySearchClose = false;

var videos = [];
var videoCounter = 0;
var videoIteration = 0;

var videoErrorIds = [];

var videosBeforeShuffle = [];
var addedVideosWhileShuffled = [];

var baseAutoplayVideoId = false;
var autoplayList = false;
var autoplayVideos = [];
var autoplayVideoIteration = -1;

var quickSearchQuery;
var quickSearchVideos = [];
var quickSearchVideosIteration = 0;

var inBoxSearch = false;
var searchResultsIteration = 0;
var searchResultsNameStorage = [];

var stationServer;
var stationSocket;
var stationRemote = false;
var stationTxQuiet = false;
var stationUserId;

var zenMode = false;
var sideBySide = false;

var videoPaused;
//this var is for addVideo knowing whether to loop to next video or not
var videoPlaying;
var backRestart;
var backRestartTimer;

var progressTimer;

var playlistPlayNext;
var playlistRepeat;
var playlistShuffle;
var playlistAutoplay;

var dataPlayer;
var radioDataPlayer;
var searchDataPlayer;
<|endoftext|>


<commit_before>/**
 * Created by elad.benedict on 8/26/2015.
 */

var sinon = require('sinon');
var Q = require('q');
var _ = require('underscore');

var logger = require('../../common/logger').getLogger('BackendClientMock');

var entries=[{
    entryId : '1_xxxxx',
    flavorParamsIds: "32",
    serverType:"0",
    playWindow : 60*60*2
},{
    entryId : '0_et201h0y',
    flavorParamsIds: "32,33,34,35",
    serverType:"0",
    playWindow : 7200
}];

var entryServerNodes= {
    id: 1,
    data: [],
    findIndex:function(entryObject) {
       return _.findIndex(this.data, function (e) {
            return e.entryId==entryObject.entryId && entryObject.serverType=== e.serverType;
        });
    },
    add:function add(entryObject,state) {

        var index=this.findIndex(entryObject);
        if (index>-1) {
            this.data[index].updated= new Date();
        } else {
            this.data.push({
                entryId: entryObject.entryId,
                serverType: entryObject.serverType,
                state: state,
                id: this.id++,
                updated: new Date()
            });
        }
    },
    remove:  function removeEntryNode(entryObject) {
        var index=this.findIndex(entryObject);
        if (index>-1) {
            var obj=this.data[index];
            this.data.splice(index,1);
            return obj;
        }
        return null;
    },
    list:function(entryId) {
        return _.filter(this.data, function (e) {
            return e.entryId === entryId;
        });
    },
    updateStreamInfo:function( entryServerNodeId, flavorsObjArray) {
        var entryServerNode = _.find(this.data, function (e) {
            return e.id==entryServerNodeId;
        });
        if (entryServerNode) {
            entryServerNode.streamInfo=flavorsObjArray;
            return Q.resolve(entryServerNode);
        } else {
            return Q.reject("");
        }
    }
};

module.exports = {
    getLiveEntriesForMediaServer : Q.resolve(entries),
    getEntryInfo : function(entryId) {
        var res=_.find(entries,function(e) {
            return e.entryId===entryId || e.entryId==='*';
        });
        if (res) {
            var result=_.clone(res);
            result.entryId=entryId;
            return Q.resolve(result);
        }
        return Q.reject("No such entry");
    },
    registerEntryInDatabase : function(entryObject, state, event) {
        logger.info("[%s] Calling registerMediaServer, serverIndex: [%s], state=%s", entryObject.entryId,entryObject.serverType,state);

        return Q.resolve(entryServerNodes.add(entryObject,state));
    },
    unregisterEntryInDatabase: function(entryObject) {
        logger.info("[%s] Calling unregisterMediaServer, serverIndex: [%s]", entryObject.entryId,entryObject.serverType);
        entryServerNodes.remove(entryObject);
        return Q.resolve();
    },
    getLiveEntryServerNodes: function(entryId){
        logger.info("[%s] Calling getLiveEntryServerNodes]", entryId);
        return Q.resolve(entryServerNodes.list(entryId));
    },
    updateStreamInfo: function(entryId, entryServerNodeId, flavorsObjArray) {
        logger.debug("Calling updateStreamInfo, with new flavors object array %j",flavorsObjArray);
        return entryServerNodes.updateStreamInfo(entryServerNodeId,flavorsObjArray);
    }

};<commit_msg>PLAT-5586 typo<commit_after>/**
 * Created by elad.benedict on 8/26/2015.
 */

var sinon = require('sinon');
var Q = require('q');
var _ = require('underscore');

var logger = require('../../common/logger').getLogger('BackendClientMock');

var entries=[{
    entryId : '1_xxxxx',
    flavorParamsIds: "32",
    serverType:"0",
    playWindow : 60*60*2
},{
    entryId : '*',
    flavorParamsIds: "32,33,34,35", //,33,34,35
    serverType:"0",
    playWindow : 3600
}];

var entryServerNodes= {
    id: 1,
    data: [],
    findIndex:function(entryObject) {
       return _.findIndex(this.data, function (e) {
            return e.entryId==entryObject.entryId && entryObject.serverType=== e.serverType;
        });
    },
    add:function add(entryObject,state) {

        var index=this.findIndex(entryObject);
        if (index>-1) {
            this.data[index].updated= new Date();
        } else {
            this.data.push({
                entryId: entryObject.entryId,
                serverType: entryObject.serverType,
                state: state,
                id: this.id++,
                updated: new Date()
            });
        }
    },
    remove:  function removeEntryNode(entryObject) {
        var index=this.findIndex(entryObject);
        if (index>-1) {
            var obj=this.data[index];
            this.data.splice(index,1);
            return obj;
        }
        return null;
    },
    list:function(entryId) {
        return _.filter(this.data, function (e) {
            return e.entryId === entryId;
        });
    },
    updateStreamInfo:function( entryServerNodeId, flavorsObjArray) {
        var entryServerNode = _.find(this.data, function (e) {
            return e.id==entryServerNodeId;
        });
        if (entryServerNode) {
            entryServerNode.streamInfo=flavorsObjArray;
            return Q.resolve(entryServerNode);
        } else {
            return Q.reject("");
        }
    }
};

module.exports = {
    getLiveEntriesForMediaServer : Q.resolve(entries),
    getEntryInfo : function(entryId) {
        var res=_.find(entries,function(e) {
            return e.entryId===entryId || e.entryId==='*';
        });
        if (res) {
            var result=_.clone(res);
            result.entryId=entryId;
            return Q.resolve(result);
        }
        return Q.reject("No such entry");
    },
    registerEntryInDatabase : function(entryObject, state, event) {
        logger.info("[%s] Calling registerMediaServer, serverIndex: [%s], state=%s", entryObject.entryId,entryObject.serverType,state);

        return Q.resolve(entryServerNodes.add(entryObject,state));
    },
    unregisterEntryInDatabase: function(entryObject) {
        logger.info("[%s] Calling unregisterMediaServer, serverIndex: [%s]", entryObject.entryId,entryObject.serverType);
        entryServerNodes.remove(entryObject);
        return Q.resolve();
    },
    getLiveEntryServerNodes: function(entryId){
        logger.info("[%s] Calling getLiveEntryServerNodes]", entryId);
        return Q.resolve(entryServerNodes.list(entryId));
    },
    updateStreamInfo: function(entryId, entryServerNodeId, flavorsObjArray) {
        logger.debug("Calling updateStreamInfo, with new flavors object array %j",flavorsObjArray);
        return entryServerNodes.updateStreamInfo(entryServerNodeId,flavorsObjArray);
    }

};<|endoftext|>


<commit_before>const fs = require('../../core/fs.js');
var {canonicalHost} = require('../../utils/host.js');
var utils = require('../../utils/utils.js');
var Server = require('./server.js');
const opn = require('opn');

require('ejs');
const Templates = {
  embark_building_placeholder: require('./templates/embark-building-placeholder.html.ejs')
};

class WebServer {
  constructor(embark) {
    this.embark = embark;
    this.logger = embark.logger;
    this.events = embark.events;
    this.buildDir = embark.config.buildDir;
    this.webServerConfig = embark.config.webServerConfig;
    if (!this.webServerConfig.enabled) {
      return;
    }

    this.host = this.webServerConfig.host;
    this.port = parseInt(this.webServerConfig.port);
    this._openBrowser = this.webServerConfig.openBrowser;

    this.events.emit("status", __("Starting Server"));

    this.server = new Server({
      buildDir: this.buildDir,
      events: this.events,
      host: this.host,
      port: this.port
    });

    this.events.on('webserver:config:change', () => {
      this.embark.config.webServerConfig = null;
      this.embark.config.loadWebServerConfigFile();
      this.webServerConfig = this.embark.config.webServerConfig;
      this.host = this.webServerConfig.host;
      this.port = this.webServerConfig.port;
      this.server.host = this.host;
      this.server.port = this.port;

      this.testPort(() => {
        this.server.stop((_err) => {
          this.server.start((_err, message, port) => {
            this.logger.info(message);
            this.port = port;
            this.events.request('open-browser', () => {});
          });
        });
      });
    });

    this.testPort(() => {
      this.listenToCommands();
      this.registerConsoleCommands();
      this.server.start((_err, message, port) => {
        this.logger.info(message);
        this.port = port;
        this.setServiceCheck();
      });
    });
  }

  testPort(done) {
    if (this.port === 0) {
      this.logger.warn(__('Assigning an available port'));
      this.server.port = 0;
      return done();
    }
    utils.pingEndpoint(this.host, this.port, 'http', 'http', '', (err) => {
      if (err) { // Port is ok
        return done();
      }
      this.logger.warn(__('Webserver already running on port %s. Assigning an available port', this.port));
      this.port = 0;
      this.server.port = 0;
      done();
    });
  }

  setServiceCheck() {
    const self = this;

    this.events.request("services:register", 'Webserver', function (cb) {
      let url = 'http://' + canonicalHost(self.host) + ':' + self.port;
      utils.checkIsAvailable(url, function (available) {
        let devServer = __('Webserver') + ' (' + url + ')';
        let serverStatus = (available ? 'on' : 'off');
        return cb({name: devServer, status: serverStatus});
      });
    });

    this.events.on('check:wentOffline:Webserver', () => {
      this.logger.info(__("Webserver is offline"));
    });
  }

  listenToCommands() {
    this.events.setCommandHandler('build-placeholder', (cb) => this.buildPlaceholderPage(cb));
    this.events.setCommandHandler('open-browser', (cb) => this.openBrowser(cb));
    this.events.setCommandHandler('start-webserver', (cb) => this.server.start(cb));
    this.events.setCommandHandler('stop-webserver',  (cb) => this.server.stop(cb));
  }

  registerConsoleCommands() {
    const self = this;
    self.embark.registerConsoleCommand((cmd, _options) => {
      return {
        match: () => cmd === 'webserver start',
        process: (cb) => self.events.request('start-webserver', cb)
      };
    });

    self.embark.registerConsoleCommand((cmd, _options) => {
      return {
        match: () => cmd === 'webserver stop',
        process: (cb) => self.events.request('stop-webserver', cb)
      };
    });

    self.embark.registerConsoleCommand((cmd, _options) => {
      return {
        match: () => cmd === 'browser open',
        process: (cb) => self.events.request('open-browser', cb)
      };
    });
  }

  buildPlaceholderPage(cb) {
    let html = Templates.embark_building_placeholder({buildingMsg: __('Embark is building, please wait...')});
    fs.mkdirpSync(this.buildDir); // create buildDir if it does not exist
    fs.writeFile(utils.joinPath(this.buildDir, 'index.html'), html, cb);
  }

  openBrowser(cb) {
    if (!this._openBrowser) {
      return cb();
    }
    const _cb = () => { cb(); };
    return opn(
      `http://${canonicalHost(this.server.hostname)}:${this.server.port}`,
      {wait: false}
    ).then(_cb, _cb); // fail silently, e.g. in a docker container
  }
}

module.exports = WebServer;
<commit_msg>supply radix -- make the linter happy<commit_after>const fs = require('../../core/fs.js');
var {canonicalHost} = require('../../utils/host.js');
var utils = require('../../utils/utils.js');
var Server = require('./server.js');
const opn = require('opn');

require('ejs');
const Templates = {
  embark_building_placeholder: require('./templates/embark-building-placeholder.html.ejs')
};

class WebServer {
  constructor(embark) {
    this.embark = embark;
    this.logger = embark.logger;
    this.events = embark.events;
    this.buildDir = embark.config.buildDir;
    this.webServerConfig = embark.config.webServerConfig;
    if (!this.webServerConfig.enabled) {
      return;
    }

    this.host = this.webServerConfig.host;
    this.port = parseInt(this.webServerConfig.port, 10);
    this._openBrowser = this.webServerConfig.openBrowser;

    this.events.emit("status", __("Starting Server"));

    this.server = new Server({
      buildDir: this.buildDir,
      events: this.events,
      host: this.host,
      port: this.port
    });

    this.events.on('webserver:config:change', () => {
      this.embark.config.webServerConfig = null;
      this.embark.config.loadWebServerConfigFile();
      this.webServerConfig = this.embark.config.webServerConfig;
      this.host = this.webServerConfig.host;
      this.port = this.webServerConfig.port;
      this.server.host = this.host;
      this.server.port = this.port;

      this.testPort(() => {
        this.server.stop((_err) => {
          this.server.start((_err, message, port) => {
            this.logger.info(message);
            this.port = port;
            this.events.request('open-browser', () => {});
          });
        });
      });
    });

    this.testPort(() => {
      this.listenToCommands();
      this.registerConsoleCommands();
      this.server.start((_err, message, port) => {
        this.logger.info(message);
        this.port = port;
        this.setServiceCheck();
      });
    });
  }

  testPort(done) {
    if (this.port === 0) {
      this.logger.warn(__('Assigning an available port'));
      this.server.port = 0;
      return done();
    }
    utils.pingEndpoint(this.host, this.port, 'http', 'http', '', (err) => {
      if (err) { // Port is ok
        return done();
      }
      this.logger.warn(__('Webserver already running on port %s. Assigning an available port', this.port));
      this.port = 0;
      this.server.port = 0;
      done();
    });
  }

  setServiceCheck() {
    const self = this;

    this.events.request("services:register", 'Webserver', function (cb) {
      let url = 'http://' + canonicalHost(self.host) + ':' + self.port;
      utils.checkIsAvailable(url, function (available) {
        let devServer = __('Webserver') + ' (' + url + ')';
        let serverStatus = (available ? 'on' : 'off');
        return cb({name: devServer, status: serverStatus});
      });
    });

    this.events.on('check:wentOffline:Webserver', () => {
      this.logger.info(__("Webserver is offline"));
    });
  }

  listenToCommands() {
    this.events.setCommandHandler('build-placeholder', (cb) => this.buildPlaceholderPage(cb));
    this.events.setCommandHandler('open-browser', (cb) => this.openBrowser(cb));
    this.events.setCommandHandler('start-webserver', (cb) => this.server.start(cb));
    this.events.setCommandHandler('stop-webserver',  (cb) => this.server.stop(cb));
  }

  registerConsoleCommands() {
    const self = this;
    self.embark.registerConsoleCommand((cmd, _options) => {
      return {
        match: () => cmd === 'webserver start',
        process: (cb) => self.events.request('start-webserver', cb)
      };
    });

    self.embark.registerConsoleCommand((cmd, _options) => {
      return {
        match: () => cmd === 'webserver stop',
        process: (cb) => self.events.request('stop-webserver', cb)
      };
    });

    self.embark.registerConsoleCommand((cmd, _options) => {
      return {
        match: () => cmd === 'browser open',
        process: (cb) => self.events.request('open-browser', cb)
      };
    });
  }

  buildPlaceholderPage(cb) {
    let html = Templates.embark_building_placeholder({buildingMsg: __('Embark is building, please wait...')});
    fs.mkdirpSync(this.buildDir); // create buildDir if it does not exist
    fs.writeFile(utils.joinPath(this.buildDir, 'index.html'), html, cb);
  }

  openBrowser(cb) {
    if (!this._openBrowser) {
      return cb();
    }
    const _cb = () => { cb(); };
    return opn(
      `http://${canonicalHost(this.server.hostname)}:${this.server.port}`,
      {wait: false}
    ).then(_cb, _cb); // fail silently, e.g. in a docker container
  }
}

module.exports = WebServer;
<|endoftext|>


<commit_before>const fs = require('../../core/fs.js');
var {canonicalHost} = require('../../utils/host.js');
var utils = require('../../utils/utils.js');
var Server = require('./server.js');
const opn = require('opn');

require('ejs');
const Templates = {
  embark_building_placeholder: require('./templates/embark-building-placeholder.html.ejs')
};

class WebServer {
  constructor(embark, options) {
    this.embark = embark;
    this.logger = embark.logger;
    this.events = embark.events;
    this.buildDir = embark.config.buildDir;
    this.plugins = options.plugins;
    this.webServerConfig = embark.config.webServerConfig;
    if (!this.webServerConfig.enabled) {
      return;
    }

    this.host = this.webServerConfig.host;
    this.port = parseInt(this.webServerConfig.port, 10);
    this.enableCatchAll = this.webServerConfig.enableCatchAll === true;
    this.enableCatchAll = false; // FIXME when true, some Requests end up failing (eg: process-logs)

    this.events.emit("status", __("Starting Server"));
    this.server = new Server({logger: this.logger, host: this.host, port: this.port, events: this.events, plugins: this.plugins, enableCatchAll: this.enableCatchAll});

    this.server = new Server({
      logger: this.logger,
      buildDir: this.buildDir,
      events: this.events,
      host: this.host,
      port: this.port,
      plugins: this.plugins,
      openBrowser: this.webServerConfig.openBrowser
    });

    this.listenToCommands();
    this.registerConsoleCommands();

    this.events.on('webserver:config:change', () => {
      this.embark.config.webServerConfig = null;
      this.embark.config.loadWebServerConfigFile();
      this.webServerConfig = this.embark.config.webServerConfig;
      this.host = this.webServerConfig.host;
      this.port = this.webServerConfig.port;
      this.server.host = this.host;
      this.server.port = this.port;

      this.testPort(() => {
        this.server.stop((_err) => {
          this.server.start((_err, message, port) => {
            this.logger.info(message);
            this.port = port;
            this.events.request('open-browser', () => {});
          });
        });
      });
    });

    this.testPort(() => {
      this.server.start((_err, message, port) => {
        this.logger.info(message);
        this.port = port;
        this.setServiceCheck();
      });
    });
  }

  testPort(done) {
    if (this.port === 0) {
      this.logger.warn(__('Assigning an available port'));
      this.server.port = 0;
      return done();
    }
    utils.pingEndpoint(this.host, this.port, 'http', 'http', '', (err) => {
      if (err) { // Port is ok
        return done();
      }
      this.logger.warn(__('Webserver already running on port %s. Assigning an available port', this.port));
      this.port = 0;
      this.server.port = 0;
      done();
    });
    this.server.start((_err, message) => this.logger.info(message));
  }

  setServiceCheck() {
    const self = this;

    this.events.request("services:register", 'Webserver', function (cb) {
      let url = 'http://' + canonicalHost(self.host) + ':' + self.port;
      utils.checkIsAvailable(url, function (available) {
        let devServer = __('Webserver') + ' (' + url + ')';
        let serverStatus = (available ? 'on' : 'off');
        return cb({name: devServer, status: serverStatus});
      });
    });

    this.events.on('check:wentOffline:Webserver', () => {
      this.logger.info(__("Webserver is offline"));
    });
  }

  listenToCommands() {
    this.events.setCommandHandler('build-placeholder', (cb) => this.buildPlaceholderPage(cb));
    this.events.setCommandHandler('open-browser', (cb) => this.openBrowser(cb));
    this.events.setCommandHandler('start-webserver', (cb) => this.server.start(cb));
    this.events.setCommandHandler('stop-webserver',  (cb) => this.server.stop(cb));
    this.events.setCommandHandler('logs:webserver:turnOn',  (cb) => this.server.enableLogging(cb));
    this.events.setCommandHandler('logs:webserver:turnOff',  (cb) => this.server.disableLogging(cb));
  }

  registerConsoleCommands() {
    const self = this;
    self.embark.registerConsoleCommand((cmd, _options) => {
      return {
        match: () => cmd === 'webserver start',
        process: (cb) => self.events.request('start-webserver', cb)
      };
    });

    self.embark.registerConsoleCommand((cmd, _options) => {
      return {
        match: () => cmd === 'webserver stop',
        process: (cb) => self.events.request('stop-webserver', cb)
      };
    });

    self.embark.registerConsoleCommand((cmd, _options) => {
      return {
        match: () => cmd === 'browser open',
        process: (cb) => self.events.request('open-browser', cb)
      };
    });

    self.embark.registerConsoleCommand((cmd, _options) => {
      return {
        match: () => cmd === 'log webserver on',
        process: (cb) => self.events.request('logs:webserver:turnOn', cb)
      };
    });

    self.embark.registerConsoleCommand((cmd, _options) => {
      return {
        match: () => cmd === 'log webserver off',
        process: (cb) => self.events.request('logs:webserver:turnOff', cb)
      };
    });
  }

  buildPlaceholderPage(cb) {
    let html = Templates.embark_building_placeholder({buildingMsg: __('Embark is building, please wait...')});
    fs.mkdirpSync(this.buildDir); // create buildDir if it does not exist
    fs.writeFile(utils.joinPath(this.buildDir, 'index.html'), html, cb);
  }

  openBrowser(cb) {
    const _cb = () => { cb(); };
    return opn(
      `http://${canonicalHost(this.server.hostname)}:${this.server.port}`,
      {wait: false}
    ).then(_cb, _cb); // fail silently, e.g. in a docker container
  }
}

module.exports = WebServer;
<commit_msg>Pass logger to webserver<commit_after>const fs = require('../../core/fs.js');
var {canonicalHost} = require('../../utils/host.js');
var utils = require('../../utils/utils.js');
var Server = require('./server.js');
const opn = require('opn');

require('ejs');
const Templates = {
  embark_building_placeholder: require('./templates/embark-building-placeholder.html.ejs')
};

class WebServer {
  constructor(embark, options) {
    this.embark = embark;
    this.logger = embark.logger;
    this.events = embark.events;
    this.buildDir = embark.config.buildDir;
    this.plugins = options.plugins;
    this.webServerConfig = embark.config.webServerConfig;
    if (!this.webServerConfig.enabled) {
      return;
    }

    this.host = this.webServerConfig.host;
    this.port = parseInt(this.webServerConfig.port, 10);
    this.enableCatchAll = this.webServerConfig.enableCatchAll === true;
    this.enableCatchAll = false; // FIXME when true, some Requests end up failing (eg: process-logs)

    this.events.emit("status", __("Starting Server"));

    this.server = new Server({
      logger: this.logger,
      buildDir: this.buildDir,
      events: this.events,
      host: this.host,
      logger: this.logger,
      port: this.port,
      plugins: this.plugins,
      openBrowser: this.webServerConfig.openBrowser
    });

    this.listenToCommands();
    this.registerConsoleCommands();

    this.events.on('webserver:config:change', () => {
      this.embark.config.webServerConfig = null;
      this.embark.config.loadWebServerConfigFile();
      this.webServerConfig = this.embark.config.webServerConfig;
      this.host = this.webServerConfig.host;
      this.port = this.webServerConfig.port;
      this.server.host = this.host;
      this.server.port = this.port;

      this.testPort(() => {
        this.server.stop((_err) => {
          this.server.start((_err, message, port) => {
            this.logger.info(message);
            this.port = port;
            this.events.request('open-browser', () => {});
          });
        });
      });
    });

    this.testPort(() => {
      this.server.start((_err, message, port) => {
        this.logger.info(message);
        this.port = port;
        this.setServiceCheck();
      });
    });
  }

  testPort(done) {
    if (this.port === 0) {
      this.logger.warn(__('Assigning an available port'));
      this.server.port = 0;
      return done();
    }
    utils.pingEndpoint(this.host, this.port, 'http', 'http', '', (err) => {
      if (err) { // Port is ok
        return done();
      }
      this.logger.warn(__('Webserver already running on port %s. Assigning an available port', this.port));
      this.port = 0;
      this.server.port = 0;
      done();
    });
    this.server.start((_err, message) => this.logger.info(message));
  }

  setServiceCheck() {
    const self = this;

    this.events.request("services:register", 'Webserver', function (cb) {
      let url = 'http://' + canonicalHost(self.host) + ':' + self.port;
      utils.checkIsAvailable(url, function (available) {
        let devServer = __('Webserver') + ' (' + url + ')';
        let serverStatus = (available ? 'on' : 'off');
        return cb({name: devServer, status: serverStatus});
      });
    });

    this.events.on('check:wentOffline:Webserver', () => {
      this.logger.info(__("Webserver is offline"));
    });
  }

  listenToCommands() {
    this.events.setCommandHandler('build-placeholder', (cb) => this.buildPlaceholderPage(cb));
    this.events.setCommandHandler('open-browser', (cb) => this.openBrowser(cb));
    this.events.setCommandHandler('start-webserver', (cb) => this.server.start(cb));
    this.events.setCommandHandler('stop-webserver',  (cb) => this.server.stop(cb));
    this.events.setCommandHandler('logs:webserver:turnOn',  (cb) => this.server.enableLogging(cb));
    this.events.setCommandHandler('logs:webserver:turnOff',  (cb) => this.server.disableLogging(cb));
  }

  registerConsoleCommands() {
    const self = this;
    self.embark.registerConsoleCommand((cmd, _options) => {
      return {
        match: () => cmd === 'webserver start',
        process: (cb) => self.events.request('start-webserver', cb)
      };
    });

    self.embark.registerConsoleCommand((cmd, _options) => {
      return {
        match: () => cmd === 'webserver stop',
        process: (cb) => self.events.request('stop-webserver', cb)
      };
    });

    self.embark.registerConsoleCommand((cmd, _options) => {
      return {
        match: () => cmd === 'browser open',
        process: (cb) => self.events.request('open-browser', cb)
      };
    });

    self.embark.registerConsoleCommand((cmd, _options) => {
      return {
        match: () => cmd === 'log webserver on',
        process: (cb) => self.events.request('logs:webserver:turnOn', cb)
      };
    });

    self.embark.registerConsoleCommand((cmd, _options) => {
      return {
        match: () => cmd === 'log webserver off',
        process: (cb) => self.events.request('logs:webserver:turnOff', cb)
      };
    });
  }

  buildPlaceholderPage(cb) {
    let html = Templates.embark_building_placeholder({buildingMsg: __('Embark is building, please wait...')});
    fs.mkdirpSync(this.buildDir); // create buildDir if it does not exist
    fs.writeFile(utils.joinPath(this.buildDir, 'index.html'), html, cb);
  }

  openBrowser(cb) {
    const _cb = () => { cb(); };
    return opn(
      `http://${canonicalHost(this.server.hostname)}:${this.server.port}`,
      {wait: false}
    ).then(_cb, _cb); // fail silently, e.g. in a docker container
  }
}

module.exports = WebServer;
<|endoftext|>


<commit_before>// Karma configuration file, see link for more information
// https://karma-runner.github.io/1.0/config/configuration-file.html

module.exports = function (config) {
  config.set({
    basePath: '',
    frameworks: ['jasmine', '@angular-devkit/build-angular'],
    plugins: [
      require('karma-jasmine'),
      require('karma-chrome-launcher'),
      require('karma-jasmine-html-reporter'),
      require('karma-coverage-istanbul-reporter'),
      require('@angular-devkit/build-angular/plugins/karma')
    ],
    client: {
      clearContext: false // leave Jasmine Spec Runner output visible in browser
    },
    coverageIstanbulReporter: {
      dir: require('path').join(__dirname, './coverage'),
      reports: ['html', 'lcovonly', 'text-summary'],
      fixWebpackSourcePaths: true
    },
    reporters: ['progress', 'kjhtml', 'coverage-istanbul'],
    port: 9876,
    colors: true,
    logLevel: config.LOG_INFO,
    autoWatch: true,
    browsers: ['ChromeHeadless'],
    singleRun: true,
    restartOnFileChange: true,
    concurrency: 1
  });
};
<commit_msg>Ensure build fails if test has no assertions<commit_after>/*
 * Copyright (c) Microsoft Corporation. All rights reserved.
 * Licensed under the MIT License.
 */

module.exports = function (config) {
    config.set({
        basePath: "",
        frameworks: ["jasmine", "@angular-devkit/build-angular"],
        plugins: [
            require("karma-jasmine"),
            require("karma-chrome-launcher"),
            require("karma-jasmine-html-reporter"),
            require("karma-coverage-istanbul-reporter"),
            require("@angular-devkit/build-angular/plugins/karma")
        ],
        client: {
            jasmine: {
                failSpecWithNoExpectations: true
            },
            clearContext: false // leave Jasmine Spec Runner output visible in browser
        },
        coverageIstanbulReporter: {
            dir: require("path").join(__dirname, "./coverage"),
            reports: ["html", "lcovonly", "text-summary"],
            fixWebpackSourcePaths: true
        },
        reporters: ["progress", "kjhtml", "coverage-istanbul"],
        port: 9876,
        colors: true,
        logLevel: config.LOG_INFO,
        autoWatch: true,
        browsers: ["ChromeHeadless"],
        singleRun: true,
        restartOnFileChange: true,
        concurrency: 1
    });
};
<|endoftext|>


<commit_before>var system = require('system'),
        fs = require('fs');

// check for required arguments
if (system.args.length < 5) {
        console.log('Usage: casperjs opencms.js <baseurl> <file> <user> <pass>');
        phantom.exit(64);
}

// set casperjs path
phantom.casperPath = 'vendor/casperjs';

// if deployment is started by deploy script the 6th argument is the absolute path to casper js
// hopefully this will work on windows too
if (system.args[5]) {
    phantom.casperPath = system.args[5];
}

// inject casperjs
phantom.injectJs(phantom.casperPath + '/bin/bootstrap.js');

// initialize casperjs and casperjs's utils
var utils = require('utils'),
        casper = require('casper').create({
                verbose: true,
                //logLevel: "warning"
                logLevel: "info"
        });

// get some mor command line arguments
var loginUrl = casper.cli.args[0] + 'cms/system/login/index.html';
var topUrl = casper.cli.args[0] + 'cms/system/workplace/views/top_head.jsp';
var uploadUrl = casper.cli.args[0] + 'cms/system/workplace/views/admin/admin-main.jsp?path=%2Fmodules%2Fmodules_import';
var file = casper.cli.args[1];
var user = casper.cli.args[2];
var pass = casper.cli.args[3];

if (casper.cli.args[5] && casper.cli.args[6]) {
    var module = casper.cli.args[5];
    var logDir = casper.cli.args[6];
}

var dateToYMD = function (date) {
        var d = date.getDate();
        var m = date.getMonth()+1;
        var y = date.getFullYear();
        var hh = date.getHours();
        var mm = date.getMinutes();
        var ss = date.getSeconds();
        return '' + y + '' + (m<=9?'0'+m:m) +''+ (d<=9?'0'+d:d) + '_' + (hh<=9?'0'+hh:hh) + '' + (mm<=9?'0'+mm:mm) + '' + (ss<=9?'0'+ss:ss);
};

// prints opencms reports in iframe to stdout
var updateReport = function () {
    var openCmsLog = casper.evaluate(function() {
        return document.querySelector('#report').contentDocument.querySelector('.main').innerText;
    });
    console.log(openCmsLog);
    if (logDir) {
        fs.write(logDir + '/' + dateToYMD(new Date()) + '_' + module + '.log', openCmsLog);
    }
};

// when the report iframe is requested, we tell the user
casper.on('navigation.requested', function(url, navigationType, navigationLocked, isMainFrame) {
    if (url.indexOf('reportupdate') > -1) casper.log('still working ...', 'info');
});

// on error print out message and exit
casper.on('error', function (msg, trace) {
        console.log(msg + '\n');
        trace.forEach(function(item) {
                console.log('  ', item.file, ':', item.line);
        });
        casper.exit(75);
});

casper.on('load.failed', function (obj) {
    casper.log('error loading ' + obj.url, 'error');
    casper.exit(69);
});

// open login form and submit
casper.start(loginUrl, function() {
        casper.fill('form[name="ocLoginForm"]', {
            ocUname: user,
            ocPword: pass
        }, true);
});

// open opencms header frame and change site to /
casper.thenOpen(topUrl, function() {
    casper.fill('form[name="wpSiteSelect"]', {
        wpSite: ''
    });
});

// open import form and submit the module zip file
casper.thenOpen(uploadUrl, function() {
    casper.fill('form[name="main"]', {
        importfile: file
    }, true);
});

// wait until the ok button isn't diabled anymore
casper.waitWhileSelector('form[name="main"] input[name="ok"]:disabled',
    function then() {},
    function timeout() {},
    60000*20);

// run all steps defined before
casper.run(function() {
    // after running all steps we get the opencms log and write to stdout
    updateReport();
    // we are done
    casper.echo('module deployed', 'GREEN_BAR');
    // exit with successful exit code
    casper.exit(0);
});
<commit_msg>fixes indentation<commit_after>var system = require('system'),
    fs = require('fs');

// check for required arguments
if (system.args.length < 5) {
        console.log('Usage: casperjs opencms.js <baseurl> <file> <user> <pass>');
        phantom.exit(64);
}

// set casperjs path
phantom.casperPath = 'vendor/casperjs';

// if deployment is started by deploy script the 6th argument is the absolute path to casper js
// hopefully this will work on windows too
if (system.args[5]) {
    phantom.casperPath = system.args[5];
}

// inject casperjs
phantom.injectJs(phantom.casperPath + '/bin/bootstrap.js');

// initialize casperjs and casperjs's utils
var utils = require('utils'),
    casper = require('casper').create({
        verbose: true,
        //logLevel: "warning"
        logLevel: "info"
    });

// get some mor command line arguments
var loginUrl = casper.cli.args[0] + 'cms/system/login/index.html';
var topUrl = casper.cli.args[0] + 'cms/system/workplace/views/top_head.jsp';
var uploadUrl = casper.cli.args[0] + 'cms/system/workplace/views/admin/admin-main.jsp?path=%2Fmodules%2Fmodules_import';
var file = casper.cli.args[1];
var user = casper.cli.args[2];
var pass = casper.cli.args[3];

if (casper.cli.args[5] && casper.cli.args[6]) {
    var module = casper.cli.args[5];
    var logDir = casper.cli.args[6];
}

var dateToYMD = function (date) {
    var d = date.getDate();
    var m = date.getMonth()+1;
    var y = date.getFullYear();
    var hh = date.getHours();
    var mm = date.getMinutes();
    var ss = date.getSeconds();
    return '' + y + '' + (m<=9?'0'+m:m) +''+ (d<=9?'0'+d:d) + '_' + (hh<=9?'0'+hh:hh) + '' + (mm<=9?'0'+mm:mm) + '' + (ss<=9?'0'+ss:ss);
};

// prints opencms reports in iframe to stdout
var updateReport = function () {
    var openCmsLog = casper.evaluate(function() {
        return document.querySelector('#report').contentDocument.querySelector('.main').innerText;
    });
    console.log(openCmsLog);
    if (logDir) {
        fs.write(logDir + '/' + dateToYMD(new Date()) + '_' + module + '.log', openCmsLog);
    }
};

// when the report iframe is requested, we tell the user
casper.on('navigation.requested', function(url, navigationType, navigationLocked, isMainFrame) {
    if (url.indexOf('reportupdate') > -1) casper.log('still working ...', 'info');
});

// on error print out message and exit
casper.on('error', function (msg, trace) {
    console.log(msg + '\n');
    trace.forEach(function(item) {
        console.log('  ', item.file, ':', item.line);
    });
    casper.exit(75);
});

casper.on('load.failed', function (obj) {
    casper.log('error loading ' + obj.url, 'error');
    casper.exit(69);
});

// open login form and submit
casper.start(loginUrl, function() {
    casper.fill('form[name="ocLoginForm"]', {
        ocUname: user,
        ocPword: pass
    }, true);
});

// open opencms header frame and change site to /
casper.thenOpen(topUrl, function() {
    casper.fill('form[name="wpSiteSelect"]', {
        wpSite: ''
    });
});

// open import form and submit the module zip file
casper.thenOpen(uploadUrl, function() {
    casper.fill('form[name="main"]', {
        importfile: file
    }, true);
});

// wait until the ok button isn't diabled anymore
casper.waitWhileSelector('form[name="main"] input[name="ok"]:disabled',
    function then() {},
    function timeout() {},
    60000*20);

// run all steps defined before
casper.run(function() {
    // after running all steps we get the opencms log and write to stdout
    updateReport();
    // we are done
    casper.echo('module deployed', 'GREEN_BAR');
    // exit with successful exit code
    casper.exit(0);
});
<|endoftext|>


<commit_before>'use strict';

var node_path   = require('path');
var node_url    = require('url');
var fs          = require('fs-sync');
var lang        = require('../util/lang');
var pkg_helper  = require('../util/package');

function is_empty_object(obj){
    for(var key in obj){
        return false;
    }

    return true;
};

// There should be no duplicate modules.
// There should be no duplicate versions of a same module
function check_duplicate_version(done, modules, cwd){
    var map = {};

    pkg_helper.get_original_package(cwd, function (err, pkg) {
        if ( err ) {
            return done(err);
        }

        var pkg_name = pkg.name;

        modules.forEach(function(module) {
            var name = module.split('@')[0];

            if(pkg_name === name){
                done('You should not install a module "' + name + '" into itself.');

            }else if( !(name in map) ){
                map[name] = true;

            }else{
                done(
                      'With the "--save" option, '
                    + 'installing more than one version of the module "'
                    + name
                    + '" is prohibited.'
                );
            }
        });

        done(null);
    });
}

// There should be no duplicate modules.
function check_duplicate(done, modules){
    var map = {};

    modules.forEach(function(module) {
        if( !(module in map) ){
            map[module] = true;

        }else{
            done('Duplicate installation of module "' + module + '".');
        }
    });

    done(null);
}

function save_check_package (save) {
    var done = this.async();

    // if --save, package.json must exists
    if(save){
        var cwd = pkg_helper.repo_root( this.get('cwd') );

        // 'cortex install' might be called inside a subtle directory of the project.
        if(cwd === null){
            return done('package.json not found, could not save dependencies');
        }

        this.set('cwd', cwd);
    }

    done(null);
}

exports.shorthands = {
    c: 'cwd',
    r: 'recursive'
};

exports.options = {
    recursive: {
        type: Boolean,
        info: 'install all dependencies recursively. If `false`, cortex will only download the current module.',
        default: true
    },

    cwd: {
        type: node_path,
        info: 'current working directory.',
        // `cortex install` could be executed anywhere
        default: process.cwd()
    },

    // if --save --save-async, --save-async will be ignored
    save: {
        type: Boolean,
        info: 'package will appear in your "cortex.dependencies" of package.json.',
        validator: save_check_package
    },

    'save-async': {
        type: Boolean,
        info: 'package will appear in your "cortex.asyncDependencies" of package.json.',
        validator: save_check_package
    },

    clone: {
        type: Boolean,
        info: 'try to clone the package repo down to the workspace.',
        default: false
    },

    modules: {

        // command line type: String
        // programmatical type: Array.<string>
        info: 'modules to install. if not specified, cortex will read them from your package.json. if you install a module without version, cortex will try to install the latest one.',
        setter: function(modules) {
            var done = this.async();

            exports._get_modules({
                remain  : this.get('_') || [],
                cwd     : this.get('cwd'),
                save    : this.get('save') || this.get('save-async'),
                modules : modules

            }, done);

            //     var parsed_modules;

            //     function check_done (err){
            //         if ( err ) {
            //             done(err);

            //         } else {
            //             done(
            //                 null,
            //                 // 'a' -> 'a@latest'
            //                 parsed_modules.map(function(module) {
            //                     var splitted = module.split('@');
            //                     return splitted[0] + '@' + ( splitted[1] || 'latest' );
            //                 })
            //             );
            //         }
            //     };

            //     // if --save, we should not install more than one version of a certain module
            //     save ?
            //         // prohibited: a@0.0.1 a@0.0.2
            //         // prohibited: a a
            //         // allow: a@0.0.1 b
            //         check_duplicate_version.call(this, check_done, parsed_modules, cwd) :

            //         // prohibited: a a
            //         // allow: a@0.0.1 a@0.0.2
            //         check_duplicate.call(this, check_done, parsed_modules);
            // });

        }
    }
};

exports._get_pkg = function (cwd, callback) {
    pkg_helper.get_original_package(cwd, callback);
};

// @param {Object} options
// - pkg
// - cwd
// - save
// - remain
exports._get_modules = function (options, callback) {
    var parsed_modules = [];

    // Invalid value
    // ```
    // cortex install --modules
    // ```
    if( options.modules === true ){
        return callback({
            code: 'EINVALID',
            message: 'invalid value of option --modules, which must be specified.',
            data: {
                option: 'modules'
            }
        });
    }

    // 1.
    // Install modules which explicitly defined in option --modules
    // ```
    // #　could be executed anywhere
    // cortex install --modules ajax,lang
    // ```
    if ( options.modules ) {
        parsed_modules = options.modules.split(/\s*,\s*/);
    }

    // 2.
    // Install modules in argv.remain
    // ```
    // #　could be executed anywhere
    // cortex install ajax lang
    // ```

    // Object `remain` might be a mocked argv object,
    // so, be careful, and do some tests
    if( options.remain.length ){
        parsed_modules = options.remain;
    }

    // 3.
    // Install modules from dependencies of package.json,
    // ```
    // # in this case, must executed inside a repo
    // cortex install
    // ```
    if (
        // if --save or --save-async,
        // there must inside a repo, or we will not be able to save dependencies
        !options.save &&
        parsed_modules.length
    ) {
        return callback(null, parsed_modules);
    }

    var cwd = pkg_helper.repo_root(options.cwd);

    if ( cwd === null ) {
        if ( options.save ) {
            return callback({
                code: 'ECOULDNOTSAVE',
                message: 'Directory "' + cwd + '" is not inside a repo, could not save dependencies.',
                data: {
                    cwd: cwd
                }
            });

        } else {
            return callback({
                code: 'ENOTAREPO',
                message: 'Directory "' + cwd + '" is not inside a repo, could not fetch dependencies.',
                data: {
                    cwd: cwd
                }
            });
        }
    }

    if ( true ) {

    }

    if( fs.exists(package_path) ){

        // read modules from package.json
        var pkg = fs.readJSON(package_path);
        module_map = lang.object_member_by_namespaces(pkg, 'cortex.dependencies', {});
    }

    if( !is_empty_object(module_map) ){
        this.context.logger.info('Read cortex.dependencies from package.json.');

    }else{
        return done('Please specify the modules to be installed.');
    }

    // -> ['a@0.0.2']
    Object.keys(module_map).forEach(function(name) {
        parsed_modules.push( name + '@' + module_map[name] );
    });
};

exports.info = 'Install specified modules or install modules from package.json';

exports.usage = [
    '{{name}} install <module>[,<modules>[,...]]',
    '{{name}} install [options]'
];

<commit_msg>#241: option/install: completely refractors option/install; improves stability; covers verge situations<commit_after>'use strict';

var node_path   = require('path');
var node_url    = require('url');
var lang        = require('../util/lang');
var pkg_helper  = require('../util/package');
var async       = require('async');

exports.shorthands = {
    c: 'cwd',
    r: 'recursive'
};

exports.options = {
    recursive: {
        type: Boolean,
        info: 'install all dependencies recursively. If `false`, cortex will only download the current module.',
        default: true
    },

    cwd: {
        type: node_path,
        info: 'current working directory.',
        // `cortex install` could be executed anywhere
        default: process.cwd()
    },

    // if --save --save-async, --save-async will be ignored
    save: {
        type: Boolean,
        info: 'package will appear in your "cortex.dependencies" of package.json.',
        validator: save_check_package
    },

    'save-async': {
        type: Boolean,
        info: 'package will appear in your "cortex.asyncDependencies" of package.json.',
        validator: save_check_package
    },

    'save-dev': {
        type: Boolean,
        info: 'package will appear in your "cortex.devDependencies" of package.json.',
        validator: save_check_package
    },

    clone: {
        type: Boolean,
        info: 'try to clone the package repo down to the workspace.',
        default: false
    },

    modules: {

        // command line type: String
        // programmatical type: Array.<string>
        info: 'modules to install. if not specified, cortex will read them from your package.json. if you install a module without version, cortex will try to install the latest one.',
        setter: function(modules) {
            var done = this.async();

            exports._get_modules({
                remain  : this.get('_') || [],
                cwd     : this.get('cwd'),
                save    : this.get('save') || this.get('save-async'),
                modules : modules

            }, done);

            //     var parsed_modules;

            //     function check_done (err){
            //         if ( err ) {
            //             done(err);

            //         } else {
            //             done(
            //                 null,
            //                 // 'a' -> 'a@latest'
            //                 parsed_modules.map(function(module) {
            //                     var splitted = module.split('@');
            //                     return splitted[0] + '@' + ( splitted[1] || 'latest' );
            //                 })
            //             );
            //         }
            //     };

            //     // if --save, we should not install more than one version of a certain module
            //     save ?
            //         // prohibited: a@0.0.1 a@0.0.2
            //         // prohibited: a a
            //         // allow: a@0.0.1 b
            //         check_duplicate_version.call(this, check_done, parsed_modules, cwd) :

            //         // prohibited: a a
            //         // allow: a@0.0.1 a@0.0.2
            //         check_duplicate.call(this, check_done, parsed_modules);
            // });

        }
    }
};

function save_check_package (save) {
    var done = this.async();

    // if --save, package.json must exists
    if(save){
        var cwd = pkg_helper.repo_root( this.get('cwd') );

        // 'cortex install' might be called inside a subtle directory of the project.
        if(cwd === null){
            return done('package.json not found, could not save dependencies');
        }

        this.set('cwd', cwd);
    }

    done(null);
}

// @param {Object} options
// - pkg
// - cwd
// - save
// - remain
exports._get_modules = function (options, callback) {
    var parsed_modules = [];

    // Invalid value
    // ```
    // cortex install --modules
    // ```
    if( options.modules === true ){
        return callback({
            code: 'EINVALID',
            message: 'invalid value of option --modules, which must be specified.',
            data: {
                option: 'modules'
            }
        });
    }

    // 1.
    // Install modules which explicitly defined in option --modules
    // ```
    // #　could be executed anywhere
    // cortex install --modules ajax,lang
    // ```
    if ( options.modules ) {
        parsed_modules = options.modules.split(/\s*,\s*/);
    }

    // 2.
    // Install modules in argv.remain
    // ```
    // #　could be executed anywhere
    // cortex install ajax lang
    // ```

    // Object `remain` might be a mocked argv object,
    // so, be careful, and do some tests
    if( !parsed_modules.length && options.remain.length ){
        parsed_modules = options.remain;
    }

    if ( options.save ) {
        // if --save or --save-async,
        // there must inside a repo, or we will not be able to save dependencies
        if ( !parsed_modules.length ) {
            return callback({
                code: 'ENONETOSAVE',
                message: 'if --save, you must specify the modules to install.'
            });
        }
        // else we should check the modules

    } else {
        if ( parsed_modules.length ) {
            return callback(null, parsed_modules);
        }
        // else we will fetch modules from dependencies
    }

    // 3.
    // Install modules from dependencies of package.json,
    // ```
    // # in this case, must executed inside a repo
    // cortex install
    // ```
    var cwd = pkg_helper.repo_root(options.cwd);

    if ( cwd === null ) {
        if ( options.save ) {
            return callback({
                code: 'ECOULDNOTSAVE',
                message: 'Directory "' + cwd + '" is not inside a repo, could not save dependencies.',
                data: {
                    cwd: cwd
                }
            });

        } else {
            return callback({
                code: 'ENOTAREPO',
                message: 'Directory "' + cwd + '" is not inside a repo, could not fetch dependencies.',
                data: {
                    cwd: cwd
                }
            });
        }
    }

    exports._get_pkg(cwd, function (err, pkg) {
        if ( err ) {
            return callback(err);
        }

        // Including all versions
        var deps_map = exports._get_all_deps(pkg);

        // We will not check `cortex install`
        if ( !parsed_modules.length ) {

            // If `deps_map` is an empty object, we will allow this.
            // Users might exec `cortex install` inside a repo which has no deps.
            return callback(null, exports._make_deps_array( deps_map ));
        }

        // if --save, we should not install more than one version of a certain module
        var allow_duplicate_versions = !options.save;

        exports._check_modules(parsed_modules, pkg, function (err) {
            if ( err ) {
                return callback(err);
            }

            callback(null, parsed_modules);

        }, allow_duplicate_versions);
    });
};

exports._get_pkg = function (cwd, callback) {
    pkg_helper.get_original_package(cwd, callback);
};

exports._get_all_deps = function (pkg) {
    var deps_obj = {};

    ['dependencies', 'asyncDependencies', 'devDependencies'].forEach(function (key) {
        lang.mix(obj, pkg[key]);
    });

    return deps_obj;
};

exports._make_deps_array = function (map) {
    var deps = [];

    // -> ['a@0.0.2']
    Object.keys(map).forEach(function(name) {
        deps.push( name + '@' + map[name] );
    });

    return deps;
};

exports._check_modules = function (modules, pkg, callback, allow_duplicate_versions) {
    if ( allow_duplicate_versions ) {
        // prohibited: a a
        // allow: a@0.0.1 a@0.0.2
        exports._check_duplicate_modules(modules, callback);
    } else {
        // prohibited: a@0.0.1 a@0.0.2
        // prohibited: a a
        // allow: a@0.0.1 b
        exports._check_duplicate_versions(modules, pkg, callback);
    }
};

// There should be no duplicate modules.
// There should be no duplicate versions of a same module
exports._check_duplicate_versions = function (modules, pkg, callback){
    var map = {};

    var pkg_name = pkg.name;

    // if no error
    var pass = !modules.some(function(module) {
        var name = module.split('@')[0];

        if(pkg_name === name){
            return ~ callback('You should not install a module "' + name + '" into itself.');

        }else if( !(name in map) ){
            map[name] = true;

        }else{
            return ~ callback(
                  'With the "--save" option, '
                + 'installing more than one version of the module "'
                + name
                + '" is prohibited.'
            );
        }
    });

    if ( pass ) {
        callback(null);
    }
};

// There should be no duplicate modules.
exports._check_duplicate_modules = function (modules, callback){
    var map = {};

    // if no error
    var pass = !modules.some(function(module) {
        if( !(module in map) ){
            map[module] = true;

        }else{
            return ~ callback('Duplicate installation of module "' + module + '".');
        }
    });

    if ( pass ) {
        callback(null);
    }
}

exports.info = 'Install specified modules or install modules from package.json';

exports.usage = [
    '{{name}} install <module>[,<modules>[,...]]',
    '{{name}} install [options]'
];

<|endoftext|>


<commit_before>;(function() {
  // don't reinitialize the bookmarklet if it has already been run
  if(typeof hsmatch === 'undefined') {

    var HSMatch = function() {
      this.baseUrl = 'http://0.0.0.0:5000/';
    };

    HSMatch.prototype.init = function() {
      this.modal = new Modal(this);
      this.createLinks();

      $('body').on('click', '.close', this.modal.closeHandler());
      $('body').on('click', '.find_matches', this.showModalHandler());
    };

    HSMatch.prototype.createLinks = function() {
      $('.person').css('height', '280px');
      $('.name').filter(function() {
        return $(this).siblings('.skills').text() !== '';
      }).after('Find matches');
    };

    HSMatch.prototype.showModalHandler = function() {
      var modal = this.modal;
      return function(e) {
        e.preventDefault();
        var name = $(e.target).prev('.name').text();
        modal.show(name);
      }
    };

    HSMatch.prototype.showMatchesHandler = function(name) {
      var self = this;
      var name = name;

      return function (matches) {
        var modal = $('#'+self.modal.id);
        console.log(matches);
        var peopleSelector = $.map(matches, function(match, i) { return '.person:contains("'+match.name+'")'; }).join(', ');
        var people = $(peopleSelector).clone().css({ width: '150px', display: 'inline-block', verticalAlign: 'top', margin: '15px' });
        $('.find_matches, .skills, .irc', people).remove();

        $('.matches', modal).empty().append('
Hacker Schoolers with the skillset most like '+name+':
').after(people);

        $.each(matches, function(i, match) {
          var name = match.name;
          $('.name:contains('+name+')', modal).append('
Shared skills: '+match.shared_skills.join(', '));
        });
      };
    };

    HSMatch.prototype.getMatches = function (name) {
      $.getJSON(this.baseUrl + "?person="+encodeURIComponent(name)+"&callback=?", null, this.showMatchesHandler(name));
    };

    /* Not used in bookmarklet itself
    * Returns person/skill data from page as an object
    */
    HSMatch.prototype.scrape = function() {
      var people = {};
      $.each($('.person'), function() {
        var skills = $('.skills', this).text().split(', ');
        $.map(skills, function (val, i) {
          return $.trim(val).toLowerCase().replace(/[-\/]/g, '');
        });
        var name = $('.name', this).text()
        people[name] = {
          skills: skills
        };
      });
      return people;
    };

    var Modal = function(page) {
      this.id = 'hsmatch-modal';
      this.page = page;

      this.styles = {
        background: '#fff',
        border: '5px solid #000',
        width: '920px',
        height: '550px',
        position: 'fixed',
        top: '50%',
        marginTop: '-275px',
        left: '50%',
        marginLeft: '-460px',
        padding: '0 20px',
        boxShadow: '0 0 15px rgba(0, 0, 0, .5)'
      };
    };

    Modal.prototype.show = function(name) {
      var html = '

Hacker School Match

Loading matches for '+name+' ...

Close
';
      $(html).css(this.styles).appendTo('body');
      this.page.getMatches(name);
    };

    Modal.prototype.closeHandler = function() {
      var id = this.id;
      return function(e) {
        $('#hsmatch-modal').remove();
        e.preventDefault();
      }
    };

    window.hsmatch = new HSMatch();

    $(function() { hsmatch.init() });
 }
})();<commit_msg>Update bookmarklet API URL<commit_after>;(function() {
  // don't reinitialize the bookmarklet if it has already been run
  if(typeof hsmatch === 'undefined') {

    var HSMatch = function() {
      this.baseUrl = 'https://hsmatch.herokuapp.com/';
    };

    HSMatch.prototype.init = function() {
      this.modal = new Modal(this);
      this.createLinks();

      $('body').on('click', '.close', this.modal.closeHandler());
      $('body').on('click', '.find_matches', this.showModalHandler());
    };

    HSMatch.prototype.createLinks = function() {
      $('.person').css('height', '280px');
      $('.name').filter(function() {
        return $(this).siblings('.skills').text() !== '';
      }).after('Find matches');
    };

    HSMatch.prototype.showModalHandler = function() {
      var modal = this.modal;
      return function(e) {
        e.preventDefault();
        var name = $(e.target).prev('.name').text();
        modal.show(name);
      }
    };

    HSMatch.prototype.showMatchesHandler = function(name) {
      var self = this;
      var name = name;

      return function (matches) {
        var modal = $('#'+self.modal.id);
        console.log(matches);
        var peopleSelector = $.map(matches, function(match, i) { return '.person:contains("'+match.name+'")'; }).join(', ');
        var people = $(peopleSelector).clone().css({ width: '150px', display: 'inline-block', verticalAlign: 'top', margin: '15px' });
        $('.find_matches, .skills, .irc', people).remove();

        $('.matches', modal).empty().append('
Hacker Schoolers with the skillset most like '+name+':
').after(people);

        $.each(matches, function(i, match) {
          var name = match.name;
          $('.name:contains('+name+')', modal).append('
Shared skills: '+match.shared_skills.join(', '));
        });
      };
    };

    HSMatch.prototype.getMatches = function (name) {
      $.getJSON(this.baseUrl + "?person="+encodeURIComponent(name)+"&callback=?", null, this.showMatchesHandler(name));
    };

    /* Not used in bookmarklet itself
    * Returns person/skill data from page as an object
    */
    HSMatch.prototype.scrape = function() {
      var people = {};
      $.each($('.person'), function() {
        var skills = $('.skills', this).text().split(', ');
        $.map(skills, function (val, i) {
          return $.trim(val).toLowerCase().replace(/[-\/]/g, '');
        });
        var name = $('.name', this).text()
        people[name] = {
          skills: skills
        };
      });
      return people;
    };

    var Modal = function(page) {
      this.id = 'hsmatch-modal';
      this.page = page;

      this.styles = {
        background: '#fff',
        border: '5px solid #000',
        width: '920px',
        height: '550px',
        position: 'fixed',
        top: '50%',
        marginTop: '-275px',
        left: '50%',
        marginLeft: '-460px',
        padding: '0 20px',
        boxShadow: '0 0 15px rgba(0, 0, 0, .5)'
      };
    };

    Modal.prototype.show = function(name) {
      var html = '

Hacker School Match

Loading matches for '+name+' ...

Close
';
      $(html).css(this.styles).appendTo('body');
      this.page.getMatches(name);
    };

    Modal.prototype.closeHandler = function() {
      var id = this.id;
      return function(e) {
        $('#hsmatch-modal').remove();
        e.preventDefault();
      }
    };

    window.hsmatch = new HSMatch();

    $(function() { hsmatch.init() });
 }
})();<|endoftext|>