<commit_before>(function(global, factory) {
    if (typeof module !== 'undefined' && module.exports !== undefined) {
        var $ = require('jquery');
        module.exports = factory($);

    } else if (typeof define === 'function' && define.amd) {
        define(['jquery'], function($) {
            return factory($);
        });

    } else {
        global.ZYTab = factory(global.jQuery || global.Zepto || global.$);
    }
})(this, function($) {
    var tabDataName = 'zt',
        defOptions = {
            lastTab: '',
            defTab: '',
            event: 'click',
            activeClass: 'zt-active'
        };

    function ZYTab(options) {
        this.tabs = {};
        this.bodies = {};

        $.extend(this, defOptions, options);

        $(options.selector).each($.proxy(
            function(k, el) {
                var $el = $(el),
                    s = $el.data(tabDataName),
                    k = createKey(s);

                if (this.defTab === '') {
                    this.defTab = k;
                }

                this.tabs[k] = $el;
                this.bodies[k] = $(s);
            }

        , this)).parent().on(
            this.event,
            this.selector,
            {context: this},
            this.handler
        );

        this.whenChange(this.defTab);
    }

    ZYTab.prototype = {
        constructor: ZYTab,

        handler: function(ev) {
            ev.data.context.whenChange($(this).data(tabDataName));
        },

        whenChange: function(curTab) {
            var lastTab = createKey(this.lastTab);
            curTab = createKey(curTab);
            if (curTab !== this.lastTab) {
                this.setTab(curTab, lastTab);
                this.setBody(curTab, lastTab);
                this.lastTab = curTab;
            }
        },

        setTab: function(curTab, lastTab) {
            lastTab = this.tabs[lastTab];
            curTab = this.tabs[curTab];
            if (lastTab) {
                lastTab.removeClass(this.activeClass);
            }
            if (curTab) {
                curTab.addClass(this.activeClass);
            }
        },

        setBody: function(curTab, lastTab) {
            lastTab = this.tabs[lastTab];
            curTab = this.tabs[curTab];
            if (lastTab) {
                lastTab.hide();
            }
            if (curTab) {
                curTab.show();
            }
        }
    };

    function createKey(s) {
        return s.replace(/[\s-#\.\[\]]+/g, '');
    }

    return ZYTab;
});

<commit_msg>fix bug<commit_after>(function(global, factory) {
    if (typeof module !== 'undefined' && module.exports !== undefined) {
        var $ = require('jquery');
        module.exports = factory($);

    } else if (typeof define === 'function' && define.amd) {
        define(['jquery'], function($) {
            return factory($);
        });

    } else {
        global.ZYTab = factory(global.jQuery || global.Zepto || global.$);
    }
})(this, function($) {
    var tabDataName = 'zt',
        defOptions = {
            lastTab: '',
            defTab: '',
            event: 'click',
            activeClass: 'zt-active'
        };

    function ZYTab(options) {
        this.tabs = {};
        this.bodies = {};

        $.extend(this, defOptions, options);

        $(options.selector).each($.proxy(
            function(k, el) {
                var $el = $(el),
                    s = $el.data(tabDataName),
                    k = createKey(s);

                if (this.defTab === '') {
                    this.defTab = k;
                }

                this.tabs[k] = $el;
                this.bodies[k] = $(s);
            }

        , this)).parent().on(
            this.event,
            this.selector,
            {context: this},
            this.handler
        );

        this.whenChange(this.defTab);
    }

    ZYTab.prototype = {
        constructor: ZYTab,

        handler: function(ev) {
            ev.data.context.whenChange($(this).data(tabDataName));
        },

        whenChange: function(curTab) {
            var lastTab = createKey(this.lastTab);
            curTab = createKey(curTab);
            if (curTab !== this.lastTab) {
                this.setTab(curTab, lastTab);
                this.setBody(curTab, lastTab);
                this.lastTab = curTab;
            }
        },

        setTab: function(curTab, lastTab) {
            lastTab = this.tabs[lastTab];
            curTab = this.tabs[curTab];
            if (lastTab) {
                lastTab.removeClass(this.activeClass);
            }
            if (curTab) {
                curTab.addClass(this.activeClass);
            }
        },

        setBody: function(curTab, lastTab) {
            lastTab = this.bodies[lastTab];
            curTab = this.bodies[curTab];
            if (lastTab) {
                lastTab.hide();
            }
            if (curTab) {
                curTab.show();
            }
        }
    };

    function createKey(s) {
        return s.replace(/[\s-#\.\[\]]+/g, '');
    }

    return ZYTab;
});

<|endoftext|>


<commit_before>// transliterated from the python snippet here:
// http://en.wikipedia.org/wiki/Lanczos_approximation

var g = 7;
var p = [
    0.99999999999980993,
    676.5203681218851,
    -1259.1392167224028,
    771.32342877765313,
    -176.61502916214059,
    12.507343278686905,
    -0.13857109526572012,
    9.9843695780195716e-6,
    1.5056327351493116e-7
];

var g_ln = 607/128;
var p_ln = [
    0.99999999999999709182,
    57.156235665862923517,
    -59.597960355475491248,
    14.136097974741747174,
    -0.49191381609762019978,
    0.33994649984811888699e-4,
    0.46523628927048575665e-4,
    -0.98374475304879564677e-4,
    0.15808870322491248884e-3,
    -0.21026444172410488319e-3,
    0.21743961811521264320e-3,
    -0.16431810653676389022e-3,
    0.84418223983852743293e-4,
    -0.26190838401581408670e-4,
    0.36899182659531622704e-5
];

// Spouge approximation (suitable for large arguments)
function lngamma(z) {

    if(z < 0) return Number('0/0');
    var x = p_ln[0];
    for(var i = p_ln.length - 1; i > 0; --i) x += p_ln[i] / (z + i);
    var t = z + g_ln + 0.5;
    return .5*Math.log(2*Math.PI)+(z+.5)*Math.log(t)-t+Math.log(x)-Math.log(z);
}

function gamma(z) {
    if (z < 0.5) {
        return Math.PI / (Math.sin(Math.PI * z) * gamma(1 - z));
    }
    else if(z > 100) return Math.exp(lngamma(z));
    else {
        z -= 1;
        var x = p[0];
        for (var i = 1; i < g + 2; i++) {
            x += p[i] / (z + i);
        }
        var t = z + g + 0.5;

        return Math.sqrt(2 * Math.PI)
            * Math.pow(t, z + 0.5)
            * Math.exp(-t)
            * x
        ;
    }
};<commit_msg>Add licensing note to gamma.js<commit_after>// Javascript implementation of the gamma function courtesy of
// substack: https://github.com/substack/gamma.js

// Released under an MIT license:

// This software is released under the MIT license:

// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:

// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.

// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

// transliterated from the python snippet here:
// http://en.wikipedia.org/wiki/Lanczos_approximation

var g = 7;
var p = [
    0.99999999999980993,
    676.5203681218851,
    -1259.1392167224028,
    771.32342877765313,
    -176.61502916214059,
    12.507343278686905,
    -0.13857109526572012,
    9.9843695780195716e-6,
    1.5056327351493116e-7
];

var g_ln = 607/128;
var p_ln = [
    0.99999999999999709182,
    57.156235665862923517,
    -59.597960355475491248,
    14.136097974741747174,
    -0.49191381609762019978,
    0.33994649984811888699e-4,
    0.46523628927048575665e-4,
    -0.98374475304879564677e-4,
    0.15808870322491248884e-3,
    -0.21026444172410488319e-3,
    0.21743961811521264320e-3,
    -0.16431810653676389022e-3,
    0.84418223983852743293e-4,
    -0.26190838401581408670e-4,
    0.36899182659531622704e-5
];

// Spouge approximation (suitable for large arguments)
function lngamma(z) {

    if(z < 0) return Number('0/0');
    var x = p_ln[0];
    for(var i = p_ln.length - 1; i > 0; --i) x += p_ln[i] / (z + i);
    var t = z + g_ln + 0.5;
    return .5*Math.log(2*Math.PI)+(z+.5)*Math.log(t)-t+Math.log(x)-Math.log(z);
}

function gamma(z) {
    if (z < 0.5) {
        return Math.PI / (Math.sin(Math.PI * z) * gamma(1 - z));
    }
    else if(z > 100) return Math.exp(lngamma(z));
    else {
        z -= 1;
        var x = p[0];
        for (var i = 1; i < g + 2; i++) {
            x += p[i] / (z + i);
        }
        var t = z + g + 0.5;

        return Math.sqrt(2 * Math.PI)
            * Math.pow(t, z + 0.5)
            * Math.exp(-t)
            * x
        ;
    }
};
<|endoftext|>


<commit_before>#!/usr/bin/env node
var fs = require('fs'),
    path = require('path'),
    helpers = require('../helpers'),
    logicCli = require('./logic'),
    argv = require('optimist').argv;

// ----------------------------------------
//  Main
// ----------------------------------------
var params = argv._;
var command = params[0];
var first = "" + params[1]; //make sure it is a string
var second = "" + params[2];
var templatesDir = path.join(__dirname, "../..", "samples");

var packagesLocalFolder = path.join(process.cwd(), "/packages");
var packagesAtlasboardFolder = path.join(__dirname, "../../packages");

// ----------------------------------
// Generate
// ----------------------------------
if (command === "generate") {
  var packageFolder = "default";
  var itemName = second;
  if (second.indexOf('#') > -1){ //package namespacing
    packageFolder = second.split('#')[0];
    itemName = second.split('#')[1];
  }
  return logicCli.generate(process.cwd(), packageFolder, first, itemName, function(err){
    if (err){
      console.error(err);
    }
  });
}
// ----------------------------------
// New item
// ----------------------------------
else if (command === "new") {
  var srcDir = path.join(templatesDir, "project");
  var destDir = path.join(process.cwd(), first);
  return logicCli.newProject (srcDir, destDir, function(err){
    if (err){
      console.error(err);
    }
    else{
      process.chdir(first);
      var childProcess = require('child_process');
      var child = childProcess.spawn('npm', ["install"], {stdio: 'inherit'});
      console.log ('Installing npm dependencies...');
      child.on('error', function () {
        console.log('\nError installing dependencies. Please run "npm install" inside the dashboard directory');
      });
      child.on('exit', function () {
        console.log('\nSUCCESS !!');
        console.log('\nNew project "%s" successfully created. Now:\n', first);
        console.log(' 1. cd ' + first);
        console.log(' 2. start your server with `atlasboard start`');
        console.log(' 3. visit it at http://localhost:3000\n');
      });
    }
  });
}
// ----------------------------------
// Display component list
// ----------------------------------
else if (command === "list") {
  function parse(package){
    console.log('\t\tPackage "' + path.basename(package.dir) + '":');
    package.items.forEach(function(item){
      console.log('\t\t    - ' + path.basename(item, '.js'));
    });
  }

  return logicCli.list([packagesLocalFolder, packagesAtlasboardFolder], function(err, packages){
    if (err){
      console.error('Error reading package folder');
      return;
    }

    console.log('Available widgets and jobs within all package folders:');
    packages.forEach(function(package){
      console.log(' ' + package.package);
      console.log('\t- Widgets:');
      package.widgets.forEach(parse);

      console.log('\t- Jobs:');
      package.jobs.forEach(parse);
    });
  });
}
// ----------------------------------
// Launch app
// ----------------------------------
else if (command === "start") {
  var port = isNaN(first) ? 3000 : first;
  logicCli.start(port, function(err){ //first parameters can be the port number
    if (err){
      console.error(err);
      process.exit(); //force exit (even if httpServer is up)
    }
  });
}
else{
  // ----------------------------------
  // No command found.
  // if we got here we better show the help message
  // ----------------------------------
  var projectPackageJson = JSON.parse(fs.readFileSync(path.join(__dirname, "../..", "package.json")));
  var version = projectPackageJson.version;
  console.log("\nAtlasBoard Version %s\n", version);
  console.log(" LIST OF AVAILABLE COMMANDS:\n");
  var commands = [
    {
      command: "new NAME",
      description: "Creates a new fully functional dashboard with the name given in NAME whose base lies in the current directory."},
    {
      command: "list",
      description: "List all available components (widgets or jobs) within all available packages."
    },
    {
      command: "generate (widget/dashboard/job) NAME",
      description: "Generates a basic widget/dashboard/job with the given NAME when run in an AtlasBoard project base directory." +
                   "\n\tIn order to create the component in an specific package, use PACKAGE#NAME"
    },
    {
      command: "start",
      description: "When run in a project's base directory, starts the AtlasBoard server." +
                   "\n\tUse $ atlasboard start <port> (to specify a port)"
    },
    {
      command: "help",
      description: "Displays this help text."
    }
];
  commands.forEach(function(item) {
    console.log(" atlasboard %s\n\t%s\n", item.command, item.description);
  });
}<commit_msg>Add help to install Atlassian package after creating a new wallboard<commit_after>#!/usr/bin/env node
var fs = require('fs'),
    path = require('path'),
    helpers = require('../helpers'),
    logicCli = require('./logic'),
    argv = require('optimist').argv;

// ----------------------------------------
//  Main
// ----------------------------------------
var params = argv._;
var command = params[0];
var first = "" + params[1]; //make sure it is a string
var second = "" + params[2];
var templatesDir = path.join(__dirname, "../..", "samples");

var packagesLocalFolder = path.join(process.cwd(), "/packages");
var packagesAtlasboardFolder = path.join(__dirname, "../../packages");

// ----------------------------------
// Generate
// ----------------------------------
if (command === "generate") {
  var packageFolder = "default";
  var itemName = second;
  if (second.indexOf('#') > -1){ //package namespacing
    packageFolder = second.split('#')[0];
    itemName = second.split('#')[1];
  }
  return logicCli.generate(process.cwd(), packageFolder, first, itemName, function(err){
    if (err){
      console.error(err);
    }
  });
}
// ----------------------------------
// New item
// ----------------------------------
else if (command === "new") {
  var srcDir = path.join(templatesDir, "project");
  var destDir = path.join(process.cwd(), first);
  return logicCli.newProject (srcDir, destDir, function(err){
    if (err){
      console.error(err);
    }
    else{
      process.chdir(first);
      var childProcess = require('child_process');
      var child = childProcess.spawn('npm', ["install"], {stdio: 'inherit'});
      console.log ('Installing npm dependencies...');
      child.on('error', function () {
        console.log('\nError installing dependencies. Please run "npm install" inside the dashboard directory');
      });
      child.on('exit', function () {
        console.log('\nSUCCESS !!');
        console.log('\nNew project "%s" successfully created. Now:\n', first);
        console.log(' 1. cd ' + first);
        console.log(' (optional: you can import the Atlassian package by running "git init;git submodule add https://bitbucket.org/atlassian/atlasboard-atlassian-package packages/atlassian"');
        console.log(' 2. start your server with `atlasboard start`');
        console.log(' 3. visit it at http://localhost:3000\n');
      });
    }
  });
}
// ----------------------------------
// Display component list
// ----------------------------------
else if (command === "list") {
  function parse(package){
    console.log('\t\tPackage "' + path.basename(package.dir) + '":');
    package.items.forEach(function(item){
      console.log('\t\t    - ' + path.basename(item, '.js'));
    });
  }

  return logicCli.list([packagesLocalFolder, packagesAtlasboardFolder], function(err, packages){
    if (err){
      console.error('Error reading package folder');
      return;
    }

    console.log('Available widgets and jobs within all package folders:');
    packages.forEach(function(package){
      console.log(' ' + package.package);
      console.log('\t- Widgets:');
      package.widgets.forEach(parse);

      console.log('\t- Jobs:');
      package.jobs.forEach(parse);
    });
  });
}
// ----------------------------------
// Launch app
// ----------------------------------
else if (command === "start") {
  var port = isNaN(first) ? 3000 : first;
  logicCli.start(port, function(err){ //first parameters can be the port number
    if (err){
      console.error(err);
      process.exit(); //force exit (even if httpServer is up)
    }
  });
}
else{
  // ----------------------------------
  // No command found.
  // if we got here we better show the help message
  // ----------------------------------
  var projectPackageJson = JSON.parse(fs.readFileSync(path.join(__dirname, "../..", "package.json")));
  var version = projectPackageJson.version;
  console.log("\nAtlasBoard Version %s\n", version);
  console.log(" LIST OF AVAILABLE COMMANDS:\n");
  var commands = [
    {
      command: "new NAME",
      description: "Creates a new fully functional dashboard with the name given in NAME whose base lies in the current directory."},
    {
      command: "list",
      description: "List all available components (widgets or jobs) within all available packages."
    },
    {
      command: "generate (widget/dashboard/job) NAME",
      description: "Generates a basic widget/dashboard/job with the given NAME when run in an AtlasBoard project base directory." +
                   "\n\tIn order to create the component in an specific package, use PACKAGE#NAME"
    },
    {
      command: "start",
      description: "When run in a project's base directory, starts the AtlasBoard server." +
                   "\n\tUse $ atlasboard start <port> (to specify a port)"
    },
    {
      command: "help",
      description: "Displays this help text."
    }
];
  commands.forEach(function(item) {
    console.log(" atlasboard %s\n\t%s\n", item.command, item.description);
  });
}<|endoftext|>


<commit_before>// -------------------------------------------------------------------------- \\
// File: MenuView.js                                                          \\
// Module: ControlViews                                                       \\
// Requires: Core, Foundation, DOM, View                                      \\
// Author: Neil Jenkins                                                       \\
// License: © 2010–2013 Opera Software ASA. All rights reserved.              \\
// -------------------------------------------------------------------------- \\

"use strict";

( function ( NS ) {

// A menu option must have:
// filter( pattern ): RegExp -> Boolean
// isFocussed: Boolean
// isHidden: Boolean
// isDisabled: Boolean

var MenuController = NS.Class({

    Extends: NS.Object,

    options: [],

    // --- Focus ---

    canSelect: function ( option ) {
        return !option.get( 'isHidden' ) && !option.get( 'isDisabled' );
    },

    focussedOption: null,

    getAdjacentOption: function ( step ) {
        var options = this.get( 'options' ),
            l = options.get( 'length' ),
            i = options.indexOf( this.get( 'focussedOption' ) ),
            current;

        if ( i < 0 && step < 0 ) {
            i = l;
        }
        current = i.mod( l );

        do {
            i = ( i + step ).mod( l );
        } while ( l &&
            !this.canSelect( options.getObjectAt( i ) ) && i !== current );

        return options.getObjectAt( i );
    },

    focusPrevious: function ( event ) {
        if ( event ) { event.preventDefault(); }
        return this.focusOption( this.getAdjacentOption( -1 ) );
    },

    focusNext: function ( event ) {
        if ( event ) { event.preventDefault(); }
        return this.focusOption( this.getAdjacentOption( 1 ) );
    },

    focusOption: function ( option ) {
        var current = this.get( 'focussedOption' );
        if ( current !== option ) {
            if ( current ) {
                current.set( 'isFocussed', false );
            }
            if ( option ) {
                if ( !this.canSelect( option ) ) {
                    option = null;
                } else {
                    option.set( 'isFocussed', true );
                }
            }
            this.set( 'focussedOption', option );
        }
        return this;
    },

    blurOption: function ( option ) {
        if ( this.get( 'focussedOption' ) === option ) {
            this.focusOption( null );
        }
        return this;
    },

    selectFocussed: function ( event ) {
        if ( event ) { event.preventDefault(); }
        var focussedOption = this.get( 'focussedOption' );
        if ( focussedOption && this.canSelect( focussedOption ) ) {
            focussedOption.activate( this );
        }
        return this;
    },

    // --- Filter ---

    filter: '',

    filterDidChange: function () {
        var value = this.get( 'filter' ).escapeRegExp(),
            pattern = value ? new RegExp( '\\b' + value, 'i' ) : null,
            options = this.get( 'options' ),
            l = options.get( 'length' ),
            focussedOption = this.get( 'focussedOption' );

        while ( l-- ) {
            options.getObjectAt( l ).filter( pattern );
        }
        if ( !focussedOption || !this.canSelect( focussedOption ) ) {
            this.focusNext();
        }
    }.observes( 'filter' ),

    // --- Keyboard support ---

    keyBindings: {
        esc: 'onEscape',
        enter: 'selectFocussed',
        up: 'focusPrevious',
        down: 'focusNext',
        left: 'closeIfSub',
        right: 'activateIfMenu'
    },

    triggerKeyBinding: function ( event ) {
        var key = NS.DOMEvent.lookupKey( event ),
            bindings = this.get( 'keyBindings' );
        if ( bindings[ key ] ) {
            event.stopPropagation();
            NS.RunLoop.invokeInNextEventLoop(
                this[ bindings[ key ] ].bind( this, event, key ) );
        }
    }.on( 'keydown' ),

    onEscape: function ( event ) {
        event.preventDefault();
        var filter = this.get( 'filter' );
        if ( filter ) {
            this.set( 'filter', '' );
        } else {
            this.get( 'view' ).hide();
        }
    },

    closeIfSub: function () {
        var view = this.get( 'view' ),
            popOverView;
        if ( !view.get( 'showFilter' ) &&
                ( popOverView = view.getParent( NS.PopOverView ) ) &&
                  popOverView.get( 'parentPopOverView' ) ) {
            view.hide();
        }
    },

    activateIfMenu: function () {
        var focussedOption = this.get( 'focussedOption' );
        if ( focussedOption && !this.get( 'view' ).get( 'showFilter' ) &&
                focussedOption.get( 'button' ) instanceof NS.MenuButtonView ) {
            this.selectFocussed();
        }
    }
});

var MenuOptionView = NS.Class({

    Extends: NS.View,

    isHidden: false,
    isDisabled: function () {
        return this.getFromPath( 'button.isDisabled' );
    }.property( 'button.isDisabled' ),
    isFocussed: false,
    isFocussable: function () {
        return !this.get( 'isHidden' ) && !this.get( 'isDisabled' );
    }.property( 'isHidden', 'isDisabled' ),

    layerTag: 'li',

    className: function () {
        return 'MenuOptionView' +
            ( this.get( 'isFocussed' ) ? ' focussed' : '' ) +
            ( this.get( 'isHidden' ) ? ' hidden' : '' );
    }.property( 'isFocussed', 'isHidden' ),

    init: function ( view, controller ) {
        this.childViews = [ view ];
        this.button = view;
        this.controller = controller;
        MenuOptionView.parent.init.call( this );
    },

    scrollIntoView: function () {
        if ( this.get( 'isFocussed' ) ) {
            var scrollView = this.getParent( NS.ScrollView );
            if ( scrollView ) {
                var scrollHeight = scrollView.get( 'pxHeight' ),
                    scrollTop = scrollView.get( 'scrollTop' ),
                    top = this.getPositionRelativeTo( scrollView ).top,
                    height = this.get( 'pxHeight' );

                if ( top < scrollTop ) {
                    scrollView.scrollTo( 0, top - ( height >> 1 ), true );
                } else if ( top + height > scrollTop + scrollHeight ) {
                    scrollView.scrollTo( 0,
                        top + height - scrollHeight + ( height >> 1 ), true );
                }
            }
        }
    }.observes( 'isFocussed' ),

    _focusTimeout: null,

    takeFocus: function () {
        if ( this.get( 'isInDocument' ) ) {
            this.get( 'controller' ).focusOption( this )
                .activateIfMenu();
        }
    },

    mouseMove: function () {
        if ( !this.get( 'isFocussed' ) && !this._focusTimeout ) {
            var popOverView = this.getParent( NS.PopOverView );
            if ( popOverView && popOverView.hasSubView() ) {
                this._focusTimeout = NS.RunLoop.invokeAfterDelay(
                    this.takeFocus, 75, this );
            } else {
                this.takeFocus();
            }
        }
    }.on( 'mousemove' ),

    mouseOut: function () {
        if ( this._focusTimeout ) {
            NS.RunLoop.cancel( this._focusTimeout );
            this._focusTimeout = null;
        }
        if ( !this.get( 'button' ).get( 'isActive' ) ) {
            this.get( 'controller' ).blurOption( this );
        }
    }.on( 'mouseout' ),

    filter: function ( pattern ) {
        var label = this.get( 'button' ).get( 'label' );
        this.set( 'isHidden', !!pattern && !pattern.test( label ) );
    },

    activate: function () {
        var button = this.get( 'button' );
        if ( button.activate ) { button.activate(); }
    }
});

var MenuView = NS.Class({

    Extends: NS.View,

    className: 'MenuView',

    showFilter: false,
    closeOnActivate: true,

    didCreateLayer: function ( layer ) {
        MenuView.parent.didCreateLayer.call( this, layer );
        layer.addEventListener( 'mousemove', this, false );
        layer.addEventListener( 'mouseout', this, false );
    },

    willDestroyLayer: function ( layer ) {
        layer.removeEventListener( 'mouseout', this, false );
        layer.removeEventListener( 'mousemove', this, false );
        MenuView.parent.willDestroyLayer.call( this, layer );
    },

    didLeaveDocument: function () {
        if ( !this.get( 'showFilter' ) ) {
            this.get( 'controller' ).focusOption( null );
        }
        return MenuView.parent.didLeaveDocument.call( this );
    },

    _checkSize: function () {
        if ( !this.get( 'isInDocument' ) ) {
            return;
        }
        var scrollView = this._scrollView;
        if ( scrollView && !this.getParent( NS.ScrollView ) ) {
            var layer = this.get( 'layer' ),
                delta = layer.getBoundingClientRect().bottom -
                    layer.ownerDocument.documentElement.clientHeight;
            scrollView.set( 'layout', {
                maxHeight: scrollView.get( 'pxHeight' ) - delta - 10
            });
        }

        if ( this.get( 'showFilter' ) ) {
            var controller = this.get( 'controller' ),
                input = this._input;
            if ( !controller.get( 'focussedOption' ) ) {
                controller.focusNext();
            }
            NS.RunLoop.invokeInNextEventLoop( function () {
                input.focus().set( 'selection', {
                    start: 0,
                    end: input.get( 'value' ).length
                });
            });
        }
    }.queue( 'after' ).observes( 'isInDocument' ),

    mayHaveResized: function () {
        this.parentViewDidResize();
    }.queue( 'after' ).observes( 'controller.filter' ),

    nextEventTarget: function () {
        return this.get( 'controller' );
    }.property( 'controller' ),

    controller: function () {
        return new MenuController({
            view: this
        });
    }.property(),

    ItemView: MenuOptionView,

    draw: function ( layer ) {
        var Element = NS.Element,
            el = Element.create,
            controller = this.get( 'controller' ),
            MenuOptionView = this.get( 'ItemView' ),
            optionViews;
        Element.appendChildren( layer, [
            this.get( 'showFilter' ) ? el( 'div', [
                this._input = new NS.TextView({
                    blurOnEscape: false,
                    type: 'text filter',
                    value: NS.bindTwoWay( 'filter', this.get( 'controller' ) )
                })
            ]) : null,
            this._scrollView = new NS.ScrollView({
                positioning: 'relative',
                layout: {},
                layerTag: 'ul',
                childViews:
                    optionViews = this.get( 'options' ).map( function ( view ) {
                        return new MenuOptionView( view, controller );
                    })
            })
        ]);
        controller.set( 'options', optionViews );
    },

    hide: function () {
        var parent = this.get( 'parentView' );
        if ( parent ) {
            NS.RunLoop.invokeInNextEventLoop( parent.hide, parent );
        }
    },

    hideAll: function () {
        if ( this.get( 'closeOnActivate' ) ) {
            var popOverView = this.getParent( NS.PopOverView ) ||
                    this.get( 'parentView' ),
                parent;
            if ( popOverView ) {
                while ( parent = popOverView.get( 'parentPopOverView' ) ) {
                    popOverView = parent;
                }
                NS.RunLoop.invokeInNextEventLoop(
                    popOverView.hide, popOverView );
            }
        }
    }.on( 'button:activate' ),

    fireShortcut: function ( event ) {
        if ( !this.get( 'showFilter' ) ) {
            var key = NS.DOMEvent.lookupKey( event ),
                handler = NS.ViewEventsController
                            .kbShortcuts.getHandlerForKey( key ),
                parent, object, method;
            if ( handler ) {
                parent = object = handler[0];
                method = handler[1];
                // Check object is child view of the menu; we want to ignore any
                // other keyboard shortcuts.
                if ( object instanceof NS.View ) {
                    while ( parent && parent !== this ) {
                        parent = parent.get( 'parentView' );
                    }
                    if ( parent ) {
                        object[ method ]( event );
                        event.preventDefault();
                    }
                }
            }
        }
    }.on( 'keypress' )
});

NS.MenuController = MenuController;
NS.MenuOptionView = MenuOptionView;
NS.MenuView = MenuView;

}( this.O ) );
<commit_msg>Trigger MenuView key bindings in current run loop.<commit_after>// -------------------------------------------------------------------------- \\
// File: MenuView.js                                                          \\
// Module: ControlViews                                                       \\
// Requires: Core, Foundation, DOM, View                                      \\
// Author: Neil Jenkins                                                       \\
// License: © 2010–2013 Opera Software ASA. All rights reserved.              \\
// -------------------------------------------------------------------------- \\

"use strict";

( function ( NS ) {

// A menu option must have:
// filter( pattern ): RegExp -> Boolean
// isFocussed: Boolean
// isHidden: Boolean
// isDisabled: Boolean

var MenuController = NS.Class({

    Extends: NS.Object,

    options: [],

    // --- Focus ---

    canSelect: function ( option ) {
        return !option.get( 'isHidden' ) && !option.get( 'isDisabled' );
    },

    focussedOption: null,

    getAdjacentOption: function ( step ) {
        var options = this.get( 'options' ),
            l = options.get( 'length' ),
            i = options.indexOf( this.get( 'focussedOption' ) ),
            current;

        if ( i < 0 && step < 0 ) {
            i = l;
        }
        current = i.mod( l );

        do {
            i = ( i + step ).mod( l );
        } while ( l &&
            !this.canSelect( options.getObjectAt( i ) ) && i !== current );

        return options.getObjectAt( i );
    },

    focusPrevious: function ( event ) {
        if ( event ) { event.preventDefault(); }
        return this.focusOption( this.getAdjacentOption( -1 ) );
    },

    focusNext: function ( event ) {
        if ( event ) { event.preventDefault(); }
        return this.focusOption( this.getAdjacentOption( 1 ) );
    },

    focusOption: function ( option ) {
        var current = this.get( 'focussedOption' );
        if ( current !== option ) {
            if ( current ) {
                current.set( 'isFocussed', false );
            }
            if ( option ) {
                if ( !this.canSelect( option ) ) {
                    option = null;
                } else {
                    option.set( 'isFocussed', true );
                }
            }
            this.set( 'focussedOption', option );
        }
        return this;
    },

    blurOption: function ( option ) {
        if ( this.get( 'focussedOption' ) === option ) {
            this.focusOption( null );
        }
        return this;
    },

    selectFocussed: function ( event ) {
        if ( event ) { event.preventDefault(); }
        var focussedOption = this.get( 'focussedOption' );
        if ( focussedOption && this.canSelect( focussedOption ) ) {
            focussedOption.activate( this );
        }
        return this;
    },

    // --- Filter ---

    filter: '',

    filterDidChange: function () {
        var value = this.get( 'filter' ).escapeRegExp(),
            pattern = value ? new RegExp( '\\b' + value, 'i' ) : null,
            options = this.get( 'options' ),
            l = options.get( 'length' ),
            focussedOption = this.get( 'focussedOption' );

        while ( l-- ) {
            options.getObjectAt( l ).filter( pattern );
        }
        if ( !focussedOption || !this.canSelect( focussedOption ) ) {
            this.focusNext();
        }
    }.observes( 'filter' ),

    // --- Keyboard support ---

    keyBindings: {
        esc: 'onEscape',
        enter: 'selectFocussed',
        up: 'focusPrevious',
        down: 'focusNext',
        left: 'closeIfSub',
        right: 'activateIfMenu'
    },

    triggerKeyBinding: function ( event ) {
        var key = NS.DOMEvent.lookupKey( event ),
            bindings = this.get( 'keyBindings' );
        if ( bindings[ key ] ) {
            event.stopPropagation();
            this[ bindings[ key ] ]( event, key );
        }
    }.on( 'keydown' ),

    onEscape: function ( event ) {
        event.preventDefault();
        var filter = this.get( 'filter' );
        if ( filter ) {
            this.set( 'filter', '' );
        } else {
            this.get( 'view' ).hide();
        }
    },

    closeIfSub: function () {
        var view = this.get( 'view' ),
            popOverView;
        if ( !view.get( 'showFilter' ) &&
                ( popOverView = view.getParent( NS.PopOverView ) ) &&
                  popOverView.get( 'parentPopOverView' ) ) {
            view.hide();
        }
    },

    activateIfMenu: function () {
        var focussedOption = this.get( 'focussedOption' );
        if ( focussedOption && !this.get( 'view' ).get( 'showFilter' ) &&
                focussedOption.get( 'button' ) instanceof NS.MenuButtonView ) {
            this.selectFocussed();
        }
    }
});

var MenuOptionView = NS.Class({

    Extends: NS.View,

    isHidden: false,
    isDisabled: function () {
        return this.getFromPath( 'button.isDisabled' );
    }.property( 'button.isDisabled' ),
    isFocussed: false,
    isFocussable: function () {
        return !this.get( 'isHidden' ) && !this.get( 'isDisabled' );
    }.property( 'isHidden', 'isDisabled' ),

    layerTag: 'li',

    className: function () {
        return 'MenuOptionView' +
            ( this.get( 'isFocussed' ) ? ' focussed' : '' ) +
            ( this.get( 'isHidden' ) ? ' hidden' : '' );
    }.property( 'isFocussed', 'isHidden' ),

    init: function ( view, controller ) {
        this.childViews = [ view ];
        this.button = view;
        this.controller = controller;
        MenuOptionView.parent.init.call( this );
    },

    scrollIntoView: function () {
        if ( this.get( 'isFocussed' ) ) {
            var scrollView = this.getParent( NS.ScrollView );
            if ( scrollView ) {
                var scrollHeight = scrollView.get( 'pxHeight' ),
                    scrollTop = scrollView.get( 'scrollTop' ),
                    top = this.getPositionRelativeTo( scrollView ).top,
                    height = this.get( 'pxHeight' );

                if ( top < scrollTop ) {
                    scrollView.scrollTo( 0, top - ( height >> 1 ), true );
                } else if ( top + height > scrollTop + scrollHeight ) {
                    scrollView.scrollTo( 0,
                        top + height - scrollHeight + ( height >> 1 ), true );
                }
            }
        }
    }.observes( 'isFocussed' ),

    _focusTimeout: null,

    takeFocus: function () {
        if ( this.get( 'isInDocument' ) ) {
            this.get( 'controller' ).focusOption( this )
                .activateIfMenu();
        }
    },

    mouseMove: function () {
        if ( !this.get( 'isFocussed' ) && !this._focusTimeout ) {
            var popOverView = this.getParent( NS.PopOverView );
            if ( popOverView && popOverView.hasSubView() ) {
                this._focusTimeout = NS.RunLoop.invokeAfterDelay(
                    this.takeFocus, 75, this );
            } else {
                this.takeFocus();
            }
        }
    }.on( 'mousemove' ),

    mouseOut: function () {
        if ( this._focusTimeout ) {
            NS.RunLoop.cancel( this._focusTimeout );
            this._focusTimeout = null;
        }
        if ( !this.get( 'button' ).get( 'isActive' ) ) {
            this.get( 'controller' ).blurOption( this );
        }
    }.on( 'mouseout' ),

    filter: function ( pattern ) {
        var label = this.get( 'button' ).get( 'label' );
        this.set( 'isHidden', !!pattern && !pattern.test( label ) );
    },

    activate: function () {
        var button = this.get( 'button' );
        if ( button.activate ) { button.activate(); }
    }
});

var MenuView = NS.Class({

    Extends: NS.View,

    className: 'MenuView',

    showFilter: false,
    closeOnActivate: true,

    didCreateLayer: function ( layer ) {
        MenuView.parent.didCreateLayer.call( this, layer );
        layer.addEventListener( 'mousemove', this, false );
        layer.addEventListener( 'mouseout', this, false );
    },

    willDestroyLayer: function ( layer ) {
        layer.removeEventListener( 'mouseout', this, false );
        layer.removeEventListener( 'mousemove', this, false );
        MenuView.parent.willDestroyLayer.call( this, layer );
    },

    didLeaveDocument: function () {
        if ( !this.get( 'showFilter' ) ) {
            this.get( 'controller' ).focusOption( null );
        }
        return MenuView.parent.didLeaveDocument.call( this );
    },

    _checkSize: function () {
        if ( !this.get( 'isInDocument' ) ) {
            return;
        }
        var scrollView = this._scrollView;
        if ( scrollView && !this.getParent( NS.ScrollView ) ) {
            var layer = this.get( 'layer' ),
                delta = layer.getBoundingClientRect().bottom -
                    layer.ownerDocument.documentElement.clientHeight;
            scrollView.set( 'layout', {
                maxHeight: scrollView.get( 'pxHeight' ) - delta - 10
            });
        }

        if ( this.get( 'showFilter' ) ) {
            var controller = this.get( 'controller' ),
                input = this._input;
            if ( !controller.get( 'focussedOption' ) ) {
                controller.focusNext();
            }
            NS.RunLoop.invokeInNextEventLoop( function () {
                input.focus().set( 'selection', {
                    start: 0,
                    end: input.get( 'value' ).length
                });
            });
        }
    }.queue( 'after' ).observes( 'isInDocument' ),

    mayHaveResized: function () {
        this.parentViewDidResize();
    }.queue( 'after' ).observes( 'controller.filter' ),

    nextEventTarget: function () {
        return this.get( 'controller' );
    }.property( 'controller' ),

    controller: function () {
        return new MenuController({
            view: this
        });
    }.property(),

    ItemView: MenuOptionView,

    draw: function ( layer ) {
        var Element = NS.Element,
            el = Element.create,
            controller = this.get( 'controller' ),
            MenuOptionView = this.get( 'ItemView' ),
            optionViews;
        Element.appendChildren( layer, [
            this.get( 'showFilter' ) ? el( 'div', [
                this._input = new NS.TextView({
                    blurOnEscape: false,
                    type: 'text filter',
                    value: NS.bindTwoWay( 'filter', this.get( 'controller' ) )
                })
            ]) : null,
            this._scrollView = new NS.ScrollView({
                positioning: 'relative',
                layout: {},
                layerTag: 'ul',
                childViews:
                    optionViews = this.get( 'options' ).map( function ( view ) {
                        return new MenuOptionView( view, controller );
                    })
            })
        ]);
        controller.set( 'options', optionViews );
    },

    hide: function () {
        var parent = this.get( 'parentView' );
        if ( parent ) {
            NS.RunLoop.invokeInNextEventLoop( parent.hide, parent );
        }
    },

    hideAll: function () {
        if ( this.get( 'closeOnActivate' ) ) {
            var popOverView = this.getParent( NS.PopOverView ) ||
                    this.get( 'parentView' ),
                parent;
            if ( popOverView ) {
                while ( parent = popOverView.get( 'parentPopOverView' ) ) {
                    popOverView = parent;
                }
                NS.RunLoop.invokeInNextEventLoop(
                    popOverView.hide, popOverView );
            }
        }
    }.on( 'button:activate' ),

    fireShortcut: function ( event ) {
        if ( !this.get( 'showFilter' ) ) {
            var key = NS.DOMEvent.lookupKey( event ),
                handler = NS.ViewEventsController
                            .kbShortcuts.getHandlerForKey( key ),
                parent, object, method;
            if ( handler ) {
                parent = object = handler[0];
                method = handler[1];
                // Check object is child view of the menu; we want to ignore any
                // other keyboard shortcuts.
                if ( object instanceof NS.View ) {
                    while ( parent && parent !== this ) {
                        parent = parent.get( 'parentView' );
                    }
                    if ( parent ) {
                        object[ method ]( event );
                        event.preventDefault();
                    }
                }
            }
        }
    }.on( 'keypress' )
});

NS.MenuController = MenuController;
NS.MenuOptionView = MenuOptionView;
NS.MenuView = MenuView;

}( this.O ) );
<|endoftext|>


<commit_before>var fs = require('fs');
var TomahawkJS = require('tomahawkjs');
var failOn = require('./utils').failOn;

/**
 * Load an AXE bundle and terminate on errors.
 */
var loadAxe = function (path, callback) {
    TomahawkJS.loadAxe(path, function (err, axe) {
        failOn(err, "Error while loading axe:", err);
        axe.getInstance(function(err, instance_context) {
            failOn(err, "Could not instantiate a resolver object:", err);
            var instance = instance_context.instance;
            var context = instance_context.context;
            instance.init();
            callback(instance, context);
        });
    });
};

exports.generate = function (args) {
    failOn(args.length !== 1, "You need to specify the name of the new resolver.");
    console.error("Not yet implemented. Please stand by!");
    // FIXME: Implement!
};

exports.resolve = function (args) {
    failOn(args.length == 0, "You need to specify a resolver to utilise.");
    failOn(args.length < 3 || args.length > 4, "Usage: \n\t tomahawkjs resolve <resolver> <artist> <title> [<album>]");
    fs.stat(args[0], function (err, stats) {
        failOn(err, "Error while reading the resolver path:", err);
        if (stats.isFile()) {
            // Load the resolver from a (zipped) bundle.
            loadAxe(args[0], function (instance, context) {
                context.on('track-result', function (qid, result) {
                    console.log(JSON.stringify(result, null, 4));
                });
                instance.resolve("some-id", args[1], args[3], args[2]);
            });
        } else if (stats.isDirectory()) {
            // Load the resolver from a directory.
            // FIXME: Implement!
        } else {
            // Will be interesting what kind of fs type people will access here
            console.error("Unsupported FS item for a resolver bundle.");
            process.exit(1);
        }
    });
};

exports.search = function (args) {
    failOn(args.length == 0, "You need to specify a resolver to utilise.");
    failOn(args.length < 2, "Usage: \n\t tomahawkjs search <resolver> <query-part1> [<query-part2> ..]");
    fs.stat(args[0], function (err, stats) {
        failOn(err, "Error while reading the resolver path:", err);
        if (stats.isFile()) {
            // Load the resolver from a (zipped) bundle.
            loadAxe(args[0], function (instance, context) {
                context.on('track-result', function (qid, result) {
                    console.log(JSON.stringify(result, null, 4));
                });
                instance.search("some-id", args.slice(1).join(' '));
            });
        } else if (stats.isDirectory()) {
            // Load the resolver from a directory.
            // FIXME: Implement!
        } else {
            // Will be interesting what kind of fs type people will access here
            console.error("Unsupported FS item for a resolver bundle.");
            process.exit(1);
        }
    });
};
<commit_msg>DRY resolver loading<commit_after>var fs = require('fs');
var TomahawkJS = require('tomahawkjs');
var failOn = require('./utils').failOn;

/**
 * Load an AXE bundle and terminate on errors.
 */
var loadResolver = function (path, callback) {
    fs.stat(path, function (err, stats) {
        failOn(err, "Error while reading the resolver path:", err);
        if (stats.isFile()) {
            TomahawkJS.loadAxe(path, function (err, axe) {
                failOn(err, "Error while loading axe:", err);
                axe.getInstance(function(err, instance_context) {
                    failOn(err, "Could not instantiate a resolver object:", err);
                    var instance = instance_context.instance;
                    var context = instance_context.context;
                    instance.init();
                    callback(instance, context);
                });
            });
        } else if (stats.isDirectory()) {
            // Load the resolver from a directory.
            // FIXME: Implement!
        } else {
            // Will be interesting what kind of fs type people will access here
            console.error("Unsupported FS item for a resolver bundle.");
            process.exit(1);
        }
    });
};

exports.generate = function (args) {
    failOn(args.length !== 1, "You need to specify the name of the new resolver.");
    console.error("Not yet implemented. Please stand by!");
    // FIXME: Implement!
};

exports.resolve = function (args) {
    failOn(args.length == 0, "You need to specify a resolver to utilise.");
    failOn(args.length < 3 || args.length > 4, "Usage: \n\t tomahawkjs resolve <resolver> <artist> <title> [<album>]");
    loadResolver(args[0], function (instance, context) {
        context.on('track-result', function (qid, result) {
            console.log(JSON.stringify(result, null, 4));
        });
        instance.resolve("some-id", args[1], args[3], args[2]);
    });
};

exports.search = function (args) {
    failOn(args.length == 0, "You need to specify a resolver to utilise.");
    failOn(args.length < 2, "Usage: \n\t tomahawkjs search <resolver> <query-part1> [<query-part2> ..]");
    loadResolver(args[0], function (instance, context) {
        context.on('track-result', function (qid, result) {
            console.log(JSON.stringify(result, null, 4));
        });
        instance.search("some-id", args.slice(1).join(' '));
    });
};
<|endoftext|>


<commit_before>getBrowserInfo = function () {
  return {
    browser: window.navigator.userAgent,
    userId: Meteor.userId && Meteor.userId(),
    url: location.href,
    resolution: getResolution()
  };
}

getResolution = function () {
  if(screen && screen.width && screen.height) {
    var resolution = screen.width + 'x' + screen.height;
    return resolution;
  }
}

getErrorStack = function (zone) {
  var trace = [];
  var eventMap = zone.eventMap || {};
  var infoMap = zone.infoMap || {};

  trace.push({
    at: (new Date().getTime()),
    stack: getNormalizedStacktrace(zone.erroredStack._e)
  });

  while (zone && zone.currentStack) {
    var stack = getNormalizedStacktrace(zone.currentStack._e);
    var events = eventMap[zone.id];
    var info = getInfoArray(infoMap[zone.id]);
    var ownerArgsEvent = events && events[0] && events[0].type == 'owner-args' && events.shift();
    var runAt = (ownerArgsEvent)? ownerArgsEvent.at : zone.runAt;
    var ownerArgs = (ownerArgsEvent)? _.toArray(ownerArgsEvent.args) : [];

    zone.owner && delete zone.owner.zoneId;

    trace.push({
      createdAt: zone.createdAt,
      runAt: runAt,
      stack: stack,
      owner: zone.owner,
      ownerArgs: ownerArgs,
      events: events,
      info: info,
      zoneId: zone.id
    });
    zone = zone.parent;
  };
  return trace;
}

getNormalizedStacktrace = function (e) {
  var trace = printStackTrace({e: e});
  trace = _.filter(trace, stackFramesFilter);
  trace = _.map(trace, formatTraceLine);
  return trace.join('\n');
}

getInfoArray = function (info) {
  return _(info || {}).map(function (value, type) {
    value.type = type;
    return value;
  })
}

formatTraceLine = function (oldLine) {
  if(oldLine) {
    //parts => ['functionName', 'url:line:col']
    var parts = oldLine.split('@');

    if(parts.length < 2) {
      return oldLine;
    }

    if(parts.length > 2) {
      var messageParts = parts.slice(1);
      parts.splice(0, 1);
      parts[1] = messageParts.join('@');
    }

    var line = '    at ';
    var origin = getCurrentOrigin();
    var path = parts[1].replace(origin + '/', '', 'gi');
    if(parts[0] === '{anonymous}()') {
      line += path;
    } else {
      line += parts[0] + ' ('+path+')';
    }
    return line;
  }
}

getCurrentOrigin = function () {
  // Internet Explorer doesn't have window.location.origin
  return window.location.origin || window.location.protocol
  + window.location.hostname
  + window.location.port;
}

var filterRegExp = /\/packages\/zones\/assets\/|^Error$/;
stackFramesFilter = function (line) {
  return !line.match(filterRegExp);
}

getTime = function () {
  if(Kadira && Kadira.syncedDate) {
    return Kadira.syncedDate.getTime();
  } else {
    return (new Date().getTime());
  }
}
<commit_msg>Add comments<commit_after>getBrowserInfo = function () {
  return {
    browser: window.navigator.userAgent,
    userId: Meteor.userId && Meteor.userId(),
    url: location.href,
    resolution: getResolution()
  };
}

getResolution = function () {
  if(screen && screen.width && screen.height) {
    var resolution = screen.width + 'x' + screen.height;
    return resolution;
  }
}

getErrorStack = function (zone) {
  var trace = [];
  var eventMap = zone.eventMap || {};
  var infoMap = zone.infoMap || {};

  trace.push({
    at: (new Date().getTime()),
    stack: getNormalizedStacktrace(zone.erroredStack._e)
  });

  while (zone && zone.currentStack) {
    var stack = getNormalizedStacktrace(zone.currentStack._e);
    var events = eventMap[zone.id];
    var info = getInfoArray(infoMap[zone.id]);
    var ownerArgsEvent = events && events[0] && events[0].type == 'owner-args' && events.shift();
    var runAt = (ownerArgsEvent)? ownerArgsEvent.at : zone.runAt;
    var ownerArgs = (ownerArgsEvent)? _.toArray(ownerArgsEvent.args) : [];

    zone.owner && delete zone.owner.zoneId;

    trace.push({
      createdAt: zone.createdAt,
      runAt: runAt,
      stack: stack,
      owner: zone.owner,
      ownerArgs: ownerArgs,
      events: events,
      info: info,
      zoneId: zone.id
    });
    zone = zone.parent;
  };
  return trace;
}

getNormalizedStacktrace = function (e) {
  var trace = printStackTrace({e: e});
  trace = _.filter(trace, stackFramesFilter);
  trace = _.map(trace, formatTraceLine);
  return trace.join('\n');
}

getInfoArray = function (info) {
  return _(info || {}).map(function (value, type) {
    value.type = type;
    return value;
  })
}

formatTraceLine = function (oldLine) {
  if(oldLine) {
    //parts => ['functionName', 'url:line:col']
    var parts = oldLine.split('@');

    // Sometimes stacktrace.js fails to parse IE8 errors
    // return the original trace line
    if(parts.length < 2) {
      return oldLine;
    }

    // merge all parts except the first if there are more than a '@' characters
    // I'm not sure whether this can ever happen with Stacktrace.js
    if(parts.length > 2) {
      var messageParts = parts.slice(1);
      parts.splice(0, 1);
      parts[1] = messageParts.join('@');
    }

    var line = '    at ';
    var origin = getCurrentOrigin();
    var path = parts[1].replace(origin + '/', '', 'gi');
    if(parts[0] === '{anonymous}()') {
      line += path;
    } else {
      line += parts[0] + ' ('+path+')';
    }
    return line;
  }
}

getCurrentOrigin = function () {
  // Internet Explorer doesn't have window.location.origin
  return window.location.origin || window.location.protocol
  + window.location.hostname
  + window.location.port;
}

var filterRegExp = /\/packages\/zones\/assets\/|^Error$/;
stackFramesFilter = function (line) {
  return !line.match(filterRegExp);
}

getTime = function () {
  if(Kadira && Kadira.syncedDate) {
    return Kadira.syncedDate.getTime();
  } else {
    return (new Date().getTime());
  }
}
<|endoftext|>


<commit_before>/*
  FlagstoneJS v3.7.1
  (c) 2015-2017 Depth Development. http://depthdev.com
  License: MIT
*/
!function(e,t){"use strict";e.flagstone=function(n){function r(n){function r(){for(var e=0,t=k.length;e<t;e++)Math.random()<q&&k.splice(e,0,!1)}function a(){L.style.visibility="hidden"}function o(){L.style.visibility="visible"}function s(){var t=[w],n=0,r=O.length;for(M=[];n<r;n++){if(n<w)k[n]?(k[n].style.top=E+"px",k[n].style[z]=A*n+(n?C*n+E:E)+"px",Y&&(k[n].style.height=k[n].style.width),t[n]=O[n]+E,se(k[n],n),M.push([k[n]])):w>1&&(t[n]=A+E);else{var a=Math.min.apply(null,t),s=t.indexOf(a);k[n]?(k[n].style.top=a+C+"px",k[n].style[z]=A*s+(s?C*s+E:E)+"px",Y&&(k[n].style.height=k[n].style.width),t[s]+=O[n]+C,se(k[n],n),M[s].push(k[n])):w>1&&(t[s]+=A+C)}T=(Math.max.apply(null,t)||O[0]+E)+E,L.style.height=T+"px"}e.setTimeout(o)}function i(t){if(k.length){y=L.offsetWidth,y<b+(E?2*E:0)&&(y=b),D=Math.floor(y/b),w=D>x?x:D,A=y/w-(C*(w-1)+2*E)/w,O=[];for(var n=0,r=k.length;n<r;n++)k[n]&&(k[n].style.width=A+"px",k[n].style.marginTop="0px"),O.push(Y||!k[n]?A:k[n].offsetHeight);y===L.offsetWidth||t?s():i(!0),t||e.setTimeout(function(){i(!0)},H)}}function l(){var t=Date.now(),n=L.getElementsByTagName("img");n.length&&!function(){var r=e.setInterval(function(){for(var a=[],o=0,s=n.length;o<s;o++)a[o]=n[o].naturalHeight;(a.indexOf(0)===-1||t+Z<Date.now())&&(e.clearInterval(r),e.setTimeout(function(){i(!0)}))},G)}()}function g(t){if("keydown"!==t.type||13===t.keyCode||32===t.keyCode){for(var n=t.target;n&&!n.classList.contains(B);)n=n.parentElement;L.removeChild(n),e.MutationObserver||!ie&&!le||ce()}}function d(t){"keydown"===t.type&&13!==t.keyCode&&32!==t.keyCode||e.setTimeout(i,V)}function c(t){function n(){for(var t=0,n=M.length,r=0,a=0;t<n&&!g;t++)for(r=0,a=M[t].length;r<a;r++)g&&(i.push(M[t][r]),l.push(e.parseInt(M[t][r].style.marginTop,10)||0)),M[t][r]===o&&(g=!0)}function r(){for(var t=0,n=w,a=[];t<n;t++){var o=M[t][M[t].length-1],s=e.parseInt(o.style.top,10)+(e.parseInt(o.style.marginTop,10)||0)+o.offsetHeight+E;a.push(s)}var i=Math.max.apply(null,a);L.style.height=i+"px",ee=e[(te?"request":"cancel")+"AnimationFrame"](r)}function a(){function t(){for(var r=o.offsetHeight+s,g=r-a,d=0;d<n;d++)i[d].style.marginTop=g+l[d]+"px";re=e[(ae?"request":"cancel")+"AnimationFrame"](t)}var n=i.length,a=e.parseInt(i[0].style.top,10)-C+l[0];ae=!0,re=e.requestAnimationFrame(t),oe=e.setTimeout(function(){ae=!1,e.cancelAnimationFrame(re)},$),te=!0,ee=e.requestAnimationFrame(r),ne=e.setTimeout(function(){te=!1,e.cancelAnimationFrame(ee)},$)}for(var o=t;o&&!o.classList.contains(B);)o=o.parentElement;var s=e.parseInt(o.style.top,10)+(e.parseInt(o.style.marginTop,10)||0),i=[],l=[],g=!1;return n(),te=!1,e.cancelAnimationFrame(ee),e.clearTimeout(ne),ae=!1,e.cancelAnimationFrame(re),e.clearTimeout(oe),i.length?void a():(te=!0,ee=e.requestAnimationFrame(r),void(ne=e.setTimeout(function(){te=!1,e.cancelAnimationFrame(ee)},$)))}function m(e){"keydown"===e.type&&13!==e.keyCode&&32!==e.keyCode||c(e.target)}function f(){e.clearTimeout(ge),ge=e.setTimeout(i,j)}function v(){e.clearTimeout(de),de=e.setTimeout(ce)}function u(){e.removeEventListener("resize",f),t.head.removeChild(t.getElementById("flagstone-"+S+"-styles"))}function h(e){e.margin||0===e.margin?(E=e.margin,C=e.margin):(E=e.bedPadding||E,C=e.stonesMargin||C),b=e.minWidth||b,x=e.maxColumns||x,J=e.dragAndDrop===!0||e.dragAndDrop===!1?e.dragAndDrop:J,U=e.dropCallback||U,se=e.callback||se,ce()}var S=e.flagstone.index,p=n?n.nodeName?{elem:n}:n:{elem:t.getElementsByClassName("flagstone")[0]},L=p.elem,E=p.margin||0===p.margin?p.margin:p.bedPadding||0===p.bedPadding?p.bedPadding:10,y=0,T=0,b=p.minWidth||280,x=p.maxColumns||5,D=0,w=0,k=[],C=p.margin||0===p.margin?p.margin:p.stonesMargin||0===p.stonesMargin?p.stonesMargin:10,A=y/w-C*(w+1)/w,O=[],M=[],B="flagstone-"+S+"-bed__stone",F=p.flow,z=p.direction?p.direction.toLowerCase():"left",I=p.assignReverseZIndexes,P=p.random,q=p.spaceFrequency||.4,N=p.space,H=p.animationDuration||0,R=p.animationDuration/1e3,W=p.animationTimingFunction||"linear",_=p.heightAnimationDuration||0,X=p.heightAnimationDuration/1e3,Q=p.heightAnimationTimingFunction||"linear",j=p.resizeDelay||0===p.resizeDelay?p.resizeDelay:250,Y=p.square,Z=p.imagesLoadedQueryDuration||2500,G=p.imagesLoadedQueryFrequency||100,J=p.dragAndDrop,K=p.dragAndDropAutoDelay,U=p.dropCallback||function(){return!0},V=p.eventResetDelay||0,$=p.eventResizeHeightDuration||0,ee=null,te=!1,ne=null,re=null,ae=!1,oe=null,se=p.callback||function(){},ie=p.watch!==!1,le=p.watchAll,ge=null,de=null,ce=null,me={targetElem:null,dragStone:null,targetStone:null,targetStoneOverLeft:0,autoDropTimer:null,autoDrop:function(){me.targetStone.classList.contains(B)&&(me.targetStoneOverLeft?me.dragStone!==me.targetStone.previousElementSibling&&(me.targetStone.parentElement.insertBefore(me.dragStone,me.targetStone),me.targetStone.classList.remove("flagstone-left"),me.targetStone.classList.remove("flagstone-dragover")):me.dragStone!==me.targetStone.nextElementSibling&&(me.targetStone.parentElement.insertBefore(me.dragStone,me.targetStone.nextElementSibling),me.targetStone.classList.remove("flagstone-right"),me.targetStone.classList.remove("flagstone-dragover")),e.clearTimeout(me.autoDropTimer),me.autoDropTimer=e.setTimeout(me.autoDrop,K))},clear:function(){me.dragStone&&(me.dragStone.classList.remove("flagstone-drag"),me.dragStone=null),me.targetStone&&(me.targetStoneOverLeft=0,me.targetStone.classList.remove("flagstone-dragover"),me.targetStone.classList.remove("flagstone-left"),me.targetStone.classList.remove("flagstone-right"),me.targetStone=null),L.classList.remove("flagstone-dragover")},getTargetElem:function(e){for(me.targetElem=e.target instanceof HTMLElement?e.target:e.target.parentElement;me.targetElem&&!me.targetElem.classList.contains("flagstone-drag-handle");)me.targetElem=me.targetElem.parentElement;if(me.targetElem)for(me.dragStone=me.targetElem;me.dragStone&&!me.dragStone.classList.contains(B);)me.dragStone=me.dragStone.parentElement},mousedown:function(e){me.getTargetElem(e)},dragStart:function(e){return!!me.targetElem&&(me.dragStone.classList.add("flagstone-drag"),void(e.dataTransfer&&e.dataTransfer.setData("text",this.id)))},touchStart:function(e){me.getTargetElem(e),me.dragStart(e)},dragEnter:function(t){t.preventDefault(),t.stopPropagation(),this!==me.dragStone&&this!==me.targetStone&&this!==L&&(e.clearTimeout(me.autoDropTimer),me.autoDropTimer=e.setTimeout(me.autoDrop,K))},touchMove:function(e){if(!me.dragStone)return!1;e.preventDefault(),e.stopPropagation();for(var n=t.elementFromPoint(e.touches[0].clientX,e.touches[0].clientY),r=n;r&&!r.classList.contains(B);)r=r.parentElement;r?(L.classList.remove("flagstone-dragover"),me.targetStoneOverLeft=r.getBoundingClientRect().left+r.offsetWidth/2>e.touches[0].clientX,me.targetStone&&me.targetStone!==r&&(me.targetStone.classList.remove("flagstone-dragover"),me.targetStone.classList.remove("flagstone-left"),me.targetStone.classList.remove("flagstone-right")),me.targetStone=r,me.targetStone.classList.contains("flagstone-lock")||(me.targetStone.classList.add("flagstone-dragover"),me.targetStoneOverLeft?(me.targetStone.classList.remove("flagstone-right"),me.targetStone.classList.add("flagstone-left")):(me.targetStone.classList.remove("flagstone-left"),me.targetStone.classList.add("flagstone-right")))):n===L&&(me.targetStone.classList.remove("flagstone-dragover"),me.targetStone.classList.remove("flagstone-left"),me.targetStone.classList.remove("flagstone-right"),L.classList.add("flagstone-dragover"),me.targetStone=L)},dragOver:function(e){return!!me.dragStone&&(e.preventDefault(),e.stopPropagation(),e.dataTransfer.dropEffect="move",void(this!==me.dragStone&&this.classList.contains(B)?(me.targetStone=this,me.targetStone.classList.add("flagstone-dragover"),me.targetStoneOverLeft=this.getBoundingClientRect().left+this.offsetWidth/2>e.clientX,me.targetStoneOverLeft?(me.targetStone.classList.remove("flagstone-right"),me.targetStone.classList.add("flagstone-left")):(me.targetStone.classList.remove("flagstone-left"),me.targetStone.classList.add("flagstone-right")),this.classList.remove("flagstone-dragover"),me.targetStone!==L&&L.classList.remove("flagstone-dragover")):this===L&&this.classList.add("flagstone-dragover")))},dragEnd:function(){me.clear()},touchEnd:function(){me.dragStone&&me.targetStone&&!me.targetStone.classList.contains("flagstone-lock")&&U(me.dropStone,me.targetStone)&&(me.targetStone===L?L.appendChild(me.dragStone):me.targetStoneOverLeft?L.insertBefore(me.dragStone,me.targetStone):L.insertBefore(me.dragStone,me.targetStone.nextElementSibling)),me.clear()},dragLeave:function(){me.targetStone&&(me.targetStone.classList.remove("flagstone-dragover"),me.targetStone.classList.remove("flagstone-left"),me.targetStone.classList.remove("flagstone-right"),L.classList.remove("flagstone-dragover"))},drop:function(t){if(!me.dragStone)return!1;if(t.stopPropagation(),e.clearTimeout(me.autoDropTimer),me.dragStone!==this&&(this.classList.contains(B)||this===L)){if(me.targetStone=this,me.targetStone===L){if(!U(me.dragStone,me.targetStone))return me.clear(),!1;me.targetStone.appendChild(me.dragStone)}else if(me.targetStoneOverLeft){if(!U(me.dragStone,me.targetStone))return me.clear(),!1;me.targetStone.parentElement.insertBefore(me.dragStone,me.targetStone)}else{if(!U(me.dragStone,me.targetStone.nextElementSibling))return me.clear(),!1;me.targetStone.parentElement.insertBefore(me.dragStone,me.targetStone.nextElementSibling)}me.clear(),e.MutationObserver||!ie&&!le||ce()}return!1}};return ce=function(){k=Array.prototype.slice.call(L.children);for(var t=0,n=k.length;t<n;t++)k[t].classList.add(B),I&&(k[t].style.zIndex=n-t);for(t=0;t<n;t++)k[t].setAttribute("draggable","false"),k[t].removeEventListener("mousedown",me.mousedown),k[t].removeEventListener("dragstart",me.dragStart),k[t].removeEventListener("touchstart",me.touchStart),k[t].removeEventListener("touchmove",me.touchMove),k[t].removeEventListener("dragover",me.dragOver),k[t].removeEventListener("dragleave",me.dragLeave),k[t].removeEventListener("dragend",me.dragEnd),k[t].removeEventListener("touchend",me.touchEnd),k[t].removeEventListener("drop",me.drop),k[t].removeEventListener("touchend",me.drop),k[t].removeEventListener("dragenter",me.dragEnter);if(L.removeEventListener("dragover",me.dragOver),L.removeEventListener("drop",me.drop),J){for(t=0;t<n;t++)k[t].classList.contains("flagstone-lock")||(k[t].setAttribute("draggable","true"),k[t].addEventListener("mousedown",me.mousedown),k[t].addEventListener("dragstart",me.dragStart),k[t].addEventListener("touchstart",me.touchStart),k[t].addEventListener("touchmove",me.touchMove),k[t].addEventListener("dragover",me.dragOver),k[t].addEventListener("dragleave",me.dragLeave),k[t].addEventListener("dragend",me.dragEnd),k[t].addEventListener("touchend",me.touchEnd),k[t].addEventListener("drop",me.drop),k[t].addEventListener("touchend",me.drop),K&&k[t].addEventListener("dragenter",me.dragEnter),k[t].getElementsByClassName("flagstone-drag-handle").length||k[t].classList.add("flagstone-drag-handle"));L.addEventListener("dragover",me.dragOver),L.addEventListener("drop",me.drop)}(P||N)&&(P&&k.sort(function(){return.5-Math.random()}),N&&r());var a=L.getElementsByClassName("flagstone-remove");for(t=0,n=a.length;t<n;t++)a[t].removeEventListener("click",g),a[t].addEventListener("click",g),a[t].removeEventListener("keydown",g),a[t].addEventListener("keydown",g);for(a=L.getElementsByClassName("flagstone-reset"),t=0,n=a.length;t<n;t++)a[t].removeEventListener("click",d),a[t].addEventListener("click",d),a[t].removeEventListener("keydown",d),a[t].addEventListener("keydown",d);for(a=L.getElementsByClassName("flagstone-resize-height"),t=0,n=a.length;t<n;t++)a[t].removeEventListener("click",m),a[t].addEventListener("click",m),a[t].removeEventListener("keydown",m),a[t].addEventListener("keydown",m);i(),H&&e.setTimeout(l,H),e.setTimeout(function(){i(!0)},H)},function(){if(a(),L.classList.add("flagstone-"+S+"-bed"),!t.getElementById("flagstone-"+S+"-styles")){var n=".flagstone-"+S+"-bed{box-sizing:border-box;list-style-type:none;overflow:hidden;position:relative;min-width:"+(b+2*E)+"px;}",r=".flagstone-"+S+"-bed__stone{box-sizing:border-box;position:absolute;top:0px;"+z+":0px;margin:0;}",o=".flagstone-"+S+"-bed__stone{transition:top "+R+"s "+W+","+z+" "+R+"s "+W+(F?",width "+R+"s "+W:"")+(_?",height "+X+"s "+Q:"")+";}",s=n+r+o,i=t.createElement("style");i.type="text/css",i.id="flagstone-"+S+"-styles",i.appendChild(t.createTextNode(s)),t.head.appendChild(i)}if(ce(),e.removeEventListener("resize",f),e.addEventListener("resize",f),(ie||le)&&e.MutationObserver){var l=new MutationObserver(v);l.observe(L,{childList:!0,subtree:le})}}(),{adjust:h,destroy:u,resizeHeight:c,hide:a,reset:f,hardReset:ce}}return e.flagstone.index++,new r(n)},e.flagstone.index=-1}(window,document);<commit_msg>Delete flagstone-3.7.1.min.js<commit_after><|endoftext|>


<commit_before>'use strict';

var execAbort = require('../execAbort');
var projectMeta = require('../projectMeta');
var fs = require('fs-extra');
var hbs = require('handlebars');
var path = require('path');
var getTemplates = require('../tasks/getTemplates');
var renameTemplate = require('../tasks/renameTemplate');
var trackCommand = require('../tasks/trackCommand');
var PleasantProgress = require('pleasant-progress');
var chalk = require('chalk');
var checkEnvironment = require('../tasks/checkEnvironment');
var spawnPromise = require('superspawn').spawn;
var execPromise = require('child-process-promise').exec;
var {question} = require('readline-sync');
var projectMeta = require('../projectMeta');
require('shelljs/global');
var getAppNames = require('../tasks/getAppNames');

var serverName = getAppNames.server();
var clientName = getAppNames.client();

function normalizeOption(option) {
  if (option === 'mongodb') {
    return 'mongo';
  }
  if (option === 'postgres') {
    return 'postgresql';
  }
  return option;
}

function prepareFigTemplate(name, option) {
  var figDatabase = null;
  var figPort = 0;
  var figIsMysql = false;

  if (option !== 'disk'){
    figDatabase = option;
  }

  switch (option) {
    case 'mysql':
      figPort = 3306;
      figIsMysql = true;
    break;
    case 'postgresql':
      figPort = 5432;
      figDatabase = 'postgres';
    break;
    case 'mongo':
      figPort = 27017;
      break;
    case 'redis':
      figPort = 6379;
      figDatabase = 'redis';
    break;
  }

  var figVariables = { database: figDatabase, port: figPort, isMysql: figIsMysql, serverName: serverName};
  return prepareTemplate(name, figVariables);
}

function prepareTemplate(name, variables) {
  var template = fs.readFileSync(path.join(projectMeta.sanePath(), 'templates', name), 'utf8');
  template = hbs.compile(template);
  return template(variables);
}

/*
 * Make sure the executed commands work with docker enabled/disabled
 */
function dockerExec(cmd, runsWithDocker, silent, dryRun) {
  if (silent === undefined) {
    silent = false;
  }

  if (dryRun === undefined) {
    dryRun = false;
  }

  var options = { stdio: 'inherit', env: process.env };
  if (silent) {
    options = { env: process.env };
  }

  var cmdMain;
  var cmdArgs;
  var cmds = cmd.split(' ');

  if (runsWithDocker) {
    cmdMain = 'fig';
    cmdArgs = ['run', serverName].concat(cmds);
  } else {
    cmdMain = cmds[0];
    cmdArgs = cmds.slice(1);
    //Note(markus): this assumes that dockerExec is only used for executing serverCommands
    options.cwd = serverName;
  }

  if (dryRun) {

    //simulate an npm i --save dry-run, since npm does not currently have that
    if (cmds[0] === 'npm' &&
    (cmds[1] === 'i' || cmds[1] === 'install')) {
      var filename = path.join(serverName, 'package.json');
      var packageInfo = fs.readFileSync(filename);
      var content = JSON.parse(packageInfo);
      for (var i = 2; i <= cmds.length; i++) {
        if (cmds[i] !== '--save') {
          content.dependencies[cmds[i]] = '*';
        }
      };
      //have to return a promise
      return new Promise(
        function(resolve, reject) {
          fs.writeFileSync(filename, JSON.stringify(content, null, 2));
          resolve();
      });
    }

    //return an empty promise
    return new Promise(
      function(resolve, reject) {
        resolve();
    });
  } else {
    return spawnPromise(cmdMain, cmdArgs, options);
  }
}

function getMigrateType(database) {
  var migrateType = 'safe';
  switch (database) {
    case 'mysql':
      migrateType = 'alter';
      break;
    case 'postgresql':
      migrateType = 'alter';
      break;
    case 'mongo':
      migrateType = 'safe';
      break;
    case 'redis':
      migrateType = 'safe';
      break;
  }

  return migrateType;
}

function isWrongProjectName(name) {
  if(name.includes('.') && name.length > 1){
    return true;
  }
  return false;
}

function cleanUpSails(options, silent){
  //clean up sails to be API only
  fs.removeSync(path.join('server', 'views'));
  fs.removeSync(path.join('server', 'tasks'));
  fs.removeSync(path.join('server', 'Gruntfile.js'));

  var sailsPackages = ['grunt', 'ejs', 'grunt-contrib-clean', 'grunt-contrib-concat',
  'grunt-contrib-copy', 'grunt-contrib-cssmin', 'grunt-contrib-jst', 'grunt-contrib-less',
  'grunt-contrib-uglify', 'grunt-contrib-watch', 'grunt-sails-linker', 'grunt-sync'];

  return dockerExec(`npm rm ${sailsPackages.join(' ')} --save`, options.docker, silent);
}

module.exports = async function newProject(name, options, leek) {
  var ember;
  //use global ember-cli if exists, otherwise the local one
  //TODO(markus): If global version differs from local one, then ask which one to use
  var localEmber = path.join(__dirname, '..', '..', 'node_modules', 'ember-cli', 'bin', 'ember');
  if (!checkEnvironment.emberExists()) {
    ember = localEmber;
  } else {
    ember = 'ember';
    //regex to get semantic version string
    var semVer = new RegExp(/([0-9]+\.[0-9]+\.[0-9]+)/);
    //Gets the first version number that the global ember spits out.
    var emberVersion = exec(`${ember} version`, { silent: true }).output.match(semVer)[0];

    //Note(markus): Somehow do not seem to be able to get access to the globally installed ember-cli package.json
    // var globalEmber = path.relative(process.cwd(), path.join(exec('npm root -g', { silent: true }).output, 'ember-cli', 'package.json'));
    // var emberVersion = require(globalEmber).version;

    //take the local ember version from the package.json. Much faster
    var localEmberVersion = require(path.join(__dirname, '..', '..', 'node_modules', 'ember-cli', 'package.json')).version;
    //compare the different ember versions
    if ( emberVersion !== localEmberVersion){
      var answer = question(chalk.gray(`Detected different versions for sane's locally installed ember-cli (${localEmberVersion}) and your global one (${emberVersion}). Want to use sane's one? (y/n):`) + '  (y) ') || 'y';
      if (answer === 'y' || answer === 'Y') {
        ember = localEmber;
      }
    }
  }

  var installMsg;
  //--docker is set
  if (options.docker) {
    installMsg = 'Setting up Sails project and downloading latest Docker Containers.';
    if (!checkEnvironment.dockerExists()) {
      console.log('sane requires the latest docker/boot2docker/fig to be installed. Check https://github.com/artificialio/sane/blob/master/README.md for more details.');
      console.log('Exitting now.');
      process.exit(1);
    }
  } else {
    installMsg = 'Setting up Sails project locally.';
    if (!checkEnvironment.sailsExists()) {
      console.log('sane requires the latest sails to be installed. Run npm install -g sails.');
      console.log('Exitting now.');
      process.exit(1);
    }
  }

  if(isWrongProjectName(name)) {
    throw new Error(`Sane currently does not support a projectname of '${name}'.`);
  }

  options.database = normalizeOption(options.database);
  var silent = true;
  if (options.verbose) {
    silent = false;
  }

  //All checks are done, log command to analytics, then start command
  //when running tests leek will be undefined
  if (typeof leek !== 'undefined') {
    trackCommand(`new ${name}`, options, leek);
  }

  console.log(`Sane version: ${projectMeta.version()}\n`);

  //if . is passed it creates a new project in the current folder with the name taken from the parent
  if (name !== '.') {
    //Creates the new folder
    execAbort.sync('mkdir ' + name,
      'Error: Creating a new folder failed. Check if the folder \'' + name + '\' already exists.',
      silent);
    //change directories into projectRoot
    cd(name);
  }

  var projectName = path.basename(process.cwd());

  fs.writeFileSync(path.join('fig.yml'), prepareFigTemplate('fig.yml', options.database));
  fs.writeFileSync(path.join('package.json'), prepareTemplate('package.json', { name: projectName, version: projectMeta.version() }));

  var cliConfig = {};
  for (var opt in options) {
    //exclude properties that are not cli options
    if (options.hasOwnProperty(opt) &&
      !opt.startsWith('_') &&
      ['commands', 'options', 'parent'].indexOf(opt) === -1) {
      cliConfig[opt] = options[opt];
  }

  cliConfig['apps'] = [clientName, serverName];
  cliConfig['disableAnalytics'] = false;
}

  //creating a default .sane-cli based on the parameters used in the new command
  fs.writeFileSync(path.join('.sane-cli'), JSON.stringify(cliConfig, null, 2));

  mkdir(serverName);

  //TODO(markus): If we use spawn with stdio inherit we can print the proper output for fog
  //should also fix the ember-cli output
  console.log(chalk.green(installMsg));

  if (!options.docker) {
    process.stdout.write(`sails version: ${exec('sails version', { silent: true }).output}`);
  } else {
    process.stdout.write(`sails version: ${exec('fig run server sails version', { silent: true }).output}`);
  }

  await dockerExec('sails new .', options.docker);

  if (!options.skipNpm) {
    var progress = new PleasantProgress();
    progress.start(chalk.green('Installing Sails packages for tooling via npm.'));
  }

  var sailsPackages = ['sails-generate-ember-blueprints', 'lodash@^2.4.1',
  'morgan', 'pluralize', `sails-${options.database}`];
  await dockerExec(`npm i ${sailsPackages.join(' ')} --save`, options.docker, silent, options.skipNpm);
  await dockerExec('sails generate ember-blueprints', options.docker, silent, options.skipNpm);

  if (!options.skipNpm) {
    progress.stop();
    console.log(chalk.green('Installed Sails packages for tooling via npm.') + '\n');
  } else {
    console.log(chalk.yellow('Warning: skipping npm tooling so you have to manually run the sails generator:'));
    console.log(chalk.yellow(`'sails-generate-ember-blueprints' (${chalk.underline('https://github.com/mphasize/sails-generate-ember-blueprints')})\n`));
  }

  //Creating new ember project
  console.log(chalk.green('Setting up Ember project locally.'));

  var emberArgs = ['new', clientName, '--skip-git'];

  if (options.skipNpm) {
    emberArgs.push('--skip-npm');
  }

  if (options.skipBower) {
    emberArgs.push('--skip-bower');
  }

  process.stdout.write('ember-cli ');
  await spawnPromise(ember, emberArgs, { stdio: 'inherit', env: process.env });

  progress.start(chalk.green('Running tooling scrips for Sane.'));

  //copy over template files
  var templates = getTemplates(projectMeta.sanePath());
  for (var i = 0; i < templates.length; i++) {
    var templateInPath = path.join(projectMeta.sanePath(), 'templates', templates[i]);
    var templateOutPath = renameTemplate(templates[i]);
    if (templates[i].indexOf('_models') > -1) {
      fs.writeFileSync(templateOutPath, prepareTemplate(templates[i],
        { database: options.database, migrateType: getMigrateType(options.database) }));
    } else if (templates[i].indexOf('_connections') > -1) {
      var host = 'localhost';
      if (options.docker) {
        host = 'db';
      }
      fs.writeFileSync(templateOutPath, prepareTemplate(templates[i],
        { host: host }));
    } else {
      fs.outputFileSync(templateOutPath, fs.readFileSync(templateInPath));
    }
  }

  await cleanUpSails(options, silent);

  await spawnPromise('npm', ['install'], { env: process.env });

  progress.stop();
  console.log(chalk.green('Sane Project \'' + projectName + '\' successfully created.'));
};
<commit_msg>Fix 'sane new --skip-npm'<commit_after>'use strict';

var execAbort = require('../execAbort');
var projectMeta = require('../projectMeta');
var fs = require('fs-extra');
var hbs = require('handlebars');
var path = require('path');
var getTemplates = require('../tasks/getTemplates');
var renameTemplate = require('../tasks/renameTemplate');
var trackCommand = require('../tasks/trackCommand');
var PleasantProgress = require('pleasant-progress');
var chalk = require('chalk');
var checkEnvironment = require('../tasks/checkEnvironment');
var spawnPromise = require('superspawn').spawn;
var execPromise = require('child-process-promise').exec;
var {question} = require('readline-sync');
var projectMeta = require('../projectMeta');
require('shelljs/global');
var getAppNames = require('../tasks/getAppNames');

var serverName = getAppNames.server();
var clientName = getAppNames.client();
var progress = new PleasantProgress();

function normalizeOption(option) {
  if (option === 'mongodb') {
    return 'mongo';
  }
  if (option === 'postgres') {
    return 'postgresql';
  }
  return option;
}

function prepareFigTemplate(name, option) {
  var figDatabase = null;
  var figPort = 0;
  var figIsMysql = false;

  if (option !== 'disk'){
    figDatabase = option;
  }

  switch (option) {
    case 'mysql':
      figPort = 3306;
      figIsMysql = true;
    break;
    case 'postgresql':
      figPort = 5432;
      figDatabase = 'postgres';
    break;
    case 'mongo':
      figPort = 27017;
      break;
    case 'redis':
      figPort = 6379;
      figDatabase = 'redis';
    break;
  }

  var figVariables = { database: figDatabase, port: figPort, isMysql: figIsMysql, serverName: serverName};
  return prepareTemplate(name, figVariables);
}

function prepareTemplate(name, variables) {
  var template = fs.readFileSync(path.join(projectMeta.sanePath(), 'templates', name), 'utf8');
  template = hbs.compile(template);
  return template(variables);
}

/*
 * Make sure the executed commands work with docker enabled/disabled
 */
function dockerExec(cmd, runsWithDocker, silent, dryRun) {
  if (silent === undefined) {
    silent = false;
  }

  if (dryRun === undefined) {
    dryRun = false;
  }

  var options = { stdio: 'inherit', env: process.env };
  if (silent) {
    options = { env: process.env };
  }

  var cmdMain;
  var cmdArgs;
  var cmds = cmd.split(' ');

  if (runsWithDocker) {
    cmdMain = 'fig';
    cmdArgs = ['run', serverName].concat(cmds);
  } else {
    cmdMain = cmds[0];
    cmdArgs = cmds.slice(1);
    //Note(markus): this assumes that dockerExec is only used for executing serverCommands
    options.cwd = serverName;
  }

  if (dryRun) {

    //simulate an npm i --save dry-run, since npm does not currently have that
    if (cmds[0] === 'npm' &&
    (cmds[1] === 'i' || cmds[1] === 'install')) {
      var filename = path.join(serverName, 'package.json');
      var packageInfo = fs.readFileSync(filename);
      var content = JSON.parse(packageInfo);
      for (var i = 2; i <= cmds.length; i++) {
        if (cmds[i] !== '--save') {
          content.dependencies[cmds[i]] = '*';
        }
      };
      //have to return a promise
      return new Promise(
        function(resolve, reject) {
          fs.writeFileSync(filename, JSON.stringify(content, null, 2));
          resolve();
      });
    }

    //return an empty promise
    return new Promise(
      function(resolve, reject) {
        resolve();
    });
  } else {
    return spawnPromise(cmdMain, cmdArgs, options);
  }
}

function getMigrateType(database) {
  var migrateType = 'safe';
  switch (database) {
    case 'mysql':
      migrateType = 'alter';
      break;
    case 'postgresql':
      migrateType = 'alter';
      break;
    case 'mongo':
      migrateType = 'safe';
      break;
    case 'redis':
      migrateType = 'safe';
      break;
  }

  return migrateType;
}

function isWrongProjectName(name) {
  if(name.includes('.') && name.length > 1){
    return true;
  }
  return false;
}

function cleanUpSails(options, silent){
  //clean up sails to be API only
  fs.removeSync(path.join('server', 'views'));
  fs.removeSync(path.join('server', 'tasks'));
  fs.removeSync(path.join('server', 'Gruntfile.js'));

  var sailsPackages = ['grunt', 'ejs', 'grunt-contrib-clean', 'grunt-contrib-concat',
  'grunt-contrib-copy', 'grunt-contrib-cssmin', 'grunt-contrib-jst', 'grunt-contrib-less',
  'grunt-contrib-uglify', 'grunt-contrib-watch', 'grunt-sails-linker', 'grunt-sync'];

  return dockerExec(`npm rm ${sailsPackages.join(' ')} --save`, options.docker, silent);
}

module.exports = async function newProject(name, options, leek) {
  var ember;
  //use global ember-cli if exists, otherwise the local one
  //TODO(markus): If global version differs from local one, then ask which one to use
  var localEmber = path.join(__dirname, '..', '..', 'node_modules', 'ember-cli', 'bin', 'ember');
  if (!checkEnvironment.emberExists()) {
    ember = localEmber;
  } else {
    ember = 'ember';
    //regex to get semantic version string
    var semVer = new RegExp(/([0-9]+\.[0-9]+\.[0-9]+)/);
    //Gets the first version number that the global ember spits out.
    var emberVersion = exec(`${ember} version`, { silent: true }).output.match(semVer)[0];

    //Note(markus): Somehow do not seem to be able to get access to the globally installed ember-cli package.json
    // var globalEmber = path.relative(process.cwd(), path.join(exec('npm root -g', { silent: true }).output, 'ember-cli', 'package.json'));
    // var emberVersion = require(globalEmber).version;

    //take the local ember version from the package.json. Much faster
    var localEmberVersion = require(path.join(__dirname, '..', '..', 'node_modules', 'ember-cli', 'package.json')).version;
    //compare the different ember versions
    if ( emberVersion !== localEmberVersion){
      var answer = question(chalk.gray(`Detected different versions for sane's locally installed ember-cli (${localEmberVersion}) and your global one (${emberVersion}). Want to use sane's one? (y/n):`) + '  (y) ') || 'y';
      if (answer === 'y' || answer === 'Y') {
        ember = localEmber;
      }
    }
  }

  var installMsg;
  //--docker is set
  if (options.docker) {
    installMsg = 'Setting up Sails project and downloading latest Docker Containers.';
    if (!checkEnvironment.dockerExists()) {
      console.log('sane requires the latest docker/boot2docker/fig to be installed. Check https://github.com/artificialio/sane/blob/master/README.md for more details.');
      console.log('Exitting now.');
      process.exit(1);
    }
  } else {
    installMsg = 'Setting up Sails project locally.';
    if (!checkEnvironment.sailsExists()) {
      console.log('sane requires the latest sails to be installed. Run npm install -g sails.');
      console.log('Exitting now.');
      process.exit(1);
    }
  }

  if(isWrongProjectName(name)) {
    throw new Error(`Sane currently does not support a projectname of '${name}'.`);
  }

  options.database = normalizeOption(options.database);
  var silent = true;
  if (options.verbose) {
    silent = false;
  }

  //All checks are done, log command to analytics, then start command
  //when running tests leek will be undefined
  if (typeof leek !== 'undefined') {
    trackCommand(`new ${name}`, options, leek);
  }

  console.log(`Sane version: ${projectMeta.version()}\n`);

  //if . is passed it creates a new project in the current folder with the name taken from the parent
  if (name !== '.') {
    //Creates the new folder
    execAbort.sync('mkdir ' + name,
      'Error: Creating a new folder failed. Check if the folder \'' + name + '\' already exists.',
      silent);
    //change directories into projectRoot
    cd(name);
  }

  var projectName = path.basename(process.cwd());

  fs.writeFileSync(path.join('fig.yml'), prepareFigTemplate('fig.yml', options.database));
  fs.writeFileSync(path.join('package.json'), prepareTemplate('package.json', { name: projectName, version: projectMeta.version() }));

  var cliConfig = {};
  for (var opt in options) {
    //exclude properties that are not cli options
    if (options.hasOwnProperty(opt) &&
      !opt.startsWith('_') &&
      ['commands', 'options', 'parent'].indexOf(opt) === -1) {
      cliConfig[opt] = options[opt];
  }

  cliConfig['apps'] = [clientName, serverName];
  cliConfig['disableAnalytics'] = false;
}

  //creating a default .sane-cli based on the parameters used in the new command
  fs.writeFileSync(path.join('.sane-cli'), JSON.stringify(cliConfig, null, 2));

  mkdir(serverName);

  //TODO(markus): If we use spawn with stdio inherit we can print the proper output for fog
  //should also fix the ember-cli output
  console.log(chalk.green(installMsg));

  if (!options.docker) {
    process.stdout.write(`sails version: ${exec('sails version', { silent: true }).output}`);
  } else {
    process.stdout.write(`sails version: ${exec('fig run server sails version', { silent: true }).output}`);
  }

  await dockerExec('sails new .', options.docker);

  if (!options.skipNpm) {
    progress.start(chalk.green('Installing Sails packages for tooling via npm.'));
  }

  var sailsPackages = ['sails-generate-ember-blueprints', 'lodash@^2.4.1',
  'morgan', 'pluralize', `sails-${options.database}`];
  await dockerExec(`npm i ${sailsPackages.join(' ')} --save`, options.docker, silent, options.skipNpm);
  await dockerExec('sails generate ember-blueprints', options.docker, silent, options.skipNpm);

  if (!options.skipNpm) {
    progress.stop();
    console.log(chalk.green('Installed Sails packages for tooling via npm.') + '\n');
  } else {
    console.log(chalk.yellow('Warning: skipping npm tooling so you have to manually run the sails generator:'));
    console.log(chalk.yellow(`'sails-generate-ember-blueprints' (${chalk.underline('https://github.com/mphasize/sails-generate-ember-blueprints')})\n`));
  }

  //Creating new ember project
  console.log(chalk.green('Setting up Ember project locally.'));

  var emberArgs = ['new', clientName, '--skip-git'];

  if (options.skipNpm) {
    emberArgs.push('--skip-npm');
  }

  if (options.skipBower) {
    emberArgs.push('--skip-bower');
  }

  process.stdout.write('ember-cli ');
  await spawnPromise(ember, emberArgs, { stdio: 'inherit', env: process.env });

  progress.start(chalk.green('Running tooling scrips for Sane.'));

  //copy over template files
  var templates = getTemplates(projectMeta.sanePath());
  for (var i = 0; i < templates.length; i++) {
    var templateInPath = path.join(projectMeta.sanePath(), 'templates', templates[i]);
    var templateOutPath = renameTemplate(templates[i]);
    if (templates[i].indexOf('_models') > -1) {
      fs.writeFileSync(templateOutPath, prepareTemplate(templates[i],
        { database: options.database, migrateType: getMigrateType(options.database) }));
    } else if (templates[i].indexOf('_connections') > -1) {
      var host = 'localhost';
      if (options.docker) {
        host = 'db';
      }
      fs.writeFileSync(templateOutPath, prepareTemplate(templates[i],
        { host: host }));
    } else {
      fs.outputFileSync(templateOutPath, fs.readFileSync(templateInPath));
    }
  }

  await cleanUpSails(options, silent);
  if (!options.skipNpm) {
    await spawnPromise('npm', ['install'], { env: process.env });
  }

  progress.stop();
  console.log(chalk.green('Sane Project \'' + projectName + '\' successfully created.'));
};
<|endoftext|>