<commit_before>const CleanCSS = require('clean-css');
const uncss = require('uncss');
const path = require('path');
const fs = require('fs');

const PUBLIC_DIR = path.join(__dirname, '..', 'public');

const cssFiles = [
    'bulma.css',
    'fonts.css',
    'normalize.css',
    'main.css'
].map(name => path.join(PUBLIC_DIR, 'css', name));

const cleanStyles = css => new CleanCSS({
    rebase: false,
    returnPromise: true
}).minify(css);

const asyncUncss = (html, options) => new Promise((resolve, reject) => {
    return uncss(html, options, (error, output) => {
        if (error) {
            return reject(error);
        }

        return resolve(output);
    })
});

const minifyFiles = (names, output) => cleanStyles(names)
    .then(data => {
        fs.writeFileSync(path.join(PUBLIC_DIR, 'css', output), data.styles);
        return data.styles;
    });

const createCriticalCSS = (rawHTML, cssFilenames) => asyncUncss(html, {
        stylesheets: cssFilenames
    }).then(cleanStyles)
    .then(data => data.styles);

minifyFiles(cssFiles, 'build.min.css')
    .then(styles => {
        const htmlFile = path.join(PUBLIC_DIR, 'index.html');
        const cssFile = path.join(PUBLIC_DIR, 'css', 'build.min.css');
        const rawHTML = fs.readFileSync(htmlFile).toString();

        return createCriticalCSS(rawHTML, [cssFile]);
    })
    .then(criticalStyles => {
        fs.writeFileSync(path.join(PUBLIC_DIR, 'css', 'core.min.css'), criticalStyles)
    })
    .catch(error => {
        console.log('Error while minifying files', error);
    });
<commit_msg>Fixed a css core build script<commit_after>const CleanCSS = require('clean-css');
const uncss = require('uncss');
const path = require('path');
const fs = require('fs');

const PUBLIC_DIR = path.join(__dirname, '..', 'public');

const cssFiles = [
    'bulma.css',
    'fonts.css',
    'normalize.css',
    'main.css'
].map(name => path.join(PUBLIC_DIR, 'css', name));

const cleanStyles = css => new CleanCSS({
    rebase: false,
    returnPromise: true
}).minify(css);

const asyncUncss = (html, options) => new Promise((resolve, reject) => {
    return uncss(html, options, (error, output) => {
        if (error) {
            return reject(error);
        }

        return resolve(output);
    })
});

const minifyFiles = (names, output) => cleanStyles(names)
    .then(data => {
        fs.writeFileSync(path.join(PUBLIC_DIR, 'css', output), data.styles);
        return data.styles;
    });

const createCriticalCSS = (rawHTML, cssFilenames) => asyncUncss(rawHTML, {
        stylesheets: cssFilenames
    }).then(cleanStyles)
    .then(data => data.styles);

minifyFiles(cssFiles, 'build.min.css')
    .then(styles => {
        const htmlFile = path.join(PUBLIC_DIR, 'index.html');
        const cssFile = path.join(PUBLIC_DIR, 'css', 'build.min.css');
        const rawHTML = fs.readFileSync(htmlFile).toString();

        return createCriticalCSS(rawHTML, [cssFile]);
    })
    .then(criticalStyles => {
        fs.writeFileSync(path.join(PUBLIC_DIR, 'css', 'core.min.css'), criticalStyles)
    })
    .catch(error => {
        console.log('Error while minifying files', error);
    });
<|endoftext|>


<commit_before>/* global define */
define(['app'], function (app) {
  'use strict';

  app.config(function (fileManagerConfigProvider) {
    var defaults = fileManagerConfigProvider.$get();

    fileManagerConfigProvider.set({
      appName: undefined,
      defaultLang: 'de',
      hidePermissions: true,
      useBinarySizePrefixes: true,
      allowedActions: angular.extend(defaults.allowedActions, {
        upload: true,
        remove: true,
        edit: false,
        changePermissions: false,
        compress: false,
        compressChooseName: false,
        extract: false,
        preview: false
      }),
      listUrl: '/api/files/list',
      downloadFileUrl: '/api/files/download',
      uploadUrl: '/api/files/upload',
      removeUrl: '/api/files/remove',
      createFolderUrl: '/api/files/createFolder'
    });
  });
});
<commit_msg>Set rename and copy url<commit_after>/* global define */
define(['app', angular], function (app, ng) {
  'use strict';

  app.config(function (fileManagerConfigProvider) {
    var defaults = fileManagerConfigProvider.$get();

    fileManagerConfigProvider.set({
      appName: undefined,
      defaultLang: 'de',
      hidePermissions: true,
      useBinarySizePrefixes: true,
      allowedActions: ng.extend(defaults.allowedActions, {
        upload: true,
        remove: true,
        edit: false,
        changePermissions: false,
        compress: false,
        compressChooseName: false,
        extract: false,
        preview: false
      }),
      listUrl: '/api/files/list',
      downloadFileUrl: '/api/files/download',
      uploadUrl: '/api/files/upload',
      removeUrl: '/api/files/remove',
      createFolderUrl: '/api/files/createFolder',
      renameUrl: '/api/files/rename',
      copyUrl: '/api/files/copy',
    });
  });
});
<|endoftext|>


<commit_before>let rmr = require("rmr");
let fs = require("fs");
let path = require("path");
let SVGIcons2SVGFontStream = require("svgicons2svgfont");
let svg2ttf = require("svg2ttf");
let ttf2woff2 = require("ttf2woff2");
let ttf2woff = require("ttf2woff");
let sass = require("node-sass");
let mkdirp = require("mkdirp");
let svgo = require("svgo");
let svgstore = require("svgstore");
let glob = require("glob");

let tasks = require("./tasks.js");

let icons = require("../icons.json");

//Output paths
let paths = {};
paths.svgFont = "./dist/fonts/siimple-icons.font.svg";
paths.ttfFont = "./dist/fonts/siimple-icons.font.ttf";
paths.woffFont = "./dist/fonts/siimple-icons.font.woff";
paths.woff2Font = "./dist/fonts/siimple-icons.font.woff2";

//Clean dist folder
tasks.task("dist:clean", function (done) {
    tasks.logger.log("Cleaning folder ./dist");
    return rmr("./dist/", function (error) {
        return done(error);
    });
});

//Create the dist folder
tasks.task("dist:create", function (done) {
    return mkdirp("./dist/fonts", function (error) {
        return done(error);
    })
});

//Compile SCSS files and generate the final CSS files
tasks.task("compile:scss", function (done) {
    return fs.readFile("./scss/siimple-icons.scss", "utf8", function (error, content) {
        if (error) {
            return done(error);
        }
        //Compile the scss file
        return sass.render({data: content, includePaths: ["./scss/"]}, function (error, result) {
            if (error) {
                return done(error);
            }
            //Write the compiled css file
            return fs.writeFile("./dist/siimple-icons.css", result.css, "utf8", function (error) {
                return done(error);
            });
        });
    });
});

//Build the svg sprite
tasks.task("compile:svg", function (done) {
    return glob("./svg/*.svg", function (error, files) {
        if (error) {
            return done(error);
        }
        //Sprites storage
        let sprites = svgstore();
        let parseSvg = function (index) {
            if (index >= files.length) {
                let output = "./dist/siimple-icons.svg";
                return fs.writeFile(output, sprites, "utf8", function (error) {
                    return done(error);
                });
            }
            let file = files[index];
            tasks.logger.log("Adding icon '" + file + "' to svg sprite");
            return fs.readFile(file, "utf8", function (error, content) {
                if (error) {
                    return done(error);
                }
                //Initialize the svg minimize
                let prefix = path.basename(file, path.extname(file));
                let svgmin = new svgo({plugins: [{cleanupIDs: {prefix: prefix + '-', minify: true}}]});
                return svgmin.optimize(content).then(function (result) {
                    //Save to the svg sprite
                    sprites.add(prefix, result);
                    return parseSvg(index + 1);
                });
            });
        };
        return parseSvg(0);
    });
});

//Build the SVG font
tasks.task("font:svg", function (done) {
    let fontStream = new SVGIcons2SVGFontStream({fontName: "SiimpleIcons", normalize: true, fontHeight: 1000});
    let writer = fs.createWriteStream(paths.svgFont);
    fontStream.pipe(writer);
    //Error listener
    fontStream.on('error', function (error) {
        return done(error);
    });
    //Writer finished
    writer.on('finish', function () {
        tasks.logger.log("Font saved as " + paths.svgFont);
        return done();
    });
    //Add each icon in the font stream
    icons.forEach(function (icon) {
        tasks.logger.log("Adding icon '" + icon.id + "' to SVG font");
        let iconPath = path.join("./svg/", icon.id + ".svg");
        let iconReader = fs.createReadStream(iconPath);
        //Set the icon metadata
        iconReader.metadata = {unicode: [String.fromCharCode(icon.unicode)], name: icon.id};
        fontStream.write(iconReader);
    });
    fontStream.end();
});

//Build font in ttf format
tasks.task("font:ttf", function (done) {
    return fs.readFile(paths.svgFont, "utf8", function (error, content) {
        if (error) {
            return done(error);
        }
        //Convert the svg font to ttf font format
        let ttf = svg2ttf(content, {});
        tasks.logger.log("Saving ttf font as " + paths.ttfFont);
        return fs.writeFile(paths.ttfFont, new Buffer(ttf.buffer), function (error) {
            return done(error);
        });
    });
});

//Build font in woff format
tasks.task("font:woff", function (done) {
    let input = fs.readFileSync(paths.ttfFont);
    let ttf = new Uint8Array(input);
    let woff = new Buffer(ttf2woff(ttf, {}).buffer);
    fs.writeFileSync(paths.woffFont, woff);
    return done();
});

//Build font in woff2 format
tasks.task("font:woff2", function (done) {
    let input = fs.readFileSync(paths.ttfFont);
    let ttf = new Uint8Array(input);
    fs.writeFileSync(paths.woff2Font, ttf2woff2(ttf));
    return done();
});

//Run all tasks in order
tasks.run();
<commit_msg>Fixed bug generating the svg sprite<commit_after>let rmr = require("rmr");
let fs = require("fs");
let path = require("path");
let SVGIcons2SVGFontStream = require("svgicons2svgfont");
let svg2ttf = require("svg2ttf");
let ttf2woff2 = require("ttf2woff2");
let ttf2woff = require("ttf2woff");
let sass = require("node-sass");
let mkdirp = require("mkdirp");
let svgo = require("svgo");
let svgstore = require("svgstore");
let glob = require("glob");

let tasks = require("./tasks.js");

let icons = require("../icons.json");

//Output paths
let paths = {};
paths.svgFont = "./dist/fonts/siimple-icons.font.svg";
paths.ttfFont = "./dist/fonts/siimple-icons.font.ttf";
paths.woffFont = "./dist/fonts/siimple-icons.font.woff";
paths.woff2Font = "./dist/fonts/siimple-icons.font.woff2";

//Clean dist folder
tasks.task("dist:clean", function (done) {
    tasks.logger.log("Cleaning folder ./dist");
    return rmr("./dist/", function (error) {
        return done(error);
    });
});

//Create the dist folder
tasks.task("dist:create", function (done) {
    return mkdirp("./dist/fonts", function (error) {
        return done(error);
    })
});

//Compile SCSS files and generate the final CSS files
tasks.task("compile:scss", function (done) {
    return fs.readFile("./scss/siimple-icons.scss", "utf8", function (error, content) {
        if (error) {
            return done(error);
        }
        //Compile the scss file
        return sass.render({data: content, includePaths: ["./scss/"]}, function (error, result) {
            if (error) {
                return done(error);
            }
            //Write the compiled css file
            return fs.writeFile("./dist/siimple-icons.css", result.css, "utf8", function (error) {
                return done(error);
            });
        });
    });
});

//Build the svg sprite
tasks.task("compile:svg", function (done) {
    return glob("./svg/*.svg", function (error, files) {
        if (error) {
            return done(error);
        }
        //Sprites storage
        let sprites = svgstore();
        let parseSvg = function (index) {
            if (index >= files.length) {
                let output = "./dist/siimple-icons.svg";
                return fs.writeFile(output, sprites, "utf8", function (error) {
                    return done(error);
                });
            }
            let file = files[index];
            tasks.logger.log("Adding icon '" + file + "' to svg sprite");
            return fs.readFile(file, "utf8", function (error, content) {
                if (error) {
                    return done(error);
                }
                //Initialize the svg minimize
                let prefix = path.basename(file, path.extname(file));
                let svgmin = new svgo({plugins: [{cleanupIDs: {prefix: prefix + '-', minify: true}}]});
                return svgmin.optimize(content).then(function (result) {
                    //Save to the svg sprite
                    sprites.add(prefix, result.data);
                    return parseSvg(index + 1);
                });
            });
        };
        return parseSvg(0);
    });
});

//Build the SVG font
tasks.task("font:svg", function (done) {
    let fontStream = new SVGIcons2SVGFontStream({fontName: "SiimpleIcons", normalize: true, fontHeight: 1000});
    let writer = fs.createWriteStream(paths.svgFont);
    fontStream.pipe(writer);
    //Error listener
    fontStream.on('error', function (error) {
        return done(error);
    });
    //Writer finished
    writer.on('finish', function () {
        tasks.logger.log("Font saved as " + paths.svgFont);
        return done();
    });
    //Add each icon in the font stream
    icons.forEach(function (icon) {
        tasks.logger.log("Adding icon '" + icon.id + "' to SVG font");
        let iconPath = path.join("./svg/", icon.id + ".svg");
        let iconReader = fs.createReadStream(iconPath);
        //Set the icon metadata
        iconReader.metadata = {unicode: [String.fromCharCode(icon.unicode)], name: icon.id};
        fontStream.write(iconReader);
    });
    fontStream.end();
});

//Build font in ttf format
tasks.task("font:ttf", function (done) {
    return fs.readFile(paths.svgFont, "utf8", function (error, content) {
        if (error) {
            return done(error);
        }
        //Convert the svg font to ttf font format
        let ttf = svg2ttf(content, {});
        tasks.logger.log("Saving ttf font as " + paths.ttfFont);
        return fs.writeFile(paths.ttfFont, new Buffer(ttf.buffer), function (error) {
            return done(error);
        });
    });
});

//Build font in woff format
tasks.task("font:woff", function (done) {
    let input = fs.readFileSync(paths.ttfFont);
    let ttf = new Uint8Array(input);
    let woff = new Buffer(ttf2woff(ttf, {}).buffer);
    fs.writeFileSync(paths.woffFont, woff);
    return done();
});

//Build font in woff2 format
tasks.task("font:woff2", function (done) {
    let input = fs.readFileSync(paths.ttfFont);
    let ttf = new Uint8Array(input);
    fs.writeFileSync(paths.woff2Font, ttf2woff2(ttf));
    return done();
});

//Run all tasks in order
tasks.run();
<|endoftext|>


<commit_before>const os = require('os');
const fs = require('fs');
const shell = require('shelljs');
const env = require('./env.js');

function exec(action) {
    const res = shell.exec(action);

    if (res.code !== 0) {
        shell.echo('Unable to build zookeeper library');
        shell.exit(1);
    }
}

function handleSunOS() {
    const uname = shell.exec('uname -v');

    if (uname.match('joyent_.*')) {
        const res = shell.exec(`pkgin list | grep zookeeper-client-${env.ZK_VERSION}`);

        if (res.code !== 0) {
            shell.echo('You must install zookeeper before installing this module. Try:');
            shell.echo(`pkgin install zookeeper-client-${env.ZK_VERSION}`);
        }
    }
}

if (os.platform() === 'SunOS') {
    handleSunOS();
    return;
}

const isAlreadyBuilt = fs.existsSync(`${env.BUILD}/lib/libzookeeper_st.la`);

if (isAlreadyBuilt) {
    shell.echo('Zookeeper has already been built');
    shell.exit(0);
    return;
}

shell.cd(`${env.ZK_DEPS}/src/c`);

exec('./configure --without-syncapi --enable-static --disable-shared --with-pic');
exec('make');

shell.cd(env.ROOT);

<commit_msg>refactor: includes platform name<commit_after>const os = require('os');
const fs = require('fs');
const shell = require('shelljs');
const env = require('./env.js');

function exec(action) {
    const res = shell.exec(action);

    if (res.code !== 0) {
        shell.echo('Unable to build zookeeper library');
        shell.exit(1);
    }
}

function handleSunOS() {
    const uname = shell.exec('uname -v');

    if (uname.match('joyent_.*')) {
        const res = shell.exec(`pkgin list | grep zookeeper-client-${env.ZK_VERSION}`);

        if (res.code !== 0) {
            shell.echo('You must install zookeeper before installing this module. Try:');
            shell.echo(`pkgin install zookeeper-client-${env.ZK_VERSION}`);
        }
    }
}

if (os.platform().toLowerCase().includes('sunos')) {
    handleSunOS();
    return;
}

const isAlreadyBuilt = fs.existsSync(`${env.BUILD}/lib/libzookeeper_st.la`);

if (isAlreadyBuilt) {
    shell.echo('Zookeeper has already been built');
    shell.exit(0);
    return;
}

shell.cd(`${env.ZK_DEPS}/src/c`);

exec('./configure --without-syncapi --enable-static --disable-shared --with-pic');
exec('make');

shell.cd(env.ROOT);

<|endoftext|>


<commit_before>/*********************************************************
** jQuery timeilinePlugin functions
** how to use : $('#element').timelineComment();
**              $('#element').timelineDelete();
** @parts     : opTimelinePlugin
** @author    : Shouta Kashiwagi <kashiwagi@tejimaya.com>
**********************************************************/
(function($){

  $.fn.timelineComment = function(settings){
    settings = jQuery.extend({
      loader_path: '',
      callback: function(){},
    });

    return this.each(function(){
      $(this).click(function(){
        var id = $(this).attr("data-timeline-id");
        var foreign = $(this).attr('data-activity-foreign');
        var foreignId = $(this).attr('data-activity-foreign-id');
        var body = $('#comment-textarea-'+id).val();
        $timelineLoader = $(this).parent().next();
        $timelineLoader.next().text('');
        $timelineLoader.next().hide();
        $timelineLoader.show();
        $(this).parent().hide();
        $(this).attr('disabled', 'disabled');
        $.ajax({
          url: openpne.apiBase + 'activity/post.json',
          type: 'POST',
          data: {
            body: body,
            in_reply_to_activity_id: id,
            apiKey: openpne.apiKey,
            target: foreign,
            target_id: foreignId
          },
          dataType: 'json',
          success: function(data) {
            if ('success' == data.status)
            {
              data.data.body_html = data.data.body;
              $('#comment-textarea-'+id).val('');
              $timelineLoader.hide();
              $('#timeline-post-comment-form-'+id).show();
              $postData = $('#timelineCommentTemplate').tmpl(data.data);
              $('#timeline-post-comment-form-'+id).before($postData);
            }
            else
            {
              $timelineLoader.hide();
              $timelineLoader.next().text('投稿に失敗しました');
              $timelineLoader.next().show();
              $timelineLoader.prev().show();
            }
          },
          error: function(x, r, t) {
            $timelineLoader.hide();
            $timelineLoader.next().text('投稿に失敗しました');
            $timelineLoader.next().show();
            $timelineLoader.prev().show();
          }
        });

        return false;
      });
    });
  };

  $.fn.timelineDelete = function() {

    return this.each(function(){
      $(this).click(function(){
      $(this).hide();
      $(this).parent().next().show();
      var activity_id = $(this).attr('data-activity-id');
        $.ajax({
          url: openpne.apiBase + 'activity/delete.json',
          type: 'POST',
          data: {
            activity_id: activity_id,
            apiKey: openpne.apiKey
          },
          dataType: 'json',
          success: function(data) {
            $(this).parent().next().hide();
            $.colorbox.close();
            timelineAllLoad();
          },
          error: function(x, r, t) {
            $(this).parent().next().hide();
            $.colorbox.close();
          }
        });
      });
    });
  };

})(jQuery);
<commit_msg>投稿したばかりのコメントが削除出来ないのを修正<commit_after>/*********************************************************
** jQuery timeilinePlugin functions
** how to use : $('#element').timelineComment();
**              $('#element').timelineDelete();
** @parts     : opTimelinePlugin
** @author    : Shouta Kashiwagi <kashiwagi@tejimaya.com>
**********************************************************/
(function($){

  $.fn.timelineComment = function(settings){
    settings = jQuery.extend({
      loader_path: '',
      callback: function(){},
    });

    return this.each(function(){
      $(this).click(function(){
        var id = $(this).attr("data-timeline-id");
        var foreign = $(this).attr('data-activity-foreign');
        var foreignId = $(this).attr('data-activity-foreign-id');
        var body = $('#comment-textarea-'+id).val();
        $timelineLoader = $(this).parent().next();
        $timelineLoader.next().text('');
        $timelineLoader.next().hide();
        $timelineLoader.show();
        $(this).parent().hide();
        $(this).attr('disabled', 'disabled');
        $.ajax({
          url: openpne.apiBase + 'activity/post.json',
          type: 'POST',
          data: {
            body: body,
            in_reply_to_activity_id: id,
            apiKey: openpne.apiKey,
            target: foreign,
            target_id: foreignId
          },
          dataType: 'json',
          success: function(data) {
            if ('success' == data.status)
            {
              data.data.body_html = data.data.body;
              $('#comment-textarea-'+id).val('');
              $timelineLoader.hide();
              $('#timeline-post-comment-form-'+id).show();
              $postData = $('#timelineCommentTemplate').tmpl(data.data);
              $('#timeline-post-comment-form-'+id).before($postData);

              $('button.timeline-post-delete-button').timelineDelete();
              $('.timeline-post-delete-confirm-link').colorbox({
                inline: true,
                width: '610px',
                opacity: '0.8',
                onOpen: function(){
                  $($(this).attr('href')).show();
                },
                onCleanup: function(){
                  $($(this).attr('href')).hide();
                },
                onClosed: function(){
                  timelineAllLoad();
                }
              });
            }
            else
            {
              $timelineLoader.hide();
              $timelineLoader.next().text('投稿に失敗しました');
              $timelineLoader.next().show();
              $timelineLoader.prev().show();
            }
          },
          error: function(x, r, t) {
            $timelineLoader.hide();
            $timelineLoader.next().text('投稿に失敗しました');
            $timelineLoader.next().show();
            $timelineLoader.prev().show();
          }
        });

        return false;
      });
    });
  };

  $.fn.timelineDelete = function() {

    return this.each(function(){
      $(this).click(function(){
      $(this).hide();
      $(this).parent().next().show();
      var activity_id = $(this).attr('data-activity-id');
        $.ajax({
          url: openpne.apiBase + 'activity/delete.json',
          type: 'POST',
          data: {
            activity_id: activity_id,
            apiKey: openpne.apiKey
          },
          dataType: 'json',
          success: function(data) {
            $(this).parent().next().hide();
            $.colorbox.close();
            timelineAllLoad();
          },
          error: function(x, r, t) {
            $(this).parent().next().hide();
            $.colorbox.close();
          }
        });
      });
    });
  };

})(jQuery);
<|endoftext|>


<commit_before>var fs = require('fs');
var os = require('os');
var sh = require('child_process').execSync;
var exec = require('child_process').exec;
var spawn = require('child_process').spawn;
var path = require('path');

var ROOT = process.cwd();
var NODEJS = '.';
var SYNC = false;

if (os.platform() == 'win32') {
  process.chdir(path.resolve(ROOT, '..'));
  ROOT = process.cwd();
  NODEJS = path.resolve(process.env['USERPROFILE'], '.node-gyp', process.version.substring(1));
} else {
  NODEJS = path.resolve(process.env['HOME'], '.node-gyp', process.version.substring(1));
}

if (fs.existsSync(ROOT + path.sep + 'nodejs.gypi')) {
  fs.unlinkSync(ROOT + path.sep + 'nodejs.gypi');
}

if (!fs.existsSync(ROOT + path.sep + 'build' + path.sep + 'config.gypi')) {
  throw new Error('Run node-gyp rebuild instead of node build.js');
}

fs.linkSync(NODEJS + path.sep + 'common.gypi', ROOT + path.sep + 'nodejs.gypi');

var CONFIG = 'Release';

if (fs.existsSync(ROOT + path.sep + 'build' + path.sep + 'Debug')) {
  CONFIG = 'Debug';
}

var THIRD_PARTY = path.resolve(ROOT, 'third_party');
var DEPOT_TOOLS_REPO = 'https://chromium.googlesource.com/chromium/tools/depot_tools.git';
var DEPOT_TOOLS = path.resolve(THIRD_PARTY, 'depot_tools');
var WEBRTC = path.resolve(THIRD_PARTY, 'webrtc');
var WEBRTC_SRC = path.resolve(WEBRTC, 'src');
var WEBRTC_OUT = path.resolve(WEBRTC_SRC, 'out', CONFIG);
var FETCH = path.resolve(DEPOT_TOOLS, (os.platform() == 'win32') ? 'fetch.bat' : 'fetch');
var GCLIENT = path.resolve(DEPOT_TOOLS, (os.platform() == 'win32') ? 'gclient.bat' : 'gclient');

if (os.platform() == 'win32' && process.arch == 'x64') {
  WEBRTC_OUT = path.resolve(WEBRTC_SRC, 'out', CONFIG + '_x64');
}

function build() {
  if (fs.existsSync(WEBRTC_SRC)) {
    sh('python ' + WEBRTC_SRC + path.sep + 'webrtc' + path.sep + 'build' + path.sep + 'gyp_webrtc src' + path.sep + 'webrtc.gyp', {
      cwd: ROOT,
      env: process.env,
      stdio: 'inherit',
    });

    sh('ninja -C ' + WEBRTC_OUT, {
      cwd: WEBRTC_SRC,
      env: process.env,
      stdio: 'inherit',
    });

    fs.linkSync(WEBRTC_OUT + path.sep + 'webrtc-native.node', ROOT + path.sep + 'build' + path.sep + CONFIG + path.sep + 'webrtc-native.node');
    console.log('Done! :)');
  }
}

function sync() {
  if (!SYNC) {
    if (fs.existsSync(THIRD_PARTY + path.sep + 'webrtc_sync')) {
      var stat = fs.statSync(THIRD_PARTY + path.sep + 'webrtc_sync');

      if (((new Date().getTime()) - stat.mtime.getTime()) > 86400000) {
        SYNC = true;
      }
    } else {
      SYNC = true;
    }
  }

  if (!SYNC) {
    return build();
  }

  var res = spawn(GCLIENT, ['sync'], {
    cwd: WEBRTC,
    env: process.env,
    stdio: 'inherit',
  });

  res.on('close', function (code) {
    if (!code) {
      fs.closeSync(fs.openSync(THIRD_PARTY + path.sep + 'webrtc_sync', 'w'));
      return build();
    }

    process.exit(1);
  });
}

function configure() {
  process.env['GYP_DEFINES'] += ' third_party=' + THIRD_PARTY;
  process.env['GYP_DEFINES'] += ' target_arch=' + process.arch;
  process.env['GYP_DEFINES'] += ' host_arch=' + process.arch;
  process.env['GYP_DEFINES'] += ' nodedir=' + NODEJS;
  process.env['GYP_DEFINES'] += ' configuration=' + CONFIG;
  process.env['GYP_DEFINES'] += ' build_with_chromium=0';
  process.env['GYP_DEFINES'] += ' include_tests=0';
  process.env['GYP_DEFINES'] += ' uv_library=static_library';

  switch (os.platform()) {
    case 'darwin':
      process.env['GYP_DEFINES'] += ' clang=1';

      break;
    case 'win32':
      process.env['DEPOT_TOOLS_WIN_TOOLCHAIN'] = 0;

      break;
    case 'linux':
      process.env['GYP_DEFINES'] += ' clang=0';

      if (!process.env['JAVA_HOME']) {
        if (fs.existsSync('/usr/lib/jvm/java')) {
          process.env['JAVA_HOME'] = '/usr/lib/jvm/java';
        } else {
          process.env['JAVA_HOME'] = '/usr/lib/jvm/default-java';
        }
      }

      break;
    default:
      break;
  }

  console.log('target_arch =', process.arch);
  console.log('host_arch =', process.arch);
  console.log('configuration =', CONFIG);

  sync();
}

function fetch(rerun) {
  if (!fs.existsSync(WEBRTC) || !fs.existsSync(WEBRTC_SRC)) {
    if (!fs.existsSync(WEBRTC)) {
      fs.mkdirSync(WEBRTC);
    }

    var res = spawn(FETCH, ['--nohooks', 'webrtc'], {
      cwd: WEBRTC,
      env: process.env,
      stdio: 'inherit',
    });

    res.on('close', function (code) {
      if (!code) {
        return configure();
      }

      if (os.platform() == 'win32' && !rerun) {
        return fetch(true);
      }

      process.exit(1);
    });
  } else {
    configure();
  }
}

function prep() {
  process.env['GYP_DEFINES'] = process.env['GYP_DEFINES'] ? process.env['GYP_DEFINES'] : '';

  if (!fs.existsSync(THIRD_PARTY)) {
    fs.mkdirSync(THIRD_PARTY);
  }

  if (!fs.existsSync(DEPOT_TOOLS)) {
    sh('git clone ' + DEPOT_TOOLS_REPO, {
      cwd: THIRD_PARTY,
      env: process.env,
      stdio: 'inherit',
    });
  }

  process.env['PATH'] = process.env['PATH'] + path.delimiter + DEPOT_TOOLS;
  fetch(false);
}

// TODO(): apt-get install

prep();
<commit_msg>Fix link<commit_after>var fs = require('fs');
var os = require('os');
var sh = require('child_process').execSync;
var exec = require('child_process').exec;
var spawn = require('child_process').spawn;
var path = require('path');

var ROOT = process.cwd();
var NODEJS = '.';
var SYNC = false;

if (os.platform() == 'win32') {
  process.chdir(path.resolve(ROOT, '..'));
  ROOT = process.cwd();
  NODEJS = path.resolve(process.env['USERPROFILE'], '.node-gyp', process.version.substring(1));
} else {
  NODEJS = path.resolve(process.env['HOME'], '.node-gyp', process.version.substring(1));
}

if (fs.existsSync(ROOT + path.sep + 'nodejs.gypi')) {
  fs.unlinkSync(ROOT + path.sep + 'nodejs.gypi');
}

if (!fs.existsSync(ROOT + path.sep + 'build' + path.sep + 'config.gypi')) {
  throw new Error('Run node-gyp rebuild instead of node build.js');
}

if (os.platform() == 'linux') {
  if (fs.existsSync('/usr/include/node/common.gypi')) {
    fs.linkSync('/usr/include/node/common.gypi', ROOT + path.sep + 'nodejs.gypi');
  }
} else {
  fs.linkSync(NODEJS + path.sep + 'common.gypi', ROOT + path.sep + 'nodejs.gypi');
}

var CONFIG = 'Release';

if (fs.existsSync(ROOT + path.sep + 'build' + path.sep + 'Debug')) {
  CONFIG = 'Debug';
}

var THIRD_PARTY = path.resolve(ROOT, 'third_party');
var DEPOT_TOOLS_REPO = 'https://chromium.googlesource.com/chromium/tools/depot_tools.git';
var DEPOT_TOOLS = path.resolve(THIRD_PARTY, 'depot_tools');
var WEBRTC = path.resolve(THIRD_PARTY, 'webrtc');
var WEBRTC_SRC = path.resolve(WEBRTC, 'src');
var WEBRTC_OUT = path.resolve(WEBRTC_SRC, 'out', CONFIG);
var FETCH = path.resolve(DEPOT_TOOLS, (os.platform() == 'win32') ? 'fetch.bat' : 'fetch');
var GCLIENT = path.resolve(DEPOT_TOOLS, (os.platform() == 'win32') ? 'gclient.bat' : 'gclient');

if (os.platform() == 'win32' && process.arch == 'x64') {
  WEBRTC_OUT = path.resolve(WEBRTC_SRC, 'out', CONFIG + '_x64');
}

function build() {
  if (fs.existsSync(WEBRTC_SRC)) {
    sh('python ' + WEBRTC_SRC + path.sep + 'webrtc' + path.sep + 'build' + path.sep + 'gyp_webrtc src' + path.sep + 'webrtc.gyp', {
      cwd: ROOT,
      env: process.env,
      stdio: 'inherit',
    });

    sh('ninja -C ' + WEBRTC_OUT, {
      cwd: WEBRTC_SRC,
      env: process.env,
      stdio: 'inherit',
    });

    fs.linkSync(WEBRTC_OUT + path.sep + 'webrtc-native.node', ROOT + path.sep + 'build' + path.sep + CONFIG + path.sep + 'webrtc-native.node');
    console.log('Done! :)');
  }
}

function sync() {
  if (!SYNC) {
    if (fs.existsSync(THIRD_PARTY + path.sep + 'webrtc_sync')) {
      var stat = fs.statSync(THIRD_PARTY + path.sep + 'webrtc_sync');

      if (((new Date().getTime()) - stat.mtime.getTime()) > 86400000) {
        SYNC = true;
      }
    } else {
      SYNC = true;
    }
  }

  if (!SYNC) {
    return build();
  }

  var res = spawn(GCLIENT, ['sync'], {
    cwd: WEBRTC,
    env: process.env,
    stdio: 'inherit',
  });

  res.on('close', function (code) {
    if (!code) {
      fs.closeSync(fs.openSync(THIRD_PARTY + path.sep + 'webrtc_sync', 'w'));
      return build();
    }

    process.exit(1);
  });
}

function configure() {
  process.env['GYP_DEFINES'] += ' third_party=' + THIRD_PARTY;
  process.env['GYP_DEFINES'] += ' target_arch=' + process.arch;
  process.env['GYP_DEFINES'] += ' host_arch=' + process.arch;
  process.env['GYP_DEFINES'] += ' nodedir=' + NODEJS;
  process.env['GYP_DEFINES'] += ' configuration=' + CONFIG;
  process.env['GYP_DEFINES'] += ' build_with_chromium=0';
  process.env['GYP_DEFINES'] += ' include_tests=0';
  process.env['GYP_DEFINES'] += ' uv_library=static_library';

  switch (os.platform()) {
    case 'darwin':
      process.env['GYP_DEFINES'] += ' clang=1';

      break;
    case 'win32':
      process.env['DEPOT_TOOLS_WIN_TOOLCHAIN'] = 0;

      break;
    case 'linux':
      process.env['GYP_DEFINES'] += ' clang=0';

      if (!process.env['JAVA_HOME']) {
        if (fs.existsSync('/usr/lib/jvm/java')) {
          process.env['JAVA_HOME'] = '/usr/lib/jvm/java';
        } else {
          process.env['JAVA_HOME'] = '/usr/lib/jvm/default-java';
        }
      }

      break;
    default:
      break;
  }

  console.log('target_arch =', process.arch);
  console.log('host_arch =', process.arch);
  console.log('configuration =', CONFIG);

  sync();
}

function fetch(rerun) {
  if (!fs.existsSync(WEBRTC) || !fs.existsSync(WEBRTC_SRC)) {
    if (!fs.existsSync(WEBRTC)) {
      fs.mkdirSync(WEBRTC);
    }

    var res = spawn(FETCH, ['--nohooks', 'webrtc'], {
      cwd: WEBRTC,
      env: process.env,
      stdio: 'inherit',
    });

    res.on('close', function (code) {
      if (!code) {
        return configure();
      }

      if (os.platform() == 'win32' && !rerun) {
        return fetch(true);
      }

      process.exit(1);
    });
  } else {
    configure();
  }
}

function prep() {
  process.env['GYP_DEFINES'] = process.env['GYP_DEFINES'] ? process.env['GYP_DEFINES'] : '';

  if (!fs.existsSync(THIRD_PARTY)) {
    fs.mkdirSync(THIRD_PARTY);
  }

  if (!fs.existsSync(DEPOT_TOOLS)) {
    sh('git clone ' + DEPOT_TOOLS_REPO, {
      cwd: THIRD_PARTY,
      env: process.env,
      stdio: 'inherit',
    });
  }

  process.env['PATH'] = process.env['PATH'] + path.delimiter + DEPOT_TOOLS;
  fetch(false);
}

// TODO(): apt-get install

prep();
<|endoftext|>


<commit_before>/**
 * Copyright (c) 2002-2016 "Neo Technology,"
 * Network Engine for Objects in Lund AB [http://neotechnology.com]
 *
 * This file is part of Neo4j.
 *
 * 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.
 */

import {debug} from "./log";
import {HeapBuffer} from "./buf";

/**
 * Create a new WebSocketChannel to be used in web browsers.
 * @access private
 */
class WebSocketChannel {

  /**
   * Create new instance
   * @param {Object} opts - Options object
   * @param {string} opts.host - The host, including protocol to connect to.
   * @param {Integer} opts.port - The port to use.
   */
  constructor (opts) {
    this._url = "ws:" + opts.host + ":" + (opts.port || 7688);
    this._ws = new WebSocket(this._url);
    this._ws.binaryType = "arraybuffer";
    this._open = true;
    this._pending = [];

    let self = this;
    this._ws.onopen = function() {
      // Drain all pending messages
      let pending = self._pending;
      self._pending = null;
      for (let i = 0; i < pending.length; i++) {
        self.write( pending[i] );
      }
    };
    this._ws.onmessage = (event) => {
      if( self.onmessage ) {
        var b = new HeapBuffer( event.data );
        self.onmessage( b );
      }
    };
  }

  /**
   * Write the passed in buffer to connection
   * @param {HeapBuffer} buffer - Buffer to write
   */
  write ( buffer ) {
    // If there is a pending queue, push this on that queue. This means
    // we are not yet connected, so we queue things locally.
    if( this._pending !== null ) {
      this._pending.push( buffer );
    } else if( buffer instanceof HeapBuffer ) {
      this._ws.send( buffer._buffer );
    } else {
      throw new Error( "Don't know how to send buffer: " + buffer );
    }
  }

  /**
   * Close the connection
   * @param {function} cb - Function to call on close.
   */
  close ( cb ) {
    if(cb) {
      this._ws.onclose(cb);
    }
    this._open = false;
    this._ws.close();
  }
}

let available = typeof WebSocket !== 'undefined';
let _websocketChannelModule = {channel: WebSocketChannel, available: available};

export default _websocketChannelModule
<commit_msg>Changed port from 7688 to 7687<commit_after>/**
 * Copyright (c) 2002-2016 "Neo Technology,"
 * Network Engine for Objects in Lund AB [http://neotechnology.com]
 *
 * This file is part of Neo4j.
 *
 * 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.
 */

import {debug} from "./log";
import {HeapBuffer} from "./buf";

/**
 * Create a new WebSocketChannel to be used in web browsers.
 * @access private
 */
class WebSocketChannel {

  /**
   * Create new instance
   * @param {Object} opts - Options object
   * @param {string} opts.host - The host, including protocol to connect to.
   * @param {Integer} opts.port - The port to use.
   */
  constructor (opts) {
    this._url = "ws:" + opts.host + ":" + (opts.port || 7687);
    this._ws = new WebSocket(this._url);
    this._ws.binaryType = "arraybuffer";
    this._open = true;
    this._pending = [];

    let self = this;
    this._ws.onopen = function() {
      // Drain all pending messages
      let pending = self._pending;
      self._pending = null;
      for (let i = 0; i < pending.length; i++) {
        self.write( pending[i] );
      }
    };
    this._ws.onmessage = (event) => {
      if( self.onmessage ) {
        var b = new HeapBuffer( event.data );
        self.onmessage( b );
      }
    };
  }

  /**
   * Write the passed in buffer to connection
   * @param {HeapBuffer} buffer - Buffer to write
   */
  write ( buffer ) {
    // If there is a pending queue, push this on that queue. This means
    // we are not yet connected, so we queue things locally.
    if( this._pending !== null ) {
      this._pending.push( buffer );
    } else if( buffer instanceof HeapBuffer ) {
      this._ws.send( buffer._buffer );
    } else {
      throw new Error( "Don't know how to send buffer: " + buffer );
    }
  }

  /**
   * Close the connection
   * @param {function} cb - Function to call on close.
   */
  close ( cb ) {
    if(cb) {
      this._ws.onclose(cb);
    }
    this._open = false;
    this._ws.close();
  }
}

let available = typeof WebSocket !== 'undefined';
let _websocketChannelModule = {channel: WebSocketChannel, available: available};

export default _websocketChannelModule
<|endoftext|>


<commit_before>const fetch = require('node-fetch');
const moment = require('moment');
moment.locale('fi');

class SlackChannelStatus {

  constructor(apiKey) {
    this.apiKey = apiKey;
  }

  async getChannelHistoryJson(method, channelId, startFrom = 0) {
    // If oldest is used then it will return that and amount of count newer ones. Have to do decision when we have anough manually.
    const result = await fetch(`https://slack.com/api/${method}?token=${this.apiKey}&channel=${channelId}&latest=${startFrom}&count=1000&pretty=0`);
    return await result.json();
  }

  async getChannelMembers(channelId) {
    const isPublic = await this.isChannelPublic(channelId);
    const method =  isPublic ? 'channels.info' : 'groups.info';
    const result = await fetch(`https://slack.com/api/${method}?token=${this.apiKey}&channel=${channelId}`);
    var json = await result.json();
    return isPublic ? json.channel.members : json.group.members;
  }

  async getUser(userId) {
    const result = await fetch(`https://slack.com/api/users.info?token=${this.apiKey}&user=${userId}&pretty=0`);
    const json = await result.json();
    return json.ok ? json.user : {};
  }

  async isChannelPublic(channelId) {
    const result = await fetch(`https://slack.com/api/channels.info?token=${this.apiKey}&channel=${channelId}`);
    const json = await result.json();
    return json.ok;
  }

  async getActivity(channelId, days = 7, top = 5) {

    const listMethod = await this.isChannelPublic(channelId) ? 'channels.history' : 'groups.history';

    const lastWeek = moment().add(-1 * days, 'days');
    const oldestTimeStamp = lastWeek.unix();

    let messages = [];
    let startFrom = 0;

    while (true) {
      let json = await this.getChannelHistoryJson(listMethod, channelId, startFrom);

      if (json.ok === false)
        return null;

      let lastInArray = json.messages[json.messages.length - 1].ts;

      if (oldestTimeStamp >= lastInArray) {
        let toAdd = json.messages.filter(e => e.ts >= oldestTimeStamp);
        messages = messages.concat(toAdd);
        break;
      }

      messages = messages.concat(json.messages);

      if (json.has_more === false)
        break;

      startFrom = lastInArray;
    }

    const userGrouped = messages.reduce((grouped, item) => {
      if (!item || item.subtype == "bot_message") return grouped;

      const key = item.user || item.comment.user;
      grouped[key] = grouped[key] || [];
      grouped[key].push(item);
      return grouped
    }, {});

    const groupedArray = Object.keys(userGrouped).map(key => {
      return {
        id: key,
        count: userGrouped[key].length
      }
    });

    const sortedArray = groupedArray.sort((a, b) => a.count - b.count).reverse();
    const itemCount = messages.length;

    let topList;

    if (top == 0) {
      const members = await this.getChannelMembers(channelId);
      const passiveMembers = members.filter(e => sortedArray.some(s => s.id == e) === false);
      topList = passiveMembers.map(e => {
        return { id: e, count: 0, percentage: 0 };
      });
    } else {
      topList = sortedArray.slice(0, top).map(e => {
        return {
          id: e.id,
          count: e.count,
          percentage: (e.count / itemCount * 100).toFixed(1)
        };
      });
    }

    const userPromises = topList.map(e => this.getUser(e.id));

    const users = await Promise.all(userPromises);

    topList.forEach((item, idx) => {
      item.name = users[idx].real_name;
    });

    const othersPercentage = ((itemCount - topList.reduce((sum, item) => sum + item.count, 0)) / itemCount * 100).toFixed(1);

    const oldestMessage = moment.unix(messages[messages.length - 1].ts);

    return {
      from: oldestMessage.format('HH:mm DD.MM.YYYY'),
      messages: itemCount,
      top: topList,
      others: othersPercentage,
      active: groupedArray.length
    };
  }

}

module.exports = SlackChannelStatus;<commit_msg>Ignore join/leave messages in stats<commit_after>const fetch = require('node-fetch');
const moment = require('moment');
moment.locale('fi');

class SlackChannelStatus {

  constructor(apiKey) {
    this.apiKey = apiKey;
  }

  async getChannelHistoryJson(method, channelId, startFrom = 0) {
    // If oldest is used then it will return that and amount of count newer ones. Have to do decision when we have anough manually.
    const result = await fetch(`https://slack.com/api/${method}?token=${this.apiKey}&channel=${channelId}&latest=${startFrom}&count=1000&pretty=0`);
    return await result.json();
  }

  async getChannelMembers(channelId) {
    const isPublic = await this.isChannelPublic(channelId);
    const method =  isPublic ? 'channels.info' : 'groups.info';
    const result = await fetch(`https://slack.com/api/${method}?token=${this.apiKey}&channel=${channelId}`);
    var json = await result.json();
    return isPublic ? json.channel.members : json.group.members;
  }

  async getUser(userId) {
    const result = await fetch(`https://slack.com/api/users.info?token=${this.apiKey}&user=${userId}&pretty=0`);
    const json = await result.json();
    return json.ok ? json.user : {};
  }

  async isChannelPublic(channelId) {
    const result = await fetch(`https://slack.com/api/channels.info?token=${this.apiKey}&channel=${channelId}`);
    const json = await result.json();
    return json.ok;
  }

  async getActivity(channelId, days = 7, top = 5) {

    const listMethod = await this.isChannelPublic(channelId) ? 'channels.history' : 'groups.history';

    const lastWeek = moment().add(-1 * days, 'days');
    const oldestTimeStamp = lastWeek.unix();

    let messages = [];
    let startFrom = 0;

    while (true) {
      let json = await this.getChannelHistoryJson(listMethod, channelId, startFrom);

      if (json.ok === false)
        return null;

      let lastInArray = json.messages[json.messages.length - 1].ts;

      if (oldestTimeStamp >= lastInArray) {
        let toAdd = json.messages.filter(e => e.ts >= oldestTimeStamp);
        messages = messages.concat(toAdd);
        break;
      }

      messages = messages.concat(json.messages);

      if (json.has_more === false)
        break;

      startFrom = lastInArray;
    }

    const userGrouped = messages.reduce((grouped, item) => {
      if (!item || item.type !== "message" || item.subtype === "bot_message" ||
          item.subtype === "group_join" || item.subtype === "group_leave") return grouped;

      const key = item.user || item.comment.user;
      grouped[key] = grouped[key] || [];
      grouped[key].push(item);
      return grouped
    }, {});

    const groupedArray = Object.keys(userGrouped).map(key => {
      return {
        id: key,
        count: userGrouped[key].length
      }
    });

    const sortedArray = groupedArray.sort((a, b) => a.count - b.count).reverse();
    const itemCount = messages.length;

    let topList;

    if (top == 0) {
      const members = await this.getChannelMembers(channelId);
      const passiveMembers = members.filter(e => sortedArray.some(s => s.id == e) === false);
      topList = passiveMembers.map(e => {
        return { id: e, count: 0, percentage: 0 };
      });
    } else {
      topList = sortedArray.slice(0, top).map(e => {
        return {
          id: e.id,
          count: e.count,
          percentage: (e.count / itemCount * 100).toFixed(1)
        };
      });
    }

    const userPromises = topList.map(e => this.getUser(e.id));

    const users = await Promise.all(userPromises);

    topList.forEach((item, idx) => {
      item.name = users[idx].real_name;
    });

    const othersPercentage = ((itemCount - topList.reduce((sum, item) => sum + item.count, 0)) / itemCount * 100).toFixed(1);

    const oldestMessage = moment.unix(messages[messages.length - 1].ts);

    return {
      from: oldestMessage.format('HH:mm DD.MM.YYYY'),
      messages: itemCount,
      top: topList,
      others: othersPercentage,
      active: groupedArray.length
    };
  }

}

module.exports = SlackChannelStatus;<|endoftext|>


<commit_before>var Q = require('q');
var fs = require('fs');
var _ = require('lodash');
var Canvas = require('canvas');

var topics = require('./topic');
var colors = require('./colors.json');

function textsize(str, size, font) {
    // We only want the context to do our predictions
    var ctx = new Canvas().getContext('2d');

    // Set font
    ctx.font = size+"px "+font;

    // Get dimensions it would occupy
    var dim = ctx.measureText(str);

    return {
        width: dim.width,
        height: dim.emHeightAscent + dim.emHeightDescent,
    };
}

// Get the good font size for text to fit in a given width
function fontSizeForDimensions(str, font, width, height, lower, upper) {
    // Lower and upper bounds for font
    lower = (lower === undefined) ? 0 : lower;
    upper = (upper === undefined) ? 1000 : upper;

    // The font size we're guessing with
    var middle = Math.floor((upper + lower) / 2);

    // Get text dimensions
    var tsize = textsize(str, middle, font);

    if(middle === lower) {
        return middle;
    }

    return (
        // Are we above or below ?
        (tsize.width <= width && tsize.height <= height) ?
        // Go up
        fontSizeForDimensions(str, font, width, height, middle, upper) :
        // Go down
        fontSizeForDimensions(str, font, width, height, lower, middle)
    );
}

function drawBackground(ctx, options) {
    ctx.fillStyle = options.background.color;
    ctx.fillRect(0, 0, options.size.w, options.size.h);
}

function drawTitle(ctx, options) {
    // Continuous top offset
    var offset = Math.floor(options.size.h * 0.20);

    // Max width that text can take
    var maxWidth = Math.floor(options.size.w * 0.8);

    // Words of title
    var parts = options.title.split(/\s+/);

    // Height allocated to each part
    var partHeight = Math.min(
        Math.floor((options.size.h * 0.6) / parts.length),
        Math.floor(options.size.h * 0.1)
    );

    var lines = parts
    .reduce(function(lines, part) {
        // First part
        if(lines.length === 0) {
            return [part];
        }

        // Last part
        var prevPart = lines[lines.length - 1];
        // Current part appended to last part
        var newPart = prevPart + ' ' + part;

        // Size of previous part by itself
        var fsize = fontSizeForDimensions(
            prevPart,
            font, maxWidth, partHeight
        );

        // How big is it if we add our new part ?
        var fsize2 = fontSizeForDimensions(
            newPart,
            font, maxWidth, partHeight
        );

        // If sizes are the same, then merge parts to same line
        if(fsize == fsize2) {
            lines[lines.length - 1] = newPart;
            return lines;
        }

        return lines.concat(part);
    }, []);

    // Font
    var font = options.font.family;

    lines.forEach(function(part) {
        // Font size
        var fsize = fontSizeForDimensions(
            part, font, maxWidth, partHeight
        );

        // Text dimensions (width & height)
        var tdim = textsize(part, fsize, font);

        // Draw text
        ctx.fillStyle = options.font.color;
        ctx.font = fsize+"px "+font;
        ctx.fillText(
            // Part of title
            part,
            // Left Margin (center text)
            Math.floor(options.size.w/2 - tdim.width/2),
            // Top Margin
            offset
        );

        // Increase offset
        offset += tdim.height;
    });
}

function drawAuthor(ctx, options) {
    var fasize = fontSizeForDimensions(
        options.author,
        options.font.family,

        // Cover width with some margin
        Math.floor(options.size.w * 0.8) / 4,
        100
    );

    // Author
    ctx.fillStyle = options.font.color;
    ctx.font = fasize+"px "+options.font.family;
    ctx.fillText(
        // Title
        options.author,
        // Left Margin
        Math.floor(options.size.w * 0.1),
        // Top Margin
        options.size.h * 0.9
    );
}

function drawPublished(ctx, options) {
    var w = options.size.w;
    var h = options.size.h;

    // Get image
    var pngData = fs.readFileSync(__dirname + '/published-with-gitbook.png');
    img = new Canvas.Image();
    img.src = pngData;

    var imgH = Math.floor(h * 0.15);
    var imgW = Math.floor(img.width * (imgH / img.height));

    ctx.drawImage(
        img,
        // Offset x
        w - imgW * 1.1,
        // Offset y
        h - imgH * 1.2,
        // Width
        imgW,
        // Height
        imgH
    );
}

function drawColor(ctx, options) {
    var _topics = topics(options.title);
    var topic = _topics[0];

    var color = (topic && colors[topic]) ? colors[topic] : colors.default;

    var hx = options.size.w / 2;
    var hy = options.size.h * 0.7;

    var x = 900;
    var y = 200;

    ctx.fillStyle = color;
    ctx.fillRect(hx-x/2, hy-y/2, x, y);
}

module.exports = function(output, options) {
    var d = Q.defer();

    // Default options
    options = _.defaults(options || {}, {
        "title": "",
        "author": "",
        "font": {
            "size": null,
            "family": "Arial",
            "color": '#424242'
        },
        "size": {
            "w": 1800,
            "h": 2360
        },
        "background": {
            "color": '#fff'
        }
    });

    // Setup canvas & context
    var canvas = new Canvas(options.size.w, options.size.h);
    var ctx = canvas.getContext('2d');

    // Background
    drawBackground(ctx, options);

    // Title
    drawTitle(ctx, options);

    // Author
    drawAuthor(ctx, options);

    // Published with GitBook
    drawPublished(ctx, options);

    // Draw the color (based on the detected topic)
    //drawColor(ctx, options);

    // Create streams
    var out = fs.createWriteStream(output);
    var stream = canvas.jpegStream();

    // Pipe
    stream.pipe(out);

    // Wait till finished piping/writing
    stream.on('end', d.resolve);

    return d.promise;
};
<commit_msg>Fix draw return, return only when output is written to disk<commit_after>var Q = require('q');
var fs = require('fs');
var _ = require('lodash');
var Canvas = require('canvas');

var topics = require('./topic');
var colors = require('./colors.json');

function textsize(str, size, font) {
    // We only want the context to do our predictions
    var ctx = new Canvas().getContext('2d');

    // Set font
    ctx.font = size+"px "+font;

    // Get dimensions it would occupy
    var dim = ctx.measureText(str);

    return {
        width: dim.width,
        height: dim.emHeightAscent + dim.emHeightDescent,
    };
}

// Get the good font size for text to fit in a given width
function fontSizeForDimensions(str, font, width, height, lower, upper) {
    // Lower and upper bounds for font
    lower = (lower === undefined) ? 0 : lower;
    upper = (upper === undefined) ? 1000 : upper;

    // The font size we're guessing with
    var middle = Math.floor((upper + lower) / 2);

    // Get text dimensions
    var tsize = textsize(str, middle, font);

    if(middle === lower) {
        return middle;
    }

    return (
        // Are we above or below ?
        (tsize.width <= width && tsize.height <= height) ?
        // Go up
        fontSizeForDimensions(str, font, width, height, middle, upper) :
        // Go down
        fontSizeForDimensions(str, font, width, height, lower, middle)
    );
}

function drawBackground(ctx, options) {
    ctx.fillStyle = options.background.color;
    ctx.fillRect(0, 0, options.size.w, options.size.h);
}

function drawTitle(ctx, options) {
    // Continuous top offset
    var offset = Math.floor(options.size.h * 0.20);

    // Max width that text can take
    var maxWidth = Math.floor(options.size.w * 0.8);

    // Words of title
    var parts = options.title.split(/\s+/);

    // Height allocated to each part
    var partHeight = Math.min(
        Math.floor((options.size.h * 0.6) / parts.length),
        Math.floor(options.size.h * 0.1)
    );

    var lines = parts
    .reduce(function(lines, part) {
        // First part
        if(lines.length === 0) {
            return [part];
        }

        // Last part
        var prevPart = lines[lines.length - 1];
        // Current part appended to last part
        var newPart = prevPart + ' ' + part;

        // Size of previous part by itself
        var fsize = fontSizeForDimensions(
            prevPart,
            font, maxWidth, partHeight
        );

        // How big is it if we add our new part ?
        var fsize2 = fontSizeForDimensions(
            newPart,
            font, maxWidth, partHeight
        );

        // If sizes are the same, then merge parts to same line
        if(fsize == fsize2) {
            lines[lines.length - 1] = newPart;
            return lines;
        }

        return lines.concat(part);
    }, []);

    // Font
    var font = options.font.family;

    lines.forEach(function(part) {
        // Font size
        var fsize = fontSizeForDimensions(
            part, font, maxWidth, partHeight
        );

        // Text dimensions (width & height)
        var tdim = textsize(part, fsize, font);

        // Draw text
        ctx.fillStyle = options.font.color;
        ctx.font = fsize+"px "+font;
        ctx.fillText(
            // Part of title
            part,
            // Left Margin (center text)
            Math.floor(options.size.w/2 - tdim.width/2),
            // Top Margin
            offset
        );

        // Increase offset
        offset += tdim.height;
    });
}

function drawAuthor(ctx, options) {
    var fasize = fontSizeForDimensions(
        options.author,
        options.font.family,

        // Cover width with some margin
        Math.floor(options.size.w * 0.8) / 4,
        100
    );

    // Author
    ctx.fillStyle = options.font.color;
    ctx.font = fasize+"px "+options.font.family;
    ctx.fillText(
        // Title
        options.author,
        // Left Margin
        Math.floor(options.size.w * 0.1),
        // Top Margin
        options.size.h * 0.9
    );
}

function drawPublished(ctx, options) {
    var w = options.size.w;
    var h = options.size.h;

    // Get image
    var pngData = fs.readFileSync(__dirname + '/published-with-gitbook.png');
    img = new Canvas.Image();
    img.src = pngData;

    var imgH = Math.floor(h * 0.15);
    var imgW = Math.floor(img.width * (imgH / img.height));

    ctx.drawImage(
        img,
        // Offset x
        w - imgW * 1.1,
        // Offset y
        h - imgH * 1.2,
        // Width
        imgW,
        // Height
        imgH
    );
}

function drawColor(ctx, options) {
    var _topics = topics(options.title);
    var topic = _topics[0];

    var color = (topic && colors[topic]) ? colors[topic] : colors.default;

    var hx = options.size.w / 2;
    var hy = options.size.h * 0.7;

    var x = 900;
    var y = 200;

    ctx.fillStyle = color;
    ctx.fillRect(hx-x/2, hy-y/2, x, y);
}

module.exports = function(output, options) {
    var d = Q.defer();

    // Default options
    options = _.defaults(options || {}, {
        "title": "",
        "author": "",
        "font": {
            "size": null,
            "family": "Arial",
            "color": '#424242'
        },
        "size": {
            "w": 1800,
            "h": 2360
        },
        "background": {
            "color": '#fff'
        }
    });

    // Setup canvas & context
    var canvas = new Canvas(options.size.w, options.size.h);
    var ctx = canvas.getContext('2d');

    // Background
    drawBackground(ctx, options);

    // Title
    drawTitle(ctx, options);

    // Author
    drawAuthor(ctx, options);

    // Published with GitBook
    drawPublished(ctx, options);

    // Draw the color (based on the detected topic)
    //drawColor(ctx, options);

    // Create streams
    var out = fs.createWriteStream(output);
    var stream = canvas.jpegStream();

    // Pipe
    stream.pipe(out);

    // Wait till finished piping/writing
    out.on('close', d.resolve);
    out.on('error', d.reject);

    return d.promise;
};
<|endoftext|>


<commit_before>main();

function main () {
    var node   = document.getElementById('warp');
    var app    = Elm.Warp.embed(node);

    app.ports.warpChange.subscribe(function (data) {
        draw(data[0], data[1]);
    });

    var canvas = document.getElementById("canvas");
    var ctx    = canvas.getContext("2d");

    function draw ( warp, colors ) {
        console.log("WARP: ", warp);
        console.log("COLORS: ", colors);

        var threading   = warp.threading;
        var tieup       = warp.tieup;
        var treadling   = warp.treadling;
        var threads     = warp.warpColors;
        var weftthreads = warp.weftColors;

        var threadWidth;
        var warpWidth =
            canvas
            .parentElement
            .getBoundingClientRect()
            .width;

        if ( threads.length != 0 ) {
            threadWidth = Math.floor(warpWidth/threads.length);
            warpWidth   = threadWidth * threads.length;
        }

        canvas.width = warpWidth;

        ctx.clearRect(0, 0, canvas.width, canvas.height);

        for ( var j = 0 ; j < treadling.length ; j++ ) {
            var wOffset = j * threadWidth;

	    for ( var i = 0 ; i < threads.length ; i++ ) {
	        var offset = i * threadWidth;

                var shaft = threading[i];
                var shafts = tieup[treadling[j] - 1];

                if (contains( shaft, shafts ))
                    "#000000"; //BOOG ctx.fillStyle = colors[ weftthreads[j] ].hex;
                else
                    ctx.fillStyle = colors[ threads[ i ] ].hex;

	        ctx.fillRect( offset, wOffset, threadWidth, threadWidth );
	    }
        }
    }

    function contains ( value, list ) {

        for ( var i = 0 ; i < list.length ; i++ )
            if ( value === list[i] )
                return true;

        return false;
    }
}
<commit_msg>remove debug<commit_after>main();

function main () {
    var node   = document.getElementById('warp');
    var app    = Elm.Warp.embed(node);

    app.ports.warpChange.subscribe(function (data) {
        draw(data[0], data[1]);
    });

    var canvas = document.getElementById("canvas");
    var ctx    = canvas.getContext("2d");

    function draw ( warp, colors ) {

        var threading   = warp.threading;
        var tieup       = warp.tieup;
        var treadling   = warp.treadling;
        var threads     = warp.warpColors;
        var weftthreads = warp.weftColors;

        var threadWidth;
        var warpWidth =
            canvas
            .parentElement
            .getBoundingClientRect()
            .width;

        if ( threads.length != 0 ) {
            threadWidth = Math.floor(warpWidth/threads.length);
            warpWidth   = threadWidth * threads.length;
        }

        canvas.width = warpWidth;

        ctx.clearRect(0, 0, canvas.width, canvas.height);

        for ( var j = 0 ; j < treadling.length ; j++ ) {
            var wOffset = j * threadWidth;

	    for ( var i = 0 ; i < threads.length ; i++ ) {
	        var offset = i * threadWidth;

                var shaft = threading[i];
                var shafts = tieup[treadling[j] - 1];

                if (contains( shaft, shafts ))
                    "#000000"; //BOOG ctx.fillStyle = colors[ weftthreads[j] ].hex;
                else
                    ctx.fillStyle = colors[ threads[ i ] ].hex;

	        ctx.fillRect( offset, wOffset, threadWidth, threadWidth );
	    }
        }
    }

    function contains ( value, list ) {

        for ( var i = 0 ; i < list.length ; i++ )
            if ( value === list[i] )
                return true;

        return false;
    }
}
<|endoftext|>


<commit_before>"use strict"

var cluster = require('cluster');

if (cluster.isMaster) {

	// cluster.fork()
	// cluster.fork()
	// cluster.fork()
	// cluster.fork()

	// cluster.on('disconnect', function(worker, code, signal) {

	// 	if (Object.keys(cluster.workers).length === 1){
	// 		var mmsIngestPrune = require("../lib/mss_ingest_prune.js")
	// 		console.log("Pruning collections w/ out captures")
	// 		mmsIngestPrune.pruneCollectionsWithoutCaptures(function(err,results){
	// 			console.log("Pruning containers w/ out captures")
	// 			mmsIngestPrune.pruneContainersWithoutCaptures(function(err,results){
	// 				process.exit()
	// 			})
	// 		})
	// 	}

	// });

	var mmsMappingStrategies = require("../lib/mms_mapping_strategies.js")

	// console.log("mapItemsToTmsObjectsByIdentifiers")
	// mmsMappingStrategies.mapItemsToTmsObjectsByIdentifiers(function(err,results){

	// 	mmsMappingStrategies.mapItemsToTmsObjectsByImageId(function(err,results){

	// 	})

	// })

	// mmsMappingStrategies.mapMmsPortraitFileToTms(function(err,results){

	// })
	//LAYER CAAAKE
	mmsMappingStrategies.mapMmsPortraitFileToTmsFuzzy(0.8,function(err,results){

		mmsMappingStrategies.mapMmsPortraitFileToTmsFuzzy(0.7,function(err,results){

			mmsMappingStrategies.mapMmsPortraitFileToTmsFuzzy(0.6,function(err,results){

			})

		})

	})

} else {

	if (cluster.worker.id == 1){

		var mmsCollectionIngest = require("../lib/mss_ingest_collections.js")
		mmsCollectionIngest.ingest(function(err,results){
			console.log("Ingesting collections done")
			cluster.worker.disconnect()
		})

	}else if (cluster.worker.id == 2){

		var mmsContainerIngest = require("../lib/mss_ingest_containers.js")
		mmsContainerIngest.ingest(function(err,results){
			console.log("Ingesting containers done")
			cluster.worker.disconnect()
		})

	}else if (cluster.worker.id == 3){

		var mmsItemsIngest = require("../lib/mss_ingest_items.js")
		mmsItemsIngest.ingest(function(err,results){
			console.log("Ingesting items done")
			cluster.worker.disconnect()
		})

	}else if (cluster.worker.id == 4){

		var mmsCapturesIngest = require("../lib/mss_ingest_captures.js")
		mmsCapturesIngest.ingest(function(err,results){
			console.log("Ingesting captures done")
			cluster.worker.disconnect()
		})

	}

}
<commit_msg>tms map<commit_after>"use strict"

var cluster = require('cluster');

if (cluster.isMaster) {

	// cluster.fork()
	// cluster.fork()
	// cluster.fork()
	// cluster.fork()

	// cluster.on('disconnect', function(worker, code, signal) {

	// 	if (Object.keys(cluster.workers).length === 1){
	// 		var mmsIngestPrune = require("../lib/mss_ingest_prune.js")
	// 		console.log("Pruning collections w/ out captures")
	// 		mmsIngestPrune.pruneCollectionsWithoutCaptures(function(err,results){
	// 			console.log("Pruning containers w/ out captures")
	// 			mmsIngestPrune.pruneContainersWithoutCaptures(function(err,results){
	// 				process.exit()
	// 			})
	// 		})
	// 	}

	// });

	var mmsMappingStrategies = require("../lib/mms_mapping_strategies.js")

	// console.log("mapItemsToTmsObjectsByIdentifiers")
	mmsMappingStrategies.mapItemsToTmsObjectsByIdentifiers(function(err,results){

		mmsMappingStrategies.mapItemsToTmsObjectsByImageId(function(err,results){

			//LAYER CAAAKE
			mmsMappingStrategies.mapMmsPortraitFileToTmsFuzzy(0.8,function(err,results){

				mmsMappingStrategies.mapMmsPortraitFileToTmsFuzzy(0.7,function(err,results){

					mmsMappingStrategies.mapMmsPortraitFileToTmsFuzzy(0.6,function(err,results){

					})

				})

			})

		})

	})

} else {

	if (cluster.worker.id == 1){

		var mmsCollectionIngest = require("../lib/mss_ingest_collections.js")
		mmsCollectionIngest.ingest(function(err,results){
			console.log("Ingesting collections done")
			cluster.worker.disconnect()
		})

	}else if (cluster.worker.id == 2){

		var mmsContainerIngest = require("../lib/mss_ingest_containers.js")
		mmsContainerIngest.ingest(function(err,results){
			console.log("Ingesting containers done")
			cluster.worker.disconnect()
		})

	}else if (cluster.worker.id == 3){

		var mmsItemsIngest = require("../lib/mss_ingest_items.js")
		mmsItemsIngest.ingest(function(err,results){
			console.log("Ingesting items done")
			cluster.worker.disconnect()
		})

	}else if (cluster.worker.id == 4){

		var mmsCapturesIngest = require("../lib/mss_ingest_captures.js")
		mmsCapturesIngest.ingest(function(err,results){
			console.log("Ingesting captures done")
			cluster.worker.disconnect()
		})

	}

}
<|endoftext|>


<commit_before>module.exports = function(test) {
    test('Collection instantiation', function(t) {
        t.plan(1)
        t.ok('ok')
        t.end()
    })
}<commit_msg>Collection tests.<commit_after>var Collection = require('../collection')
var Model = require('../model')

module.exports = function(test) {
    test('Collection utilities', function(t) {
        t.plan(3)

        var c = new Collection([{ id: 1 }, { id: 2 }, { id: 3 }, { id: 4 }])
        var second = c.get(2)
        var third = c.get(3)
        t.notEqual(c.models, c.all(), 'Return of .all() is referentially different to .models')
        t.equal(c.before(third), second, 'Before model')
        t.equal(c.after(second), third, 'After model')

        t.end()
    })
}<|endoftext|>


<commit_before>module('lively.morphic.ColorChooserDraft').requires('lively.morphic.Core', 'lively.morphic.TextCore', 'lively.CrayonColors').toRun(function() {

lively.morphic.Box.subclass('lively.morphic.ColorChooser',
'settings', {
    defaultBounds: new Rectangle(0,0, 160, 120),
},
'initializing', {
    initialize: function($super, bounds) {
        $super(bounds || this.defaultBounds);
        this.buildColorMap();
        // this.ignoreEvents();
    },
    buildColorMap: function() {
        throw new Error('subclass responsibility')
    },
},
'color mapping', {
    colorForPos: function(pos) {
        throw new Error('subclass responsibility');
    },
});
lively.morphic.ColorChooser.subclass('lively.morphic.RGBColorChooser',
'settings', {
    colorNames: 'rgb',
},
'initializing', {
    buildColorMap: function() {
        // copied from lively.Widgets ColorPicker
        // Slow -- should be cached as a bitmap and invalidated by layoutChanged
        // Try caching wheel as an interim measure
        var r = this.shape.getBounds().insetBy(this.getBorderWidth());
        var rh2 = r.height/2;
        var dd = 5; // grain for less resolution in output (input is still full resolution)

        //DI: This could be done with width*2 gradients, instead of width*height simple fills
        for (var x = 0; x < r.width; x += dd) {
            for (var y = 0; y < r.height; y += dd) { // lightest down to neutral
                var element = new lively.morphic.Morph.makeRectangle(new Rectangle(x + r.x, y + r.y, dd, dd));
                element.applyStyle({
                    fill: this.colorMap(x, y, rh2, this.colorWheel(r.width + 1)),
                    borderWidth: 0
                });
                element.ignoreEvents();
                this.addMorph(element);
            }
        }
    },
},
'color mapping', {
colorForPos: function(pos) {
         var r = this.shape.getBounds().insetBy(this.getBorderWidth()),
            pos = r.closestPointToPt(pos),
            rh2 = r.height/2;
        var color =  this.colorMap(pos.x, pos.y, rh2, this.colorWheel(r.width+1));
        this.ensureLabel().setTextString("color:" + color)
        return color
    },
  ensureLabel: function() {
       if (!this.label) {
            this.label = new lively.morphic.Text(new Rectangle(0,0,160,20), "rbg", {fill: Color.white});
            this.addMorph(this.label);
            this.label.setPosition(pt(0,120));
       }
        return this.label
    },

    colorWheel: function(n) {
        if (this.colorWheelCache && this.colorWheelCache.length == n)
            return this.colorWheelCache;
        // the start of the color range should be just white for grayscale
        var whiteAmount = 5,
            whites = Array.range(1,whiteAmount).collect(function() {return Color.white})
        return this.colorWheelCache = whites.concat(Color.wheelHsb(Math.round(n-whiteAmount),338,1,1));
    },

    colorMap: function(x,y,rh2,wheel) {
        var columnHue = wheel[Math.round(x)];
        return y <= rh2 ?
            columnHue.mixedWith(Color.white, y/rh2) : // lightest down to neutral
            Color.black.mixedWith(columnHue, (y - rh2)/rh2);  // neutral down to darkest
    },
});

lively.morphic.ColorChooser.subclass('lively.morphic.CrayonColorChooser',
'settings', {
    colorNames: 'crayons',
},
'initializing', {
    buildColorMap: function() {
        var colorNames = CrayonColors.colorNames(),
            x = 8, y = 6, // like MacOS colors
            extent = this.innerBounds().extent().scaleByPt(pt(1/x, 1/y));
        for (var j = 0; j < y; j++) {
            for (var i = 0; i < x; i++) {
                var idx = j*x+i, // running offset j*x^1 + i*y^0
                    color = CrayonColors[colorNames[idx]],
                    r = extent.scaleByPt(pt(i, j)).extent(extent);
                    morph = new lively.morphic.Box(r);
                morph.applyStyle({fill: color, borderWidth: 0});
                morph.ignoreEvents();
                this.addMorph(morph);
            }
        }
    },
},
'color mapping', {
    colorForPos: function(pos) {
        var r = this.shape.getBounds().insetBy(this.getBorderWidth()),
            pos = r.closestPointToPt(pos),
            m = this.submorphs.detect(function(ea) { return ea.bounds().containsPoint(pos) });
        return m ? m.getFill() : Color.black;
    },
});
lively.morphic.ColorChooser.subclass('lively.morphic.CustomColorChooser',
'settings', {
    colorNames: 'custom',
},
'initializing', {
    initialize: function($super,bounds, colors){
        // under constructions...
        if (!colors) {
            colors = this.gatherCustomColors();
        }
        this.colors = colors;
        $super(bounds);
    },
    gatherCustomColors: function() {
        // lively.morphic.CustomColorChooser.prototype.gatherCustomColors()
        var colors = [];
        var gatherColor = function(eaColor) {
            if (eaColor && !colors.detect(function(colorSetEa) {
                return colorSetEa.equals(eaColor)}))
                colors.push(eaColor)
        }
        $world.withAllSubmorphsDo(function(ea) {
            gatherColor(ea.getBorderColor());
        })
        return colors
    },

    buildColorMap: function() {
        var x = Math.floor(Math.sqrt(this.colors.length)) + 1,
            y = x,
            extent = this.innerBounds().extent().scaleByPt(pt(1/x, 1/y));
        for (var j = 0; j < y; j++) {
            for (var i = 0; i < x; i++) {
                var idx = j*x+i, // running offset j*x^1 + i*y^0
                    color = this.colors[idx],
                    r = extent.scaleByPt(pt(i, j)).extent(extent),
                    morph = new lively.morphic.Box(r);
                morph.applyStyle({fill: color, borderWidth: 0});
                morph.ignoreEvents();
                this.addMorph(morph);
            }
        }
    },
},
'color mapping', {
    colorForPos: function(pos) {
        var r = this.shape.getBounds().insetBy(this.getBorderWidth()),
            pos = r.closestPointToPt(pos),
            m = this.submorphs.detect(function(ea) { return ea.bounds().containsPoint(pos) });
        return m ? m.getFill() : Color.black;
    },
});
lively.morphic.Text.subclass('lively.morphic.ColorChooserSwitcher',
'documentation', {
    documentation: 'used for changing the color chooser of a color field',
},
'settings', {
    style: {fixedWidth: false, fixedHeight: false, fill: Color.white},
},
'initializing', {
    initialize: function($super, colorChooser) {
        this.colorChooser = colorChooser;
        $super(new Rectangle(0,0,10,10), colorChooser.colorNames);
        this.registerForEvent('mouseMove', this, 'onMouseMove');
    },
},
'mouse events', {
    onMouseMove: function(evt) {
        this.colorField.setCurrentColorSwitcher(this)
    },
});

lively.morphic.Box.subclass('lively.morphic.ColorField',
/* example:
new lively.morphic.ColorField().openInWorld(pt(100,100))
*/
'settings', {
    doNotSerialize: ['colorSwitchers', 'currentColorSwitcher'],
    style: {
        enableDragging: true,
        enableGrabbing: false,
        fill: Color.white,
        borderWidth: 1,
        borderColor: Color.black
    }
},
'initializing', {
    initialize: function($super, optBounds) {
        $super(optBounds || new Rectangle(0,0, 40, 30));
        // initialize laziliy loaded switchers so that those are there when clicked
        this.getColorSwitchers()
    },
},
'color choosers', {
    showColorChooserAndSwitchers: function(chooser) {
        this.world().addMorph(chooser);
        chooser.align(chooser.bounds().topLeft(), this.worldPoint(this.innerBounds().bottomLeft()));
        var x = chooser.bounds().right(), y = chooser.bounds().top();
        var switchers = this.getColorSwitchers();
        switchers.forEach(function(ea) {
            ea.colorField = this;
            this.world().addMorph(ea);
            ea.align(ea.bounds().bottomRight(), pt(x, y));
            x -= ea.getExtent().x;
        }, this)
    },

},
'accessing', {
    getColorSwitchers: function() {
        // so that they are created just once
        //  this.constructor.prototype.colorSwitchers = null
        if (!this.colorSwitchers)
            this.constructor.prototype.colorSwitchers = [
                new lively.morphic.ColorChooserSwitcher(new lively.morphic.CrayonColorChooser()),
                new lively.morphic.ColorChooserSwitcher(new lively.morphic.RGBColorChooser()),
                new lively.morphic.ColorChooserSwitcher(new lively.morphic.CustomColorChooser())
                ];
        return this.colorSwitchers;
    },
    getCurrentColorChooser: function() { return this.getCurrentColorSwitcher().colorChooser },
    getCurrentColorSwitcher: function() {
        if (!this.currentColorSwitcher)
            this.constructor.prototype.currentColorSwitcher = this.getColorSwitchers()[0];
        return this.currentColorSwitcher;
    },
    setCurrentColorSwitcher: function(switcher) {
        this.constructor.prototype.currentColorSwitcher = switcher;
        this.showColorChooserAndSwitchers(switcher.colorChooser);
    },

},
'mouse events', {
    correctForDragOffset: Functions.False,

    onMouseDown: function($super, evt) {
        if (!evt.isCommandKey() && evt.isLeftMouseButtonDown()) {
            this.showColorChooserAndSwitchers(this.getCurrentColorChooser());
            return true;
        }
        return $super(evt);
    },

    onMouseUp: function($super, evt) {
        if ($super(evt)) return true;
        this. removHelperMorphs()
        return true;
    },

    onDrag: function(evt) {
        var cc = this.getCurrentColorChooser(),
            color = cc.colorForPos(cc.localize(evt.getPosition()));
        this.setFill(color);
        this.color = color;
        return true;
    },

    onDragEnd: function(evt) {
        this.removHelperMorphs();
        return true;
    },

    removHelperMorphs: function() {
        this.getColorSwitchers().forEach(function(ea) {
            ea.remove()
            ea.colorChooser.remove()
        })
    },
});
}) // end of moduleeee<commit_msg>from ww: lively.morphic.RGBColorChooser fix<commit_after>module('lively.morphic.ColorChooserDraft').requires('lively.morphic.Core', 'lively.morphic.TextCore', 'lively.CrayonColors').toRun(function() {

lively.morphic.Box.subclass('lively.morphic.ColorChooser',
'settings', {
    defaultBounds: new Rectangle(0,0, 160, 120),
},
'initializing', {
    initialize: function($super, bounds) {
        $super(bounds || this.defaultBounds);
        this.buildColorMap();
        // this.ignoreEvents();
    },
    buildColorMap: function() {
        throw new Error('subclass responsibility')
    },
},
'color mapping', {
    colorForPos: function(pos) {
        throw new Error('subclass responsibility');
    },
});
lively.morphic.ColorChooser.subclass('lively.morphic.RGBColorChooser',
'settings', {
    colorNames: 'rgb',
    hasLabel: true,
},
'initializing', {
    buildColorMap: function() {
        // copied from lively.Widgets ColorPicker
        // Slow -- should be cached as a bitmap and invalidated by layoutChanged
        // Try caching wheel as an interim measure
        var r = this.shape.getBounds().insetBy(this.getBorderWidth());
        var rh2 = r.height/2;
        var dd = 5; // grain for less resolution in output (input is still full resolution)

        //DI: This could be done with width*2 gradients, instead of width*height simple fills
        for (var x = 0; x < r.width; x += dd) {
            for (var y = 0; y < r.height; y += dd) { // lightest down to neutral
                var element = new lively.morphic.Morph.makeRectangle(new Rectangle(x + r.x, y + r.y, dd, dd));
                element.applyStyle({
                    fill: this.colorMap(x, y, rh2, this.colorWheel(r.width + 1)),
                    borderWidth: 0
                });
                element.ignoreEvents();
                this.addMorph(element);
            }
        }
    },
},
'color mapping', {
colorForPos: function(pos) {
         var r = this.shape.getBounds().insetBy(this.getBorderWidth()),
            pos = r.closestPointToPt(pos),
            rh2 = r.height/2;
        var color =  this.colorMap(pos.x, pos.y, rh2, this.colorWheel(r.width+1));
        this.hasLabel && this.ensureLabel().setTextString("color:" + color);
        return color;
    },
  ensureLabel: function() {
       if (!this.label) {
            this.label = new lively.morphic.Text(new Rectangle(0,0,160,20), "rbg", {fill: Color.white});
            this.addMorph(this.label);
            this.label.setPosition(pt(0,120));
       }
        return this.label
    },

    colorWheel: function(n) {
        if (this.colorWheelCache && this.colorWheelCache.length == n)
            return this.colorWheelCache;
        // the start of the color range should be just white for grayscale
        var whiteAmount = 5,
            whites = Array.range(1,whiteAmount).collect(function() {return Color.white})
        return this.colorWheelCache = whites.concat(Color.wheelHsb(Math.round(n-whiteAmount),338,1,1));
    },

    colorMap: function(x,y,rh2,wheel) {
        var columnHue = wheel[Math.round(x)];
        return y <= rh2 ?
            columnHue.mixedWith(Color.white, y/rh2) : // lightest down to neutral
            Color.black.mixedWith(columnHue, (y - rh2)/rh2);  // neutral down to darkest
    },
});

lively.morphic.ColorChooser.subclass('lively.morphic.CrayonColorChooser',
'settings', {
    colorNames: 'crayons',
},
'initializing', {
    buildColorMap: function() {
        var colorNames = CrayonColors.colorNames(),
            x = 8, y = 6, // like MacOS colors
            extent = this.innerBounds().extent().scaleByPt(pt(1/x, 1/y));
        for (var j = 0; j < y; j++) {
            for (var i = 0; i < x; i++) {
                var idx = j*x+i, // running offset j*x^1 + i*y^0
                    color = CrayonColors[colorNames[idx]],
                    r = extent.scaleByPt(pt(i, j)).extent(extent);
                    morph = new lively.morphic.Box(r);
                morph.applyStyle({fill: color, borderWidth: 0});
                morph.ignoreEvents();
                this.addMorph(morph);
            }
        }
    },
},
'color mapping', {
    colorForPos: function(pos) {
        var r = this.shape.getBounds().insetBy(this.getBorderWidth()),
            pos = r.closestPointToPt(pos),
            m = this.submorphs.detect(function(ea) { return ea.bounds().containsPoint(pos) });
        return m ? m.getFill() : Color.black;
    },
});
lively.morphic.ColorChooser.subclass('lively.morphic.CustomColorChooser',
'settings', {
    colorNames: 'custom',
},
'initializing', {
    initialize: function($super,bounds, colors){
        // under constructions...
        if (!colors) {
            colors = this.gatherCustomColors();
        }
        this.colors = colors;
        $super(bounds);
    },
    gatherCustomColors: function() {
        // lively.morphic.CustomColorChooser.prototype.gatherCustomColors()
        var colors = [];
        var gatherColor = function(eaColor) {
            if (eaColor && !colors.detect(function(colorSetEa) {
                return colorSetEa.equals(eaColor)}))
                colors.push(eaColor)
        }
        $world.withAllSubmorphsDo(function(ea) {
            gatherColor(ea.getBorderColor());
        })
        return colors
    },

    buildColorMap: function() {
        var x = Math.floor(Math.sqrt(this.colors.length)) + 1,
            y = x,
            extent = this.innerBounds().extent().scaleByPt(pt(1/x, 1/y));
        for (var j = 0; j < y; j++) {
            for (var i = 0; i < x; i++) {
                var idx = j*x+i, // running offset j*x^1 + i*y^0
                    color = this.colors[idx],
                    r = extent.scaleByPt(pt(i, j)).extent(extent),
                    morph = new lively.morphic.Box(r);
                morph.applyStyle({fill: color, borderWidth: 0});
                morph.ignoreEvents();
                this.addMorph(morph);
            }
        }
    },
},
'color mapping', {
    colorForPos: function(pos) {
        var r = this.shape.getBounds().insetBy(this.getBorderWidth()),
            pos = r.closestPointToPt(pos),
            m = this.submorphs.detect(function(ea) { return ea.bounds().containsPoint(pos) });
        return m ? m.getFill() : Color.black;
    },
});
lively.morphic.Text.subclass('lively.morphic.ColorChooserSwitcher',
'documentation', {
    documentation: 'used for changing the color chooser of a color field',
},
'settings', {
    style: {fixedWidth: false, fixedHeight: false, fill: Color.white},
},
'initializing', {
    initialize: function($super, colorChooser) {
        this.colorChooser = colorChooser;
        $super(new Rectangle(0,0,10,10), colorChooser.colorNames);
        this.registerForEvent('mouseMove', this, 'onMouseMove');
    },
},
'mouse events', {
    onMouseMove: function(evt) {
        this.colorField.setCurrentColorSwitcher(this)
    },
});

lively.morphic.Box.subclass('lively.morphic.ColorField',
/* example:
new lively.morphic.ColorField().openInWorld(pt(100,100))
*/
'settings', {
    doNotSerialize: ['colorSwitchers', 'currentColorSwitcher'],
    style: {
        enableDragging: true,
        enableGrabbing: false,
        fill: Color.white,
        borderWidth: 1,
        borderColor: Color.black
    }
},
'initializing', {
    initialize: function($super, optBounds) {
        $super(optBounds || new Rectangle(0,0, 40, 30));
        // initialize laziliy loaded switchers so that those are there when clicked
        this.getColorSwitchers()
    },
},
'color choosers', {
    showColorChooserAndSwitchers: function(chooser) {
        this.world().addMorph(chooser);
        chooser.align(chooser.bounds().topLeft(), this.worldPoint(this.innerBounds().bottomLeft()));
        var x = chooser.bounds().right(), y = chooser.bounds().top();
        var switchers = this.getColorSwitchers();
        switchers.forEach(function(ea) {
            ea.colorField = this;
            this.world().addMorph(ea);
            ea.align(ea.bounds().bottomRight(), pt(x, y));
            x -= ea.getExtent().x;
        }, this)
    },

},
'accessing', {
    getColorSwitchers: function() {
        // so that they are created just once
        //  this.constructor.prototype.colorSwitchers = null
        if (!this.colorSwitchers)
            this.constructor.prototype.colorSwitchers = [
                new lively.morphic.ColorChooserSwitcher(new lively.morphic.CrayonColorChooser()),
                new lively.morphic.ColorChooserSwitcher(new lively.morphic.RGBColorChooser()),
                new lively.morphic.ColorChooserSwitcher(new lively.morphic.CustomColorChooser())
                ];
        return this.colorSwitchers;
    },
    getCurrentColorChooser: function() { return this.getCurrentColorSwitcher().colorChooser },
    getCurrentColorSwitcher: function() {
        if (!this.currentColorSwitcher)
            this.constructor.prototype.currentColorSwitcher = this.getColorSwitchers()[0];
        return this.currentColorSwitcher;
    },
    setCurrentColorSwitcher: function(switcher) {
        this.constructor.prototype.currentColorSwitcher = switcher;
        this.showColorChooserAndSwitchers(switcher.colorChooser);
    },

},
'mouse events', {
    correctForDragOffset: Functions.False,

    onMouseDown: function($super, evt) {
        if (!evt.isCommandKey() && evt.isLeftMouseButtonDown()) {
            this.showColorChooserAndSwitchers(this.getCurrentColorChooser());
            return true;
        }
        return $super(evt);
    },

    onMouseUp: function($super, evt) {
        if ($super(evt)) return true;
        this. removHelperMorphs()
        return true;
    },

    onDrag: function(evt) {
        var cc = this.getCurrentColorChooser(),
            color = cc.colorForPos(cc.localize(evt.getPosition()));
        this.setFill(color);
        this.color = color;
        return true;
    },

    onDragEnd: function(evt) {
        this.removHelperMorphs();
        return true;
    },

    removHelperMorphs: function() {
        this.getColorSwitchers().forEach(function(ea) {
            ea.remove()
            ea.colorChooser.remove()
        })
    },
});

lively.morphic.Button.subclass('lively.morphic.SimpleColorField',
'init', {
    defaultBounds: new Rectangle(0,0,24,24),
    defaultColor: Color.red,
    colorDisplayOffset: 4,
    colorDisplayBorderRadius: 3,

    initialize: function($super, bounds){
        var b = bounds || this.defaultBounds;
        $super(b, '');
        this.colorDisplay = new lively.morphic.Box(b.insetBy(this.colorDisplayOffset));
        this.removeAllMorphs(); // get rid of the default Text
        this.addMorph(this.colorDisplay);
        this.colorDisplay.disableHalos();
        this.setColor(this.defaultColor);
        this.colorDisplay.applyStyle({borderRadius: this.colorDisplayBorderRadius, resizeWidth: true, resizeHeight: true});
        this.applyStyle({adjustForNewBounds: true});
    },
    setValue: function(bool) {
        this.value = bool;
        // buttons should fire on mouse up
        if (!bool) {
            var chooser = new lively.morphic.RGBColorChooser();
            var menu = new lively.morphic.SimpleColorMenu(chooser);
            var pos = this.getPosition();
            var menuPos = pos.addPt(pt(0, this.bounds().height));
            menu.open(lively.morphic.World.current(), menuPos, false);
            menu.setCallback(this, 'setColor');
        }
    },
    setColor: function(color){
        console.log('Change color to '+color.toString());
         this.colorDisplay.setFill(color);
    }

}

);

lively.morphic.Box.subclass('lively.morphic.SimpleColorMenu',
'settings', {
    style: {
        fill: Color.gray.lighter(3),
        borderColor: Color.gray,
        borderWidth: 1,
        borderStyle: 'outset',
        borderRadius: 4,
    },
    chooserOffset: 4,
    isEpiMorph: true,
},
'init', {
    initialize: function($super, chooser) {
        this.colorChooser = chooser || new lively.morphic.RGBColorChooser();
        this.colorChooser.hasLabel = false;
        var b = this.colorChooser.getBounds();
        $super(new Rectangle(0,0, b.width + this.chooserOffset*2 , b.height+ this.chooserOffset*2));

    },

    setCallback: function(target, callback){
        if (this.colorChooser) connect(this.colorChooser, 'currentlySelectedColor', target, callback);
    },

    open: function(parentMorph, pos, remainOnScreen, callbackTarget, callbackFunc) {
        this.setPosition(pos || pt(0,0));
        var owner = parentMorph || lively.morphic.World.current();
        this.remainOnScreen = remainOnScreen;
        if (!remainOnScreen) {
            if (owner.currentMenu) { owner.currentMenu.remove() };
            owner.currentMenu = this;
        } else {
            this.isEpiMorph = false;
        }

        owner.addMorph(this);

        this.offsetForWorld(pos);

        this.addMorph(this.colorChooser);
        this.colorChooser.setPosition(pt(this.chooserOffset,this.chooserOffset));
        this.colorChooser.disableGrabbing();
        this.colorChooser.disableDragging();
        this.colorChooser.onMouseUp = function(evt) {
              this.currentlySelectedColor = this.colorForPos(this.localize(evt.getPosition()));
              this.owner.remove();
        };
        //this.colorChooser.callback = this.chooseColor;
        //connect(this.colorChooser, 'currentlySelectedColor', this, 'choosenColor');

        return this;
    },
    choosenColor: Color.black,
    remove: function($super) {
        var w = this.world();
        if (w && w.currentMenu === this) w.currentMenu = null;
        $super();
    },
    offsetForWorld: function(pos) {
        var bounds = this.innerBounds().translatedBy(pos);
        if (this.title) {
            bounds = bounds.withTopLeft(bounds.topLeft().addXY(0, this.title.getExtent().y));
        }
        if (this.owner.visibleBounds) {
            bounds = this.moveBoundsForVisibility(bounds, this.owner.visibleBounds());
        }
        this.setBounds(bounds);
    },
    moveBoundsForVisibility: function(menuBounds, visibleBounds) {
        var offsetX = 0,
            offsetY = 0;
        Global.lastMenuBounds = menuBounds;

        if (menuBounds.right() > visibleBounds.right())
            offsetX = -1 * (menuBounds.right() - visibleBounds.right());

        var overlapLeft = menuBounds.left() + offsetX;
        if (overlapLeft < 0)
            offsetX += -overlapLeft;

        if (menuBounds.bottom() > visibleBounds.bottom()) {
            offsetY = -1 * (menuBounds.bottom() - visibleBounds.bottom());
            // so that hand is not directly over menu, does not work when
            // menu is in the bottom right corner
            offsetX += 1;
        }
        var overlapTop = menuBounds.top() + offsetY;
        if (overlapTop < 0)
            offsetY += -overlapTop;

        return menuBounds.translatedBy(pt(offsetX, offsetY));
    },
}

);

lively.morphic.ColorChooser.subclass('lively.morphic.SimpleColorChooser',
'settings', {
    colorNames: 'custom',
},
'initializing', {
    initialize: function($super,bounds, colors){
        // under constructions...
        if (!colors) {
            colors = this.gatherCustomColors();
        }
        this.colors = colors;
        $super(bounds);
    },
    gatherCustomColors: function() {
        // lively.morphic.CustomColorChooser.prototype.gatherCustomColors()
        var colors = [];
        var gatherColor = function(eaColor) {
            if (eaColor && !colors.detect(function(colorSetEa) {
                return colorSetEa.equals(eaColor)}))
                colors.push(eaColor)
        }
        $world.withAllSubmorphsDo(function(ea) {
            gatherColor(ea.getBorderColor());
        })
        return colors
    },

    buildColorMap: function() {
        var x = Math.floor(Math.sqrt(this.colors.length)) + 1,
            y = x,
            extent = this.innerBounds().extent().scaleByPt(pt(1/x, 1/y));
        for (var j = 0; j < y; j++) {
            for (var i = 0; i < x; i++) {
                var idx = j*x+i, // running offset j*x^1 + i*y^0
                    color = this.colors[idx],
                    r = extent.scaleByPt(pt(i, j)).extent(extent),
                    morph = new lively.morphic.Box(r);
                morph.applyStyle({fill: color, borderWidth: 0});
                morph.ignoreEvents();
                this.addMorph(morph);
            }
        }
    },
},
'color mapping', {
    colorForPos: function(pos) {
        var r = this.shape.getBounds().insetBy(this.getBorderWidth()),
            pos = r.closestPointToPt(pos),
            m = this.submorphs.detect(function(ea) { return ea.bounds().containsPoint(pos) });
        return m ? m.getFill() : Color.black;
    },
});

}) // end of module<|endoftext|>


<commit_before>var passport        = require('passport'),
    LocalStrategy   = require('passport-local').Strategy,
    provider        = require('../providers').userProvider,
    bcrypt          = require('bcrypt');

module.exports = function () {
    passport.use(new LocalStrategy({
            usernameField: 'email',
            passwordField: 'password'
        },
        function (username, password, done) {
            return provider
                .findByEmail(username)
                .then(function (user) {
                    return bcrypt.compare(password, user.hash, function (err, res) {
                        if (err) return done(err);
                        if (res) done(null, user);
                        else done(null, false);
                    });
                });
        }
    ));

    passport.serializeUser(function(user, done) {
        done(null, user.id);
    });

    passport.deserializeUser(function(id, done) {
        provider.findById(id).then(function (user) {
            done(null, user);
        })
    });
};

module.exports.loggedIn = function (req, res, fn) {
    if (req.isAuthenticated()) fn();
    else res.redirect(302, '/login');
}<commit_msg>Authentication functionality updates<commit_after>var passport        = require('passport'),
    LocalStrategy   = require('passport-local').Strategy,
    provider        = require('../providers').userProvider,
    bcrypt          = require('bcryptjs');

module.exports = function () {
    passport.use(new LocalStrategy({
            usernameField: 'email',
            passwordField: 'password'
        },
        function (username, password, done) {
            return provider
                .findByEmail(username)
                .then(function (user) {
                    return bcrypt.compare(password, user.hash, function (err, res) {
                        if (err) return done(err);
                        if (res) { done(null, user); } else { done(null, false); }
                    });
                });
        }
    ));

    passport.serializeUser(function(user, done) {
        done(null, user.id);
    });

    passport.deserializeUser(function(id, done) {
        provider.findById(id).then(function (user) {
            done(null, user);
        });
    });
};

module.exports.loggedIn = function (req, res, fn) {
    if (req.isAuthenticated()) { fn(); } else { res.redirect(302, '/login'); }
}<|endoftext|>