<commit_before>var fs = require('fs'),
    os = require('os'),
    request = require('request'),
    ncp = require('ncp').ncp,
    path = require('path'),
    shelljs = require('shelljs/global'),
    unzip = require('unzip'),
    argv = require('optimist').argv,
    colors = require('colors'),
    spawn = require('child_process').spawn,
    Q = require('q'),
    IonicProject = require('../ionic'),
    IonicProject = require('./project'),
    IonicTask = require('./task').IonicTask;
    IonicStats = require('./stats').IonicStats;

fs.mkdirParent = function(dirPath, mode, callback) {
  //Call the standard fs.mkdir
  fs.mkdir(dirPath, mode, function(error) {
    //When it fail in this way, do the custom steps
    if (error && error.errno === 34) {
      //Create all the parents recursively
      fs.mkdirParent(path.dirname(dirPath), mode, callback);
      //And then the directory
      fs.mkdirParent(dirPath, mode, callback);
    }
    //Manually run the callback since we used our own callback to do all these
    callback && callback(error);
  });
};

var IonicStartTask = function() {
}

// The URL for the cordova wrapper project
IonicStartTask.WRAPPER_REPO_NAME = 'ionic-app-base';

IonicStartTask.HELP_LINE = 'Start a new Ionic project with the given name.';

IonicStartTask.prototype = new IonicTask();

IonicStartTask.prototype._printUsage = function() {
  process.stderr.write('\nUsage: ionic start appName [starterProject(blank,tabs,sidemenu)]\n');
};

IonicStartTask.prototype.run = function(ionic) {
  if(argv._.length < 2) {
    ionic.fail('No app name specified, exiting.');
  }

  // Grab the name of the app
  this.appName = argv._[1];

  // Grab the target path from the command line, or use this as the app name
  var targetPathName = this.appName;

  var starterProject = argv._[2] || 'tabs';

  this.targetPath = path.resolve(this.appName);

  // Make sure to create this, or ask them if they want to override it
  if(this._checkTargetPath() === false) {
    process.stderr.write('\nExiting.\n');
    process.exit(1);
  }

  console.log('Creating Ionic app in folder', this.targetPath, 'based on', starterProject.info.bold, 'project');

  fs.mkdirSync(this.targetPath);

  this._fetchAndWriteSeed(starterProject.toLowerCase());
  this._writeConfig(ionic);

};

IonicStartTask.prototype._getStarterUrl = function(repo) {
  return 'https://github.com/driftyco/' + repo + '/archive/master.zip' ;
};

IonicStartTask.prototype._fetchWrapper = function() {
  var q = Q.defer();
  var self = this;

  var repoName = IonicStartTask.WRAPPER_REPO_NAME;
  var repoUrl = 'https://github.com/driftyco/' + IonicStartTask.WRAPPER_REPO_NAME + '/archive/master.zip';

  Ionic.fetchRepo(self.targetPath, repoName, repoUrl).then(function(repoFolderName) {
    cp('-R', self.targetPath + '/' + repoFolderName + '/.', self.targetPath);
    rm('-rf', self.targetPath + '/' + repoFolderName + '/');
    cd(self.targetPath);

    q.resolve(self.targetPath);
  }, function(err) {
    q.reject(err);
  });

  return q.promise;
};

IonicStartTask.prototype._fetchAndWriteSeed = function(projectType) {
  var self = this;

  // First, grab the wrapper project.

  var wrapperPromise = this._fetchWrapper();

  wrapperPromise.then(function() {
    // Get the starter project repo name:
    var repoName = 'ionic-starter-' + projectType;

    // The folder name the project will be downloaded and extracted to
    var repoFolderName = repoName + '-master';

    // Get the URL for the starter project repo:
    var repoUrl = self._getStarterUrl(repoName);

    Ionic.fetchRepo(self.targetPath, repoName, repoUrl).then(function(repoFolderName) {
      var npmQ = Q.defer();
      var gulpQ = Q.defer();
      var pluginQ = Q.defer();
      // Install dependencies for the starter project

      //Ionic.spawnPromise('npm', ['install', '--quiet']).then(function() {
        // Move the content of this repo into the www folder
        cp('-Rf', self.targetPath + '/' + repoFolderName + '/.', 'www');

        // Copy the root config file to the www folder
        cp(self.targetPath + '/config.xml', 'www');

        // Clean up start template folder
        rm('-rf', self.targetPath + '/' + repoFolderName + '/');

        console.log('Initializing cordova project.'.info.bold);
        exec('cordova plugin add org.apache.cordova.device && ' +
             'cordova plugin add org.apache.cordova.console && ' +
             'cordova plugin add org.apache.cordova.statusbar', function(err, stdout, stderr) {
          if(err) {
            pluginQ.reject(stderr);
          } else {
            pluginQ.resolve(stdout);
          }
        })

        pluginQ.promise.then(function() {
          self._printQuickHelp(self.appName);
        }, function(err) {
          Ionic.fail('Unable to add plugins. Perhaps your version of Cordova is too old. Try updating (npm install -g cordova), removing this project folder, and trying again.');
        });

        IonicStats.t('start', {});
      /*
      }).fail(function(err, stderr) {;
        Ionic.fail('Unable to install Ionic dependencies. Please make sure you\'ve installed cordova, and gulp globally by running:\nsudo npm install -g cordova gulp. Error:\n'.error.bold + err + '\n' + stderr);
      });
      */
    }).catch(function(err) {
      console.error('Error: Unable to fetch project: HTTP:'.error.bold,  err.statusCode, err);
      console.error('Valid project types are blank, tabs, or sidemenu (or see more on our starter page: http://ionicframework.com/getting-started/)'.error.bold);
      Ionic.fail('');
    });

  }, function(err) {
    Ionic.fail('Unable to grab wrapper project:'.error.bold, err);
  });

};

IonicStartTask.prototype._printQuickHelp = function(projectDirectory) {
  console.log('\nYour Ionic project is ready to go!'.green.bold);
  console.log('\nSome quick tips:');
  console.log('\n * cd into your project directory before running any of the following commands', ('(cd ' + projectDirectory + ')').info.bold);
  console.log('\n * Make sure to add a platform (ios or Android):', 'ionic platform add android [ios]'.info.bold);
  console.log('    Note: iOS development requires OS X currently'.small);
  console.log('\n * To build your project, run', 'ionic build [platform]'.info.bold);
  console.log('\n * To emulate your project in a simulator or emulator, run', 'ionic emulate [platform]'.info.bold);
  console.log('\n * To run your project on a device, run', 'ionic run [platform]'.info.bold);
  console.log('\n\nFor more help, visit the Ionic docs:', 'http://ionicframework.com/docs'.info.bold);
};

IonicStartTask.prototype._writeConfig = function(ionic) {
  var project = IonicProject.create();
  project.set('name', this.appName);
  project.save(this.targetPath);
};

IonicStartTask.prototype._checkTargetPath = function() {
  if(fs.existsSync(this.targetPath)) {
    process.stderr.write('The directory '.error.bold + this.targetPath + ' already exists, please remove it if you would like to create a new ionic project there.\n'.error.bold);
    return false;
  }
  return true;
};

exports.IonicStartTask = IonicStartTask;
<commit_msg>Don't copy config.xml into www anymore<commit_after>var fs = require('fs'),
    os = require('os'),
    request = require('request'),
    ncp = require('ncp').ncp,
    path = require('path'),
    shelljs = require('shelljs/global'),
    unzip = require('unzip'),
    argv = require('optimist').argv,
    colors = require('colors'),
    spawn = require('child_process').spawn,
    Q = require('q'),
    IonicProject = require('../ionic'),
    IonicProject = require('./project'),
    IonicTask = require('./task').IonicTask;
    IonicStats = require('./stats').IonicStats;

fs.mkdirParent = function(dirPath, mode, callback) {
  //Call the standard fs.mkdir
  fs.mkdir(dirPath, mode, function(error) {
    //When it fail in this way, do the custom steps
    if (error && error.errno === 34) {
      //Create all the parents recursively
      fs.mkdirParent(path.dirname(dirPath), mode, callback);
      //And then the directory
      fs.mkdirParent(dirPath, mode, callback);
    }
    //Manually run the callback since we used our own callback to do all these
    callback && callback(error);
  });
};

var IonicStartTask = function() {
}

// The URL for the cordova wrapper project
IonicStartTask.WRAPPER_REPO_NAME = 'ionic-app-base';

IonicStartTask.HELP_LINE = 'Start a new Ionic project with the given name.';

IonicStartTask.prototype = new IonicTask();

IonicStartTask.prototype._printUsage = function() {
  process.stderr.write('\nUsage: ionic start appName [starterProject(blank,tabs,sidemenu)]\n');
};

IonicStartTask.prototype.run = function(ionic) {
  if(argv._.length < 2) {
    ionic.fail('No app name specified, exiting.');
  }

  // Grab the name of the app
  this.appName = argv._[1];

  // Grab the target path from the command line, or use this as the app name
  var targetPathName = this.appName;

  var starterProject = argv._[2] || 'tabs';

  this.targetPath = path.resolve(this.appName);

  // Make sure to create this, or ask them if they want to override it
  if(this._checkTargetPath() === false) {
    process.stderr.write('\nExiting.\n');
    process.exit(1);
  }

  console.log('Creating Ionic app in folder', this.targetPath, 'based on', starterProject.info.bold, 'project');

  fs.mkdirSync(this.targetPath);

  this._fetchAndWriteSeed(starterProject.toLowerCase());
  this._writeConfig(ionic);

};

IonicStartTask.prototype._getStarterUrl = function(repo) {
  return 'https://github.com/driftyco/' + repo + '/archive/master.zip' ;
};

IonicStartTask.prototype._fetchWrapper = function() {
  var q = Q.defer();
  var self = this;

  var repoName = IonicStartTask.WRAPPER_REPO_NAME;
  var repoUrl = 'https://github.com/driftyco/' + IonicStartTask.WRAPPER_REPO_NAME + '/archive/master.zip';

  Ionic.fetchRepo(self.targetPath, repoName, repoUrl).then(function(repoFolderName) {
    cp('-R', self.targetPath + '/' + repoFolderName + '/.', self.targetPath);
    rm('-rf', self.targetPath + '/' + repoFolderName + '/');
    cd(self.targetPath);

    q.resolve(self.targetPath);
  }, function(err) {
    q.reject(err);
  });

  return q.promise;
};

IonicStartTask.prototype._fetchAndWriteSeed = function(projectType) {
  var self = this;

  // First, grab the wrapper project.

  var wrapperPromise = this._fetchWrapper();

  wrapperPromise.then(function() {
    // Get the starter project repo name:
    var repoName = 'ionic-starter-' + projectType;

    // The folder name the project will be downloaded and extracted to
    var repoFolderName = repoName + '-master';

    // Get the URL for the starter project repo:
    var repoUrl = self._getStarterUrl(repoName);

    Ionic.fetchRepo(self.targetPath, repoName, repoUrl).then(function(repoFolderName) {
      var npmQ = Q.defer();
      var gulpQ = Q.defer();
      var pluginQ = Q.defer();
      // Install dependencies for the starter project

      //Ionic.spawnPromise('npm', ['install', '--quiet']).then(function() {
        // Move the content of this repo into the www folder
        cp('-Rf', self.targetPath + '/' + repoFolderName + '/.', 'www');

        // Copy the root config file to the www folder
        // cp(self.targetPath + '/config.xml', 'www');

        // Clean up start template folder
        rm('-rf', self.targetPath + '/' + repoFolderName + '/');

        console.log('Initializing cordova project.'.info.bold);
        exec('cordova plugin add org.apache.cordova.device && ' +
             'cordova plugin add org.apache.cordova.console && ' +
             'cordova plugin add org.apache.cordova.statusbar', function(err, stdout, stderr) {
          if(err) {
            pluginQ.reject(stderr);
          } else {
            pluginQ.resolve(stdout);
          }
        })

        pluginQ.promise.then(function() {
          self._printQuickHelp(self.appName);
        }, function(err) {
          Ionic.fail('Unable to add plugins. Perhaps your version of Cordova is too old. Try updating (npm install -g cordova), removing this project folder, and trying again.');
        });

        IonicStats.t('start', {});
      /*
      }).fail(function(err, stderr) {;
        Ionic.fail('Unable to install Ionic dependencies. Please make sure you\'ve installed cordova, and gulp globally by running:\nsudo npm install -g cordova gulp. Error:\n'.error.bold + err + '\n' + stderr);
      });
      */
    }).catch(function(err) {
      console.error('Error: Unable to fetch project: HTTP:'.error.bold,  err.statusCode, err);
      console.error('Valid project types are blank, tabs, or sidemenu (or see more on our starter page: http://ionicframework.com/getting-started/)'.error.bold);
      Ionic.fail('');
    });

  }, function(err) {
    Ionic.fail('Unable to grab wrapper project:'.error.bold, err);
  });

};

IonicStartTask.prototype._printQuickHelp = function(projectDirectory) {
  console.log('\nYour Ionic project is ready to go!'.green.bold);
  console.log('\nSome quick tips:');
  console.log('\n * cd into your project directory before running any of the following commands', ('(cd ' + projectDirectory + ')').info.bold);
  console.log('\n * Make sure to add a platform (ios or Android):', 'ionic platform add android [ios]'.info.bold);
  console.log('    Note: iOS development requires OS X currently'.small);
  console.log('\n * To build your project, run', 'ionic build [platform]'.info.bold);
  console.log('\n * To emulate your project in a simulator or emulator, run', 'ionic emulate [platform]'.info.bold);
  console.log('\n * To run your project on a device, run', 'ionic run [platform]'.info.bold);
  console.log('\n\nFor more help, visit the Ionic docs:', 'http://ionicframework.com/docs'.info.bold);
};

IonicStartTask.prototype._writeConfig = function(ionic) {
  var project = IonicProject.create();
  project.set('name', this.appName);
  project.save(this.targetPath);
};

IonicStartTask.prototype._checkTargetPath = function() {
  if(fs.existsSync(this.targetPath)) {
    process.stderr.write('The directory '.error.bold + this.targetPath + ' already exists, please remove it if you would like to create a new ionic project there.\n'.error.bold);
    return false;
  }
  return true;
};

exports.IonicStartTask = IonicStartTask;
<|endoftext|>


<commit_before>CKEDITOR.plugins.add( 'mediahelper', {

    icons: 'mediahelper',

    init: function( editor ) {

        var self = this;

        CKEDITOR.dialog.add( 'MediaHelperDialog', function (editor) {

            return {

                title: 'Media Helper',
                minWidth: 400,
                minHeight: 200,

                contents: [

                    // Frame for settings
                    {
                        id: 'frame',
                        label: 'Settings',
                        elements: [

                            // URL
                            {
                                type: 'text',
                                id: 'url',
                                label: 'Video URL',
                                'autofocus': 'autofocus'
                            },

                            // Width
                            {
                                type: 'text',
                                id: 'width',
                                label: 'Width (pixels)'
                            },

                            // Height
                            {
                                type: 'text',
                                id: 'height',
                                label: 'Height (pixels)'
                            },

                            // Autoplay
                            {
                                type: 'checkbox',
                                id: 'autoplay',
                                label: 'Autoplay mode'
                            },

                            // Responsive
                            {
                                type: 'checkbox',
                                id: 'responsive',
                                'default': 'checked',
                                label: 'Responsive mode'
                            },

                            // Embed code
                            {
                                type: 'textarea',
                                id: 'embedcode',
                                label: 'Paste embed code (will ignore other settings)'
                            }

                        // End frame elements
                        ]
                    }

                // End contents
                ],

                onOk: function () {

                    var embedElement = null,
                        embedElementContent = null,
                        embedCode = this.getValueOf('frame', 'embedcode'),
                        responsive = this.getValueOf('frame', 'responsive'),
                        url = this.getValueOf('frame', 'url');

                    // If embed code is put in, and the element does not require responsive mode
                    if (embedCode && !responsive) {
                        editor.insertHtml(embedCode);
                    }

                    else {

                        var contentProps = {};

                        if (responsive) {
                            contentProps.styles = {
                                position: 'absolute',
                                top: 0,
                                left: 0,
                                width: '100%',
                                height: '100%'
                            };
                        }

                        // If embedCode is set, use that in an empty div
                        if (embedCode) {
                            embedElementContent = editor.document.createElement('div', contentProps);
                            embedElementContent.setHtml(embedCode);
                        }

                        // Else check value of url fields
                        else if (url) {

                            var width = this.getValueOf('frame', 'width') || 640,
                                height = this.getValueOf('frame', 'height') || 360,
                                autoplay = this.getValueOf('frame', 'autoplay'),
                                videoId = null,
                                attributes = [];

                            // Youtube
                            videoId = url.match(/(\.be\/|v[=\/])([\w\-]{11,})/i);
                            if ( videoId ) {
                                url = '//www.youtube.com/embed/' + videoId[2];
                                if (autoplay) {
                                    attributes.push('autoplay=1');
                                }
                            }

                            // Vimeo
                            videoId = url.match(/vimeo\.com(\/video|\/channels\/.*?)?\/(\d+)/i);
                            if ( videoId ) {
                                url = '//player.vimeo.com/video/' + videoId[2];
                                if (autoplay) {
                                    attributes.push('autoplay=1');
                                }
                            }

                            // Create element
                            contentProps.attributes = {
                                src: url + ( attributes.length ? '?' + attributes.join('&') : '' ),
                                width: parseInt( width ),
                                height: parseInt( height ),
                                frameborder: 0,
                                allowfullscreen: ''
                            };

                            embedElementContent = editor.document.createElement('iframe', contentProps);
                        }

                        // Could not determine type
                        else {
                            alert('No URL or embed code was given');
                            return false;
                        }

                        // Add defining class to element content
                        embedElementContent.addClass( 'media-element-content' );

                        // If responsive, put embed content into container
                        if (responsive) {
                            embedElement = editor.document.createElement('div',
                                {
                                    attributes: {
                                        'class': 'media-element'
                                    },
                                    styles: {
                                        position: 'relative',
                                        'padding-bottom': '56.25%', /* 16:9 */
                                        'padding-top': '25px',
                                        height: 0
                                    }
                                }
                            );
                            embedElementContent.appendTo( embedElement );
                        }

                        // Else set embed element to content
                        else {
                            embedElementContent.addClass( 'media-element' );
                            embedElement = embedElementContent;
                        }

                        // Append embedElement to editor
                        editor.insertElement( embedElement );

                    }

                    return true;
                }

            }

        });

        // Command to open dialog
        editor.addCommand( 'mediahelper', new CKEDITOR.dialogCommand( 'MediaHelperDialog', {
            allowedContent: 'div[*],iframe[*],object[*]'
        } ) );

        // Toolbar Button
        editor.ui.addButton( 'MediaHelper', {

            label: 'Media Helper',
            command: 'mediahelper',
            toolbar: 'insert'

        });

    }

});
<commit_msg>Description + authoring<commit_after>/**
*   This addon for CKEditor will enable the user to add (responsive) media elements.
*   The engine within this addon has knowledge of Youtube and Vimeo specific embedding, but is also lenient
*   towards custom embedding.
*
*   @author Jacob Overgaard <http://jovergaard.me>
*   @version 0.1.0
*   @updated 2014-09-24
*/

CKEDITOR.plugins.add( 'mediahelper', {

    icons: 'mediahelper',

    init: function( editor ) {

        var self = this;

        CKEDITOR.dialog.add( 'MediaHelperDialog', function (editor) {

            return {

                title: 'Media Helper',
                minWidth: 400,
                minHeight: 200,

                contents: [

                    // Frame for settings
                    {
                        id: 'frame',
                        label: 'Settings',
                        elements: [

                            // URL
                            {
                                type: 'text',
                                id: 'url',
                                label: 'Video URL',
                                'autofocus': 'autofocus'
                            },

                            // Width
                            {
                                type: 'text',
                                id: 'width',
                                label: 'Width (pixels)'
                            },

                            // Height
                            {
                                type: 'text',
                                id: 'height',
                                label: 'Height (pixels)'
                            },

                            // Autoplay
                            {
                                type: 'checkbox',
                                id: 'autoplay',
                                label: 'Autoplay mode'
                            },

                            // Responsive
                            {
                                type: 'checkbox',
                                id: 'responsive',
                                'default': 'checked',
                                label: 'Responsive mode'
                            },

                            // Embed code
                            {
                                type: 'textarea',
                                id: 'embedcode',
                                label: 'Paste embed code (will ignore other settings)'
                            }

                        // End frame elements
                        ]
                    }

                // End contents
                ],

                onOk: function () {

                    var embedElement = null,
                        embedElementContent = null,
                        embedCode = this.getValueOf('frame', 'embedcode'),
                        responsive = this.getValueOf('frame', 'responsive'),
                        url = this.getValueOf('frame', 'url');

                    // If embed code is put in, and the element does not require responsive mode
                    if (embedCode && !responsive) {
                        editor.insertHtml(embedCode);
                    }

                    else {

                        var contentProps = {};

                        if (responsive) {
                            contentProps.styles = {
                                position: 'absolute',
                                top: 0,
                                left: 0,
                                width: '100%',
                                height: '100%'
                            };
                        }

                        // If embedCode is set, use that in an empty div
                        if (embedCode) {
                            embedElementContent = editor.document.createElement('div', contentProps);
                            embedElementContent.setHtml(embedCode);
                        }

                        // Else check value of url fields
                        else if (url) {

                            var width = this.getValueOf('frame', 'width') || 640,
                                height = this.getValueOf('frame', 'height') || 360,
                                autoplay = this.getValueOf('frame', 'autoplay'),
                                videoId = null,
                                attributes = [];

                            // Youtube
                            videoId = url.match(/(\.be\/|v[=\/])([\w\-]{11,})/i);
                            if ( videoId ) {
                                url = '//www.youtube.com/embed/' + videoId[2];
                                if (autoplay) {
                                    attributes.push('autoplay=1');
                                }
                            }

                            // Vimeo
                            videoId = url.match(/vimeo\.com(\/video|\/channels\/.*?)?\/(\d+)/i);
                            if ( videoId ) {
                                url = '//player.vimeo.com/video/' + videoId[2];
                                if (autoplay) {
                                    attributes.push('autoplay=1');
                                }
                            }

                            // Create element
                            contentProps.attributes = {
                                src: url + ( attributes.length ? '?' + attributes.join('&') : '' ),
                                width: parseInt( width ),
                                height: parseInt( height ),
                                frameborder: 0,
                                allowfullscreen: ''
                            };

                            embedElementContent = editor.document.createElement('iframe', contentProps);
                        }

                        // Could not determine type
                        else {
                            alert('No URL or embed code was given');
                            return false;
                        }

                        // Add defining class to element content
                        embedElementContent.addClass( 'media-element-content' );

                        // If responsive, put embed content into container
                        if (responsive) {
                            embedElement = editor.document.createElement('div',
                                {
                                    attributes: {
                                        'class': 'media-element'
                                    },
                                    styles: {
                                        position: 'relative',
                                        'padding-bottom': '56.25%', /* 16:9 */
                                        'padding-top': '25px',
                                        height: 0
                                    }
                                }
                            );
                            embedElementContent.appendTo( embedElement );
                        }

                        // Else set embed element to content
                        else {
                            embedElementContent.addClass( 'media-element' );
                            embedElement = embedElementContent;
                        }

                        // Append embedElement to editor
                        editor.insertElement( embedElement );

                    }

                    return true;
                }

            }

        });

        // Command to open dialog
        editor.addCommand( 'mediahelper', new CKEDITOR.dialogCommand( 'MediaHelperDialog', {
            allowedContent: 'div[*],iframe[*],object[*]'
        } ) );

        // Toolbar Button
        editor.ui.addButton( 'MediaHelper', {

            label: 'Media Helper',
            command: 'mediahelper',
            toolbar: 'insert'

        });

    }

});
<|endoftext|>


<commit_before>

// return the shaper function as string based on given schema
export const shaperFunction = (schema) => {

  let functionCode = ''

  // start recursion
  recursiveWalk(schema)

  // write function code recursively
  function recursiveWalk(current, propertyName) {

    // if it's an object
    if (isObject(current)) {

      // it's not the root object
      if (propertyName) {
        // so write the property name
        functionCode += '"' + propertyName + '": '
      }

      // open object
      functionCode += '{ '

      // go through all properties and run recursion
      forEach(current, (nextProperty, nextPropertyName) => {
        recursiveWalk(nextProperty, nextPropertyName)
      })

      // close object
      functionCode += ' }'

      // only add comma if it's not the root object
      if (propertyName) {
        functionCode += ', '
      }
    }
    // otherwise it's a property only
    else {
      // assign value
      functionCode +=  '"' + propertyName + '":  data[ "' + current + '" ], '
    }
  }

  // return the function as string
  return functionCode
}

// check whether it is an object or not
function isObject(obj) {
  return obj !== null && (typeof obj === 'object' || typeof obj === 'function')
}

// map through all object keys and run a function
function forEach(obj, fn) {

  const propertyNames = isObject(obj)
    ? Object.keys(obj)
    : []

  propertyNames.map((propertyName) => {
    fn(obj[propertyName], propertyName)
  })
}

<commit_msg>convert generated code into an executable function<commit_after>

// return the shaper function as string based on given schema
export const shaperFunction = (schema) => {

  let functionCode = ''

  // start recursion
  recursiveWalk(schema)

  // write function code recursively
  function recursiveWalk(current, propertyName) {

    // if it's an object
    if (isObject(current)) {

      // it's not the root object
      if (propertyName) {
        // so write the property name
        functionCode += '"' + propertyName + '": '
      }

      // open object
      functionCode += '{ '

      // go through all properties and run recursion
      forEach(current, (nextProperty, nextPropertyName) => {
        recursiveWalk(nextProperty, nextPropertyName)
      })

      // close object
      functionCode += ' }'

      // only add comma if it's not the root object
      if (propertyName) {
        functionCode += ', '
      }
    }
    // otherwise it's a property only
    else {
      // assign value
      functionCode +=  '"' + propertyName + '":  data[ "' + current + '" ], '
    }
  }

  // return the function as string
  return functionCode
}

// return the shaper function as executable function based on given schema
export const shaper = (schema) => {

  // generate function
  const fnString = shaperFunction(schema)

  // generate executable function
  return new Function('data', `return ${fnString}`)
}

// check whether it is an object or not
function isObject(obj) {
  return obj !== null && (typeof obj === 'object' || typeof obj === 'function')
}

// map through all object keys and run a function
function forEach(obj, fn) {

  const propertyNames = isObject(obj)
    ? Object.keys(obj)
    : []

  propertyNames.map((propertyName) => {
    fn(obj[propertyName], propertyName)
  })
}

// default export
export default shaper
<|endoftext|>


<commit_before>var debug = require('debug')('kona:logger');
var winston = require('winston');
var fs = require('fs');

/**
 * @extends Kona
 *
 * methods for creatting and mounting the logger instance
 * to the appropriate file path based on the environment
 */
module.exports = {

  mountLogger: function(env) {

    this.log = this.createLogger(this.root.join('log', env + '.log'));

    this.on('error', function(err, ctx) {

      var messages = [err.message, err.stack];
      // if (ctx) {
      //   messages.push(ctx);
      // }
      if (env === 'development') { console.error(err.stack); }

      this.log.error.apply(this.log, messages);

    }.bind(this));

  },

  /**
   *
   * Attempts to create a winston logger at {filePath}
   * writes to file *and* stdout if not in test env
   *
   * also logs all `error` events emitted from the app
   *
   * @param  {String} filePath the path at which to write the log
   * @return {winston.Logger}     winston logger instance
   */
  createLogger: function(filePath) {

    var logTransports = [],
        logger,
        filePath;

    try {

      debug('opening log: ' + filePath);

      fs.writeFileSync(filePath, '');

      logTransports.push(new (winston.transports.File)({filename: filePath}));

    } catch(e) {
      if (['EACCES', 'ENOENT'].indexOf(e.code) > -1) {
        if (this.inApp) {
          console.error('Couldn\'t open log file at %s', filePath);
        } else {
          filePath = '/dev/null';
        }
      } else {
        throw e;
      }
    } finally {
      if (process.env.NODE_ENV === 'test') {
        logTransports.push(new (winston.transports.Console)({json: false}));
      }
      logger = new (winston.Logger)({transports: logTransports});
    }

    return logger;
  }

};<commit_msg>default to stdout logger<commit_after>var debug = require("debug")("kona:logger");
var winston = require("winston");
var fs = require("fs");

/**
 * @extends Kona
 *
 * methods for creatting and mounting the logger instance
 * to the appropriate file path based on the environment
 */
module.exports = {
  mountLogger: function (env) {
    this.log = this.createLogger(this.root.join("log", env + ".log"));

    this.on(
      "error",
      function (err, ctx) {
        var messages = [err.message, err.stack];
        // if (ctx) {
        //   messages.push(ctx);
        // }
        if (env === "development") {
          console.error(err.stack);
        }

        this.log.error.apply(this.log, messages);
      }.bind(this)
    );
  },

  /**
   *
   * Attempts to create a winston logger at {filePath}
   * writes to file *and* stdout if not in test env
   *
   * also logs all `error` events emitted from the app
   *
   * @param  {String} filePath the path at which to write the log
   * @return {winston.Logger}     winston logger instance
   */
  createLogger: function (filePath) {
    var logTransports = [],
      logger,
      filePath;

    try {
      debug("opening log: " + filePath);

      fs.writeFileSync(filePath, "");

      logTransports.push(new winston.transports.File({ filename: filePath }));
    } catch (e) {
      logTransports.push(new winston.transports.Console({ json: false }));
    } finally {
      logger = new winston.Logger({ transports: logTransports });
    }

    return logger;
  },
};
<|endoftext|>


<commit_before>import MapGenerator from './map-generator';
import Result       from './result';
import parse        from './parse';
import Root         from './root';

var warn = (message) => {
    if ( typeof(console) != 'undefined' && console.warn ) console.warn(message);
};

export default class LazyResult {
    constructor(processor, css, opts) {
        this.stringified = false;
        this.processed   = false;

        var root;
        if ( css instanceof Root ) {
            root = css;
        } else if ( css instanceof LazyResult || css instanceof Result ) {
            root = css.root;
            if ( css.map && typeof(opts.map) == 'undefined' ) {
                opts.map = { prev: css.map };
            }
        } else {
            root = parse(css, opts);
        }

        this.result = new Result(processor, root, opts);
    }

    get processor() {
        return this.result.processor;
    }

    get opts() {
        return this.result.opts;
    }

    get css() {
        return this.stringify().css;
    }

    get map() {
        return this.stringify().map;
    }

    get root() {
        return this.sync().root;
    }

    toString() {
        return this.css;
    }

    then(onFulfilled, onRejected) {
        return this.async().then(onFulfilled, onRejected);
    }

    catch(onRejected) {
        return this.async().catch(onRejected);
    }

    async() {
        if ( this.processed ) {
            return Promise.resolve().then( () => this.stringify() );
        }
        if ( this.processing ) {
            return this.processing;
        }

        this.processing = this.processor.plugins.map( (plugin) => {
            return new Promise( (resolve, reject) => {

                var promise = this.run(plugin);
                if ( promise instanceof Promise ) {
                    promise.then( () => resolve() )
                           .catch( (error) => reject(error) );
                } else {
                    resolve();
                }

            });
        })
        .reduce( (sequence, promise) => {
            return sequence.then( () => promise );
        }, Promise.resolve())
        .then( () => {
            this.processed = true;
            return this.stringify();
        });

        return this.processing;
    }

    sync() {
        if ( this.processed ) return this.result;
        this.processed = true;

        if ( this.processing ) {
            throw 'Use process(css).then(cb) to work with async plugins';
        }

        for ( var plugin of this.result.processor.plugins ) {
            var promise = this.run(plugin);
            if ( promise instanceof Promise ) {
                throw 'Use process(css).then(cb) to work with async plugins';
            }
        }

        return this.result;
    }

    run(plugin) {
        this.result.lastPlugin = plugin;

        try {
            var returned = plugin(this.result.root, this.result);
        } catch (error) {
            if ( plugin.postcssVersion ) {
                var pluginName     = plugin.postcssPlugin;
                var pluginVersion  = plugin.postcssVersion;
                var runtimeVersion = this.result.processor.version;
                var a = pluginVersion.split('.');
                var b = runtimeVersion.split('.');

                if ( a[0] != b[0] || parseInt(a[1]) > parseInt(b[1]) ) {
                    warn(`${pluginName} is based on PostCSS ${pluginVersion} ` +
                         `but you use it with PostCSS ${runtimeVersion}. ` +
                         'Maybe this is a source of error below.');
                }
            }
            throw error;
        }

        if ( returned instanceof Root ) {
            this.result.root = returned;
        } else {
            return returned;
        }
    }

    stringify() {
        if ( this.stringified ) return this.result;
        this.stringified = true;

        this.sync();
        var map = new MapGenerator(this.result.root, this.result.opts);
        [this.result.css, this.result.map] = map.generate();

        return this.result;
    }

}
<commit_msg>Fix variable scope<commit_after>import MapGenerator from './map-generator';
import Result       from './result';
import parse        from './parse';
import Root         from './root';

var warn = (message) => {
    if ( typeof(console) != 'undefined' && console.warn ) console.warn(message);
};

export default class LazyResult {
    constructor(processor, css, opts) {
        this.stringified = false;
        this.processed   = false;

        var root;
        if ( css instanceof Root ) {
            root = css;
        } else if ( css instanceof LazyResult || css instanceof Result ) {
            root = css.root;
            if ( css.map && typeof(opts.map) == 'undefined' ) {
                opts.map = { prev: css.map };
            }
        } else {
            root = parse(css, opts);
        }

        this.result = new Result(processor, root, opts);
    }

    get processor() {
        return this.result.processor;
    }

    get opts() {
        return this.result.opts;
    }

    get css() {
        return this.stringify().css;
    }

    get map() {
        return this.stringify().map;
    }

    get root() {
        return this.sync().root;
    }

    toString() {
        return this.css;
    }

    then(onFulfilled, onRejected) {
        return this.async().then(onFulfilled, onRejected);
    }

    catch(onRejected) {
        return this.async().catch(onRejected);
    }

    async() {
        if ( this.processed ) {
            return Promise.resolve().then( () => this.stringify() );
        }
        if ( this.processing ) {
            return this.processing;
        }

        this.processing = this.processor.plugins.map( (plugin) => {
            return new Promise( (resolve, reject) => {

                var promise = this.run(plugin);
                if ( promise instanceof Promise ) {
                    promise.then( () => resolve() )
                           .catch( (error) => reject(error) );
                } else {
                    resolve();
                }

            });
        })
        .reduce( (sequence, promise) => {
            return sequence.then( () => promise );
        }, Promise.resolve())
        .then( () => {
            this.processed = true;
            return this.stringify();
        });

        return this.processing;
    }

    sync() {
        if ( this.processed ) return this.result;
        this.processed = true;

        if ( this.processing ) {
            throw 'Use process(css).then(cb) to work with async plugins';
        }

        for ( var plugin of this.result.processor.plugins ) {
            var promise = this.run(plugin);
            if ( promise instanceof Promise ) {
                throw 'Use process(css).then(cb) to work with async plugins';
            }
        }

        return this.result;
    }

    run(plugin) {
        this.result.lastPlugin = plugin;

        var returned;
        try {
            returned = plugin(this.result.root, this.result);
        } catch (error) {
            if ( plugin.postcssVersion ) {
                var pluginName     = plugin.postcssPlugin;
                var pluginVersion  = plugin.postcssVersion;
                var runtimeVersion = this.result.processor.version;
                var a = pluginVersion.split('.');
                var b = runtimeVersion.split('.');

                if ( a[0] != b[0] || parseInt(a[1]) > parseInt(b[1]) ) {
                    warn(`${pluginName} is based on PostCSS ${pluginVersion} ` +
                         `but you use it with PostCSS ${runtimeVersion}. ` +
                         'Maybe this is a source of error below.');
                }
            }
            throw error;
        }

        if ( returned instanceof Root ) {
            this.result.root = returned;
        } else {
            return returned;
        }
    }

    stringify() {
        if ( this.stringified ) return this.result;
        this.stringified = true;

        this.sync();
        var map = new MapGenerator(this.result.root, this.result.opts);
        [this.result.css, this.result.map] = map.generate();

        return this.result;
    }

}
<|endoftext|>


<commit_before>'use strict';

var MatchError = require('./error').MatchError;
var names = require('../utils/names');
var generic = require('./generic');
var parse = require('./grammar/parse');
var translate = require('./grammar/translate');
var walk = require('./grammar/walk');
var match = require('./match');
var trace = require('./trace');
var cssWideKeywords = parse('inherit | initial | unset');
var cssWideKeywordsWithExpression = parse('inherit | initial | unset | <expression>');

function dumpMapSyntax(map, syntaxAsAst) {
    var result = {};

    for (var name in map) {
        if (map[name].syntax) {
            result[name] = syntaxAsAst ? map[name].syntax : translate(map[name].syntax);
        }
    }

    return result;
}

function unwrapNode(item) {
    return item && item.data;
}

function valueHasVar(value) {
    var hasVar = false;

    this.syntax.walk(value, function(node) {
        if (node.type === 'Function' && node.name.toLowerCase() === 'var') {
            hasVar = true;
        }
    });

    return hasVar;
}

// check node is \0 or \9 hack
function isHack(node) {
    return node.type === 'Identifier' && /^\\[09]/.test(node.name);
}

// white spaces, comments and some hacks can to be ignored at the end of value
function isNextMayToBeIgnored(cursor) {
    while (cursor !== null) {
        if (cursor.data.type !== 'WhiteSpace' &&
            cursor.data.type !== 'Comment' &&
            !isHack(cursor.data)) {
            return false;
        }

        cursor = cursor.next;
    }

    return true;
}

function buildMatchResult(match, error) {
    return {
        matched: match || null,
        error: error || null,
        getTrace: trace.getTrace,
        isType: trace.isType,
        isProperty: trace.isProperty,
        isKeyword: trace.isKeyword
    };
}

function matchSyntax(lexer, syntax, value) {
    var result;

    if (!value || value.type !== 'Value') {
        return buildMatchResult(null, new Error('Not a Value node'));
    }

    if (valueHasVar.call(lexer, value)) {
        return buildMatchResult(null, new Error('Due to matching for value with var() is very complex those values are always valid for now'));
    }

    result = match(lexer, lexer.valueCommonSyntax, value.children.head);

    if (!result.match) {
        result = syntax.match(value.children.head);
        if (!result.match) {
            return buildMatchResult(null, new MatchError('Mismatch', lexer, syntax.syntax, value, result.badNode || unwrapNode(result.next)));
        }
    }

    if (result.next && !isNextMayToBeIgnored(result.next)) {
        return buildMatchResult(null, new MatchError('Uncomplete match', lexer, syntax.syntax, value, result.badNode || unwrapNode(result.next)));
    }

    return buildMatchResult(result.match, null);
}

var Lexer = function(config, syntax, structure) {
    this.valueCommonSyntax = cssWideKeywords;
    this.syntax = syntax;
    this.generic = false;
    this.properties = {};
    this.types = {};
    this.structure = structure;

    if (config) {
        if (config.generic) {
            this.generic = true;
            for (var name in generic) {
                this.addType_(name, generic[name]);
            }
        }

        if (config.types) {
            for (var name in config.types) {
                this.addType_(name, config.types[name]);
            }
        }

        if (config.properties) {
            for (var name in config.properties) {
                this.addProperty_(name, config.properties[name]);
            }
        }
    }
};

Lexer.prototype = {
    structure: {},
    checkStructure: function(ast) {
        var structure = this.structure;
        var warns = [];

        this.syntax.walk(ast, function(node) {
            if (structure.hasOwnProperty(node.type)) {
                structure[node.type].check(node, warns.push.bind(warns));
            } else {
                throw new Error('Unknown node type: ' + node.type);
            }
        });

        return warns.length ? warns : false;
    },

    createDescriptor: function(syntax) {
        var self = this;
        var descriptor = {
            syntax: null,
            match: null
        };

        if (typeof syntax === 'function') {
            // convert syntax to pseudo syntax node
            // NOTE: that's not a part of match result tree
            syntax = {
                type: 'ASTNode',
                match: syntax
            };

            descriptor.match = function(item) {
                return match(self, syntax, item);
            };
        } else {
            if (typeof syntax === 'string') {
                // lazy parsing on first access
                Object.defineProperty(descriptor, 'syntax', {
                    get: function() {
                        Object.defineProperty(descriptor, 'syntax', {
                            value: parse(syntax)
                        });

                        return descriptor.syntax;
                    }
                });
            } else {
                descriptor.syntax = syntax;
            }

            descriptor.match = function(item) {
                return match(self, descriptor.syntax, item);
            };
        }

        return descriptor;
    },
    addProperty_: function(name, syntax) {
        this.properties[name] = this.createDescriptor(syntax);
    },
    addType_: function(name, syntax) {
        this.types[name] = this.createDescriptor(syntax);

        if (syntax === generic.expression) {
            this.valueCommonSyntax = cssWideKeywordsWithExpression;
        }
    },

    matchDeclaration: function(node) {
        if (node.type !== 'Declaration') {
            return buildMatchResult(null, new Error('Value not a Declaration node'));
        }

        return this.matchProperty(node.property, node.value);
    },
    matchProperty: function(propertyName, value) {
        var property = names.property(propertyName);

        // don't match syntax for a custom property
        if (property.custom) {
            return buildMatchResult(null, new Error('Lexer matching doesn\'t applicable for custom properties'));
        }

        var propertySyntax = property.vendor
            ? this.getProperty(property.vendor + property.name) || this.getProperty(property.name)
            : this.getProperty(property.name);

        if (!propertySyntax) {
            return buildMatchResult(null, new Error('Unknown property: ' + propertyName));
        }

        return matchSyntax(this, propertySyntax, value);
    },
    matchType: function(typeName, value) {
        var typeSyntax = this.getType(typeName);

        if (!typeSyntax) {
            return buildMatchResult(null, new Error('Unknown type: ' + typeName));
        }

        return matchSyntax(this, typeSyntax, value);
    },

    getProperty: function(name) {
        return this.properties.hasOwnProperty(name) ? this.properties[name] : null;
    },
    getType: function(name) {
        return this.types.hasOwnProperty(name) ? this.types[name] : null;
    },

    validate: function() {
        function validate(syntax, name, broken, descriptor) {
            if (broken.hasOwnProperty(name)) {
                return broken[name];
            }

            broken[name] = false;
            if (descriptor.syntax !== null) {
                walk(descriptor.syntax, function(node) {
                    if (node.type !== 'Type' && node.type !== 'Property') {
                        return;
                    }

                    var map = node.type === 'Type' ? syntax.types : syntax.properties;
                    var brokenMap = node.type === 'Type' ? brokenTypes : brokenProperties;

                    if (!map.hasOwnProperty(node.name) || validate(syntax, node.name, brokenMap, map[node.name])) {
                        broken[name] = true;
                    }
                }, this);
            }
        }

        var brokenTypes = {};
        var brokenProperties = {};

        for (var key in this.types) {
            validate(this, key, brokenTypes, this.types[key]);
        }

        for (var key in this.properties) {
            validate(this, key, brokenProperties, this.properties[key]);
        }

        brokenTypes = Object.keys(brokenTypes).filter(function(name) {
            return brokenTypes[name];
        });
        brokenProperties = Object.keys(brokenProperties).filter(function(name) {
            return brokenProperties[name];
        });

        if (brokenTypes.length || brokenProperties.length) {
            return {
                types: brokenTypes,
                properties: brokenProperties
            };
        }

        return null;
    },
    dump: function(syntaxAsAst) {
        return {
            generic: this.generic,
            types: dumpMapSyntax(this.types, syntaxAsAst),
            properties: dumpMapSyntax(this.properties, syntaxAsAst)
        };
    },
    toString: function() {
        return JSON.stringify(this.dump());
    }
};

module.exports = Lexer;
<commit_msg>fix error message<commit_after>'use strict';

var MatchError = require('./error').MatchError;
var names = require('../utils/names');
var generic = require('./generic');
var parse = require('./grammar/parse');
var translate = require('./grammar/translate');
var walk = require('./grammar/walk');
var match = require('./match');
var trace = require('./trace');
var cssWideKeywords = parse('inherit | initial | unset');
var cssWideKeywordsWithExpression = parse('inherit | initial | unset | <expression>');

function dumpMapSyntax(map, syntaxAsAst) {
    var result = {};

    for (var name in map) {
        if (map[name].syntax) {
            result[name] = syntaxAsAst ? map[name].syntax : translate(map[name].syntax);
        }
    }

    return result;
}

function unwrapNode(item) {
    return item && item.data;
}

function valueHasVar(value) {
    var hasVar = false;

    this.syntax.walk(value, function(node) {
        if (node.type === 'Function' && node.name.toLowerCase() === 'var') {
            hasVar = true;
        }
    });

    return hasVar;
}

// check node is \0 or \9 hack
function isHack(node) {
    return node.type === 'Identifier' && /^\\[09]/.test(node.name);
}

// white spaces, comments and some hacks can to be ignored at the end of value
function isNextMayToBeIgnored(cursor) {
    while (cursor !== null) {
        if (cursor.data.type !== 'WhiteSpace' &&
            cursor.data.type !== 'Comment' &&
            !isHack(cursor.data)) {
            return false;
        }

        cursor = cursor.next;
    }

    return true;
}

function buildMatchResult(match, error) {
    return {
        matched: match || null,
        error: error || null,
        getTrace: trace.getTrace,
        isType: trace.isType,
        isProperty: trace.isProperty,
        isKeyword: trace.isKeyword
    };
}

function matchSyntax(lexer, syntax, value) {
    var result;

    if (!value || value.type !== 'Value') {
        return buildMatchResult(null, new Error('Not a Value node'));
    }

    if (valueHasVar.call(lexer, value)) {
        return buildMatchResult(null, new Error('Due to matching for value with var() is very complex those values are always valid for now'));
    }

    result = match(lexer, lexer.valueCommonSyntax, value.children.head);

    if (!result.match) {
        result = syntax.match(value.children.head);
        if (!result.match) {
            return buildMatchResult(null, new MatchError('Mismatch', lexer, syntax.syntax, value, result.badNode || unwrapNode(result.next)));
        }
    }

    if (result.next && !isNextMayToBeIgnored(result.next)) {
        return buildMatchResult(null, new MatchError('Uncomplete match', lexer, syntax.syntax, value, result.badNode || unwrapNode(result.next)));
    }

    return buildMatchResult(result.match, null);
}

var Lexer = function(config, syntax, structure) {
    this.valueCommonSyntax = cssWideKeywords;
    this.syntax = syntax;
    this.generic = false;
    this.properties = {};
    this.types = {};
    this.structure = structure;

    if (config) {
        if (config.generic) {
            this.generic = true;
            for (var name in generic) {
                this.addType_(name, generic[name]);
            }
        }

        if (config.types) {
            for (var name in config.types) {
                this.addType_(name, config.types[name]);
            }
        }

        if (config.properties) {
            for (var name in config.properties) {
                this.addProperty_(name, config.properties[name]);
            }
        }
    }
};

Lexer.prototype = {
    structure: {},
    checkStructure: function(ast) {
        var structure = this.structure;
        var warns = [];

        this.syntax.walk(ast, function(node) {
            if (structure.hasOwnProperty(node.type)) {
                structure[node.type].check(node, warns.push.bind(warns));
            } else {
                throw new Error('Unknown node type: ' + node.type);
            }
        });

        return warns.length ? warns : false;
    },

    createDescriptor: function(syntax) {
        var self = this;
        var descriptor = {
            syntax: null,
            match: null
        };

        if (typeof syntax === 'function') {
            // convert syntax to pseudo syntax node
            // NOTE: that's not a part of match result tree
            syntax = {
                type: 'ASTNode',
                match: syntax
            };

            descriptor.match = function(item) {
                return match(self, syntax, item);
            };
        } else {
            if (typeof syntax === 'string') {
                // lazy parsing on first access
                Object.defineProperty(descriptor, 'syntax', {
                    get: function() {
                        Object.defineProperty(descriptor, 'syntax', {
                            value: parse(syntax)
                        });

                        return descriptor.syntax;
                    }
                });
            } else {
                descriptor.syntax = syntax;
            }

            descriptor.match = function(item) {
                return match(self, descriptor.syntax, item);
            };
        }

        return descriptor;
    },
    addProperty_: function(name, syntax) {
        this.properties[name] = this.createDescriptor(syntax);
    },
    addType_: function(name, syntax) {
        this.types[name] = this.createDescriptor(syntax);

        if (syntax === generic.expression) {
            this.valueCommonSyntax = cssWideKeywordsWithExpression;
        }
    },

    matchDeclaration: function(node) {
        if (node.type !== 'Declaration') {
            return buildMatchResult(null, new Error('Not a Declaration node'));
        }

        return this.matchProperty(node.property, node.value);
    },
    matchProperty: function(propertyName, value) {
        var property = names.property(propertyName);

        // don't match syntax for a custom property
        if (property.custom) {
            return buildMatchResult(null, new Error('Lexer matching doesn\'t applicable for custom properties'));
        }

        var propertySyntax = property.vendor
            ? this.getProperty(property.vendor + property.name) || this.getProperty(property.name)
            : this.getProperty(property.name);

        if (!propertySyntax) {
            return buildMatchResult(null, new Error('Unknown property: ' + propertyName));
        }

        return matchSyntax(this, propertySyntax, value);
    },
    matchType: function(typeName, value) {
        var typeSyntax = this.getType(typeName);

        if (!typeSyntax) {
            return buildMatchResult(null, new Error('Unknown type: ' + typeName));
        }

        return matchSyntax(this, typeSyntax, value);
    },

    getProperty: function(name) {
        return this.properties.hasOwnProperty(name) ? this.properties[name] : null;
    },
    getType: function(name) {
        return this.types.hasOwnProperty(name) ? this.types[name] : null;
    },

    validate: function() {
        function validate(syntax, name, broken, descriptor) {
            if (broken.hasOwnProperty(name)) {
                return broken[name];
            }

            broken[name] = false;
            if (descriptor.syntax !== null) {
                walk(descriptor.syntax, function(node) {
                    if (node.type !== 'Type' && node.type !== 'Property') {
                        return;
                    }

                    var map = node.type === 'Type' ? syntax.types : syntax.properties;
                    var brokenMap = node.type === 'Type' ? brokenTypes : brokenProperties;

                    if (!map.hasOwnProperty(node.name) || validate(syntax, node.name, brokenMap, map[node.name])) {
                        broken[name] = true;
                    }
                }, this);
            }
        }

        var brokenTypes = {};
        var brokenProperties = {};

        for (var key in this.types) {
            validate(this, key, brokenTypes, this.types[key]);
        }

        for (var key in this.properties) {
            validate(this, key, brokenProperties, this.properties[key]);
        }

        brokenTypes = Object.keys(brokenTypes).filter(function(name) {
            return brokenTypes[name];
        });
        brokenProperties = Object.keys(brokenProperties).filter(function(name) {
            return brokenProperties[name];
        });

        if (brokenTypes.length || brokenProperties.length) {
            return {
                types: brokenTypes,
                properties: brokenProperties
            };
        }

        return null;
    },
    dump: function(syntaxAsAst) {
        return {
            generic: this.generic,
            types: dumpMapSyntax(this.types, syntaxAsAst),
            properties: dumpMapSyntax(this.properties, syntaxAsAst)
        };
    },
    toString: function() {
        return JSON.stringify(this.dump());
    }
};

module.exports = Lexer;
<|endoftext|>


<commit_before>// ltsv Copyright(c) 2013 sasa+1
// https://github.com/sasaplus1/ltsv
// Released under the MIT License.

function parse(ltsvStr) {
  var ltsv = String(ltsvStr),
      records = ltsv.split('\t'),
      result = {},
      i, len, field;

  for (i = 0, len = records.length; i < len; ++i) {
    field = records[i].split(':');
    result[field[0]] = field[1];
  }

  return result;
}

module.exports = {
  parse: parse
};
<commit_msg>フィールドの分割にsplitでなくsliceを使うように<commit_after>// ltsv Copyright(c) 2013 sasa+1
// https://github.com/sasaplus1/ltsv
// Released under the MIT License.

function getField_(fieldStr) {
  var field = String(fieldStr),
      separatorIndex = field.indexOf(':');

  if (separatorIndex === -1) {
    throw new Error('"' + fieldStr + '" has not field separator');
  }

  return {
    label: field.slice(0, separatorIndex),
    value: field.slice(separatorIndex + 1)
  };
}

function parse(ltsvStr) {
  var ltsv = String(ltsvStr),
      records = ltsv.split('\t'),
      result = {},
      i, len, field;

  for (i = 0, len = records.length; i < len; ++i) {
    field = getField_(records[i]);
    result[field.label] = field.value;
  }

  return result;
}

module.exports = {
  parse: parse
};
<|endoftext|>


<commit_before>/// <reference path="../types/node-0.11.d.ts" />
var stream = require('stream');
var util = require('util');
var WritableStreamBuffer = require('stream-buffers').WritableStreamBuffer;
var M2TsPacket = require('./m2ts-packet.js');

var M2TsStream = (function () {
	var DecideSyncUnitSizeCount = 3;
	util.inherits(M2TsStream, stream.Transform);
	var SyncByte = 0x47;
	function M2TsStream (unitSize) {
		stream.Transform.call(this);

		this.enableParse = false;
		this.buffer = new WritableStreamBuffer();
		this.unitSize = unitSize || -1;
		this.syncByteOffsets = [];
		this.dataOffset = -1;
		this.predicate = null;
	}

	M2TsStream.Packet = M2TsPacket;
	M2TsStream.PSI = require('./m2ts-psi.js');
	M2TsStream.PAT = require('./m2ts-pat.js');
	M2TsStream.PMT = require('./m2ts-pmt.js');

	M2TsStream.prototype._transform = function (chunk, encoding, callback) {
		if (this._writableState.objectMode) {
			var push = true;
			if (this._readableState.objectMode) {
				if (this.predicate !== null) {
					push = this.predicate(chunk, chunk.pid);
				}
			} else {
				// unparse
				chunk = chunk.rawTsPacket;
			}
			if (push) {
				this.push(chunk);
			}
		} else {
			if (this.unitSize < 0) {
				var offset = this.buffer.size();
				for (var i = 0; i < chunk.length; i++) {
					if (chunk[i] === SyncByte) {
						this.syncByteOffsets.push(i + offset);
					}
				}

				this.unitSize = this._decideUnitSize(this.syncByteOffsets);
				this.buffer.write(chunk);

				if (this.unitSize > 0) {
					this.syncByteOffsets = [];
					if (this.dataOffset > 0) {
						this.buffer.getContents(this.dataOffset);
					}
				}
			} else {
				this.buffer.write(chunk);
			}

			while (this.unitSize > 0 && this.buffer.size() >= this.unitSize) {
				var rawTsPacket = this.buffer.getContents(this.unitSize);
				var pid = -1;
				var tsPacket = null;

				if (this.enableParse) {
					tsPacket = new M2TsPacket(rawTsPacket);
					pid = tsPacket.pid;
				} else {
					tsPacket = rawTsPacket;
					pid = tsPacket.readUInt16BE(1) & 0x1fff;
				}

				var push = true;
				if (this.predicate !== null) {
					push = this.predicate(tsPacket, pid);
				}

				if (push) {
					this.push(tsPacket);
				}
			}
		}

		callback();
	};

	M2TsStream.prototype._decideUnitSize = function (syncByteOffsets, readCount) {
		readCount = readCount || 0;
		if (syncByteOffsets.length - readCount < DecideSyncUnitSizeCount) {
			return -1;
		}

		var diffs = [];
		var syncByteOffset = syncByteOffsets[readCount];
		for (var i = readCount + 1; i < syncByteOffsets.length; i++) {
			diffs.push(syncByteOffsets[i] - syncByteOffset);
		}

		for (var i = 0; i < diffs.length; i++) {
			var diff = diffs[i];
			var found = true;
			for (var j = 1; j <= DecideSyncUnitSizeCount; j++) {
				if (syncByteOffsets.indexOf(syncByteOffset + diff * j) < 0) {
					found = false;
					break;
				}
			}

			if (found) {
				this.dataOffset = syncByteOffset;
				return diff;
			}
		}

		return this._decideUnitSize(syncByteOffsets, readCount + 1);
	};

	M2TsStream.prototype._setPredicate = function (predicate) {
		this.predicate = predicate;
	};

	M2TsStream.prototype.include = function (args) {
		if (!Array.isArray(args)) {
			args = Array.prototype.slice.call(arguments);
		}

		var stream = new M2TsStream(this.unitSize);
		stream._setObjectMode(this._readableState.objectMode, this._readableState.objectMode);
		stream._setPredicate(function (_, pid) {
			return args.indexOf(pid) >= 0;
		});
		return this.pipe(stream);
	};

	M2TsStream.prototype.exclude = function (args) {
		if (!Array.isArray(args)) {
			args = Array.prototype.slice.call(arguments);
		}

		var stream = new M2TsStream(this.unitSize);
		stream._setObjectMode(this._readableState.objectMode, this._readableState.objectMode);
		stream._setPredicate(function (_, pid) {
			return args.indexOf(pid) < 0;
		});
		return this.pipe(stream);
	};

	M2TsStream.prototype.where = function (predicate) {
		var stream = new M2TsStream(this.unitSize);
		stream._setObjectMode(this._readableState.objectMode, this._readableState.objectMode);
		stream._setPredicate(predicate);
		return this.pipe(stream);
	};

	M2TsStream.prototype._setObjectMode = function (readObjectMode, writeObjectMode) {
		this.enableParse = this._readableState.objectMode = readObjectMode;
		this._writableState.objectMode = writeObjectMode;
	};

	M2TsStream.prototype.parse = function () {
		var stream = new M2TsStream(this.unitSize);
		stream._setObjectMode(true, this.enableParse);
		return this.pipe(stream);
	};

	M2TsStream.prototype.unparse = function () {
		var stream = new M2TsStream(this.unitSize);
		stream._setObjectMode(false, this.enableParse);
		return this.pipe(stream);
	};

	return M2TsStream;
})();

module.exports = M2TsStream;
<commit_msg>少し高速化<commit_after>/// <reference path="../types/node-0.11.d.ts" />
var stream = require('stream');
var util = require('util');
var WritableStreamBuffer = require('stream-buffers').WritableStreamBuffer;
var M2TsPacket = require('./m2ts-packet.js');

var M2TsStream = (function () {
	var DecideSyncUnitSizeCount = 3;
	util.inherits(M2TsStream, stream.Transform);
	var SyncByte = 0x47;
	function M2TsStream (unitSize) {
		stream.Transform.call(this);

		this.enableParse = false;
		this.buffer = new WritableStreamBuffer();
		this.unitSize = unitSize || -1;
		this.syncByteOffsets = [];
		this.dataOffset = -1;
		this.predicate = null;
	}

	M2TsStream.Packet = M2TsPacket;
	M2TsStream.PSI = require('./m2ts-psi.js');
	M2TsStream.PAT = require('./m2ts-pat.js');
	M2TsStream.PMT = require('./m2ts-pmt.js');

	M2TsStream.prototype._transform = function (chunk, encoding, callback) {
		if (this._writableState.objectMode) {
			var push = true;
			if (this._readableState.objectMode) {
				if (this.predicate !== null) {
					push = this.predicate(chunk, chunk.pid);
				}
			} else {
				// unparse
				chunk = chunk.rawTsPacket;
			}
			if (push) {
				this.push(chunk);
			}
		} else {
			if (this.unitSize < 0) {
				var offset = this.buffer.size();
				for (var i = 0; i < chunk.length; i++) {
					if (chunk[i] === SyncByte) {
						this.syncByteOffsets.push(i + offset);
					}
				}

				this.unitSize = this._decideUnitSize(this.syncByteOffsets);
				this.buffer.write(chunk);

				if (this.unitSize > 0) {
					this.syncByteOffsets = [];
					if (this.dataOffset > 0) {
						this.buffer.getContents(this.dataOffset);
					}
				}
			} else {
				this.buffer.write(chunk);
			}

			while (this.unitSize > 0 && this.buffer.size() >= this.unitSize) {
				var packetNum = Math.floor(this.buffer.size() / this.unitSize);
				var buf = this.buffer.getContents(this.unitSize * packetNum);
				for (var packetOffset = 0; packetOffset < buf.length; packetOffset += this.unitSize) {
					var rawTsPacket = buf.slice(packetOffset, packetOffset + this.unitSize);
					var pid = -1;
					var tsPacket = null;

					if (this.enableParse) {
						tsPacket = new M2TsPacket(rawTsPacket);
						pid = tsPacket.pid;
					} else {
						tsPacket = rawTsPacket;
						pid = tsPacket.readUInt16BE(1) & 0x1fff;
					}

					var push = true;
					if (this.predicate !== null) {
						push = this.predicate(tsPacket, pid);
					}

					if (push) {
						this.push(tsPacket);
					}
				}
			}
		}

		callback();
	};

	M2TsStream.prototype._decideUnitSize = function (syncByteOffsets, readCount) {
		readCount = readCount || 0;
		if (syncByteOffsets.length - readCount < DecideSyncUnitSizeCount) {
			return -1;
		}

		var diffs = [];
		var syncByteOffset = syncByteOffsets[readCount];
		for (var i = readCount + 1; i < syncByteOffsets.length; i++) {
			diffs.push(syncByteOffsets[i] - syncByteOffset);
		}

		for (var i = 0; i < diffs.length; i++) {
			var diff = diffs[i];
			var found = true;
			for (var j = 1; j <= DecideSyncUnitSizeCount; j++) {
				if (syncByteOffsets.indexOf(syncByteOffset + diff * j) < 0) {
					found = false;
					break;
				}
			}

			if (found) {
				this.dataOffset = syncByteOffset;
				return diff;
			}
		}

		return this._decideUnitSize(syncByteOffsets, readCount + 1);
	};

	M2TsStream.prototype._setPredicate = function (predicate) {
		this.predicate = predicate;
	};

	M2TsStream.prototype.include = function (args) {
		if (!Array.isArray(args)) {
			args = Array.prototype.slice.call(arguments);
		}

		var stream = new M2TsStream(this.unitSize);
		stream._setObjectMode(this._readableState.objectMode, this._readableState.objectMode);
		stream._setPredicate(function (_, pid) {
			return args.indexOf(pid) >= 0;
		});
		return this.pipe(stream);
	};

	M2TsStream.prototype.exclude = function (args) {
		if (!Array.isArray(args)) {
			args = Array.prototype.slice.call(arguments);
		}

		var stream = new M2TsStream(this.unitSize);
		stream._setObjectMode(this._readableState.objectMode, this._readableState.objectMode);
		stream._setPredicate(function (_, pid) {
			return args.indexOf(pid) < 0;
		});
		return this.pipe(stream);
	};

	M2TsStream.prototype.where = function (predicate) {
		var stream = new M2TsStream(this.unitSize);
		stream._setObjectMode(this._readableState.objectMode, this._readableState.objectMode);
		stream._setPredicate(predicate);
		return this.pipe(stream);
	};

	M2TsStream.prototype._setObjectMode = function (readObjectMode, writeObjectMode) {
		this.enableParse = this._readableState.objectMode = readObjectMode;
		this._writableState.objectMode = writeObjectMode;
	};

	M2TsStream.prototype.parse = function () {
		var stream = new M2TsStream(this.unitSize);
		stream._setObjectMode(true, this.enableParse);
		return this.pipe(stream);
	};

	M2TsStream.prototype.unparse = function () {
		var stream = new M2TsStream(this.unitSize);
		stream._setObjectMode(false, this.enableParse);
		return this.pipe(stream);
	};

	return M2TsStream;
})();

module.exports = M2TsStream;
<|endoftext|>


<commit_before>const Writable = require('stream').Writable;
const util     = require('util');

/**
 * A very simple m3u8 playlist file parser that detects tags and segments.
 *
 * @extends WritableStream
 * @constructor
 */
var m3u8parser = module.exports = function() {
  var lastLine = '';
  var self = this;
  function parseLine(line) {
    var tag = line.match(/^#(EXT[A-Z0-9\-]+)(?::(.*))?/);
    if (tag) {
      // This is a tag.
      self.emit('tag', tag[1], tag[2] || null);

    } else if (line.trim()) {
      // This is a segment
      self.emit('item', line.trim());
    }
  }

  Writable.call(this, {
    decodeStrings: false,
    write: function(chunk, encoding, callback) {
      var lines = chunk.toString('utf8').split('\n');
      if (lastLine) { lines[0] = lastLine + lines[0]; }
      lines.forEach(function(line, i) {
        if (i < lines.length - 1) {
          parseLine(line);
        } else {
          // Save the last line in case it has been broken up.
          lastLine = line;
        }
      });
      callback();
    },
  }),

  this.on('finish', function() {
    parseLine(lastLine);
    self.emit('end');
  });
};

util.inherits(m3u8parser, Writable);
<commit_msg>Support old Writable options<commit_after>const Writable = require('stream').Writable;
const util     = require('util');

/**
 * A very simple m3u8 playlist file parser that detects tags and segments.
 *
 * @extends WritableStream
 * @constructor
 */
var m3u8parser = module.exports = function() {
  var lastLine = '';
  var self = this;
  function parseLine(line) {
    var tag = line.match(/^#(EXT[A-Z0-9\-]+)(?::(.*))?/);
    if (tag) {
      // This is a tag.
      self.emit('tag', tag[1], tag[2] || null);

    } else if (line.trim()) {
      // This is a segment
      self.emit('item', line.trim());
    }
  }

  Writable.call(this, {
    decodeStrings: false,
  }),

  this._write = function(chunk, encoding, callback) {
    var lines = chunk.toString('utf8').split('\n');
    if (lastLine) { lines[0] = lastLine + lines[0]; }
    lines.forEach(function(line, i) {
      if (i < lines.length - 1) {
        parseLine(line);
      } else {
        // Save the last line in case it has been broken up.
        lastLine = line;
      }
    });
    callback();
  };

  this.on('finish', function() {
    parseLine(lastLine);
    self.emit('end');
  });
};

util.inherits(m3u8parser, Writable);
<|endoftext|>


<commit_before>'use strict';

var _ = require('lodash');

exports.attributes = function(attr){
  var template = {
    facebookId: {
      type: 'integer',
      unique: true
    },
    name:{
      type: 'string'
    }
  };

  _.merge(template, attr);
  _.merge(attr, template);
};<commit_msg>Update auth.js<commit_after>'use strict';

var _ = require('lodash');

exports.attributes = function(attr){
  var template = {
    facebookId: {
      type: 'float',
      unique: true
    },
    name:{
      type: 'string'
    }
  };

  _.merge(template, attr);
  _.merge(attr, template);
};
<|endoftext|>


<commit_before>"use strict";

var xdTesting = require('./index');
var WebdriverIOMultiBrowser = require('webdriverio/lib/multibrowser');
var q = require('q');

/**
 * @constructor
 * @extends {Multibrowser}
 */
function MultiDevice(options) {
    WebdriverIOMultiBrowser.call(this);
    /**
     * @type {Object.<string, Device>}
     */
    this.options = options;
}

// Inherit from WebdriverIOMultiBrowser
MultiDevice.prototype = Object.create(WebdriverIOMultiBrowser.prototype);

/**
 * Modifier for multi instance.
 * @returns {Function} - Modify or add functionality for the given client
 * @override
 */
MultiDevice.prototype.getModifier = function () {

    var multiDevice = this;

    var stepIndex = 0;

    return function (client) {
        // Call parent method.
        let parentModifier = WebdriverIOMultiBrowser.prototype.getModifier.call(multiDevice);
        client = parentModifier.call(multiDevice, client);

        // Add additional functionality

        var _next = client.next;
        client.next = _next;

        //function next() {
        //    console.log('multidevice', arguments);
        //
        //    var self = this,
        //        promises = [],
        //        args = Array.prototype.slice.apply(arguments), // copy array
        //        stack = args.pop(),
        //        fnName = args.pop();
        //
        //    console.log(stepIndex, fnName);
        //
        //    stepIndex += 1;
        //
        //    return _next.apply(this, arguments)
        //        .then(() => {
        //            return client.forEach(device => {
        //                let screenShotName = './screenshots/step' + stepIndex + '_'
        //                    + device.options.id + '_' + fnName + '.png';
        //                console.log(screenShotName);
        //
        //                return device.saveScreenshot(screenShotName);
        //            });
        //        });
        //    //return client.lastPromise.done(function() {
        //    //    return client.forEach(device => saveScreenshot('./screenshots/step' + stepIndex + '_' + device.options.id + '_' + fnName + '.png'));
        //    //})
        //}

        // TODO add custom `select` return xdTesting.remote()

        /**
         * @callback DeviceCallback
         * @param {WebdriverIO.Client} device
         */

        /**
         * @callback DeviceIdsCallback
         * @return {number|number[]}
         */

        /**
         * @param {string[]|string|DeviceIdsCallback} ids - A single id or an array of ids; can also be a promise
         * @param {DeviceCallback} callback - receives the DeviceCollection as parameter
         */
        client.selectById = function selectById(ids, callback) {
            return client.call(function () {
                // Resolve ids callback
                if (ids instanceof Function) {
                    ids = ids()
                }
                // Normalize ids to array
                if (!Array.isArray(ids)) {
                    ids = [ids]
                }
                // TODO throw TypeError on invalid parameter types
                //if (typeof callback !== 'function') {
                //    throw new Error("Invalid callback");
                //}

                // TODO Refactor this: Merge with multiremote() ?

                let newOptions = {};
                let newMultiDevice = new MultiDevice(newOptions);
                ids.forEach(id => {
                    let instance = multiDevice.instances[id];

                    if(!instance) {
                        throw new Error('browser "' + id + '" is not defined');
                    }

                    newMultiDevice.addInstance(id, instance);
                    newOptions[id] = multiDevice.options[id];
                });
                var newRemote = xdTesting.remote(newOptions, newMultiDevice.getModifier(), newMultiDevice);

                return callback(newRemote);
            })
        };

        /**
         * @param {string[]|string} sizes - A single size or an array of sizes
         * @param {DeviceCallback} callback - receives the DeviceCollection as parameter
         */
        client.selectBySize = function selectBySize(sizes, callback) {
            sizes = Array.isArray(sizes) ? sizes : [sizes];

            var matchingInstanceIds = Object.keys(multiDevice.instances).filter(id => sizes.indexOf(multiDevice.options[id].size) >= 0);

            return client.selectById(matchingInstanceIds, callback);
        }

        /**
         * @param {string[]|string} types - A single type or an array of types
         * @param {DeviceCallback} callback - receives the DeviceCollection as parameter
         */
        client.selectByType = function selectByType(types, callback) {
            types = Array.isArray(types) ? types : [types];

            var matchingInstanceIds = Object.keys(multiDevice.instances).filter(id => types.indexOf(multiDevice.options[id].type) >= 0);

            return client.selectById(matchingInstanceIds, callback);
        }

        /**
         * Select all devices matching the selector parameter and execute the callback on them.
         * @param {string} selector - A css selector as used in WebdriverIO
         * @param {DeviceCallback} callback - receives the DeviceCollection as parameter
         */
        client.selectByElement = function selectByElement(selector, callback) {
            selector = selector || null

            let matchingInstanceIds = []

            return client
                .forEach(device => device
                    .elements(selector)
                    .then(response => {
                        if (response.value.length) {
                            matchingInstanceIds.push(device.options.id)
                        }
                    })
                )
                // Provide ids per callback, otherwise the array is read before it is filled
                .selectById(() => matchingInstanceIds, callback)
        }

        /**
         * Select any single device and execute the callback on it.
         * @param {DeviceCallback} callback - receives a single device as parameter
         */
        client.selectAny = function selectAny(callback) {
            let ids = []
            return client
                .forEach(device => ids.push(device.options.id))
                // Execute callback on the first device
                .selectById(() => ids[0], callback)
        }

        /**
         * @callback DeviceCallbackWithIndex
         * @param {WebdriverIO.Client} device
         * @param {number} index
         */

        /**
         * @param {DeviceCallbackWithIndex} callback
         */
        client.forEach = (callback) => {
            return client.call(function () {
                return q.all(Object.keys(multiDevice.instances).map(
                    (key, index) => callback(multiDevice.instances[key], index))
                );
            });
        };

        /**
         * @returns {number}
         */
        client.getCount = () => {
            let count = 0

            return client.forEach(device => {
                count++
            }).then(() => {
                return count
            })
        }

        return client;
    }
}

module.exports = MultiDevice
<commit_msg>Remove dead code<commit_after>"use strict";

var xdTesting = require('./index');
var WebdriverIOMultiBrowser = require('webdriverio/lib/multibrowser');
var q = require('q');

/**
 * @constructor
 * @extends {Multibrowser}
 */
function MultiDevice(options) {
    WebdriverIOMultiBrowser.call(this);
    /**
     * @type {Object.<string, Device>}
     */
    this.options = options;
}

// Inherit from WebdriverIOMultiBrowser
MultiDevice.prototype = Object.create(WebdriverIOMultiBrowser.prototype);

/**
 * Modifier for multi instance.
 * @returns {Function} - Modify or add functionality for the given client
 * @override
 */
MultiDevice.prototype.getModifier = function () {

    var multiDevice = this;

    var stepIndex = 0;

    return function (client) {
        // Call parent method.
        let parentModifier = WebdriverIOMultiBrowser.prototype.getModifier.call(multiDevice);
        client = parentModifier.call(multiDevice, client);

        // Add additional functionality

        var _next = client.next;
        client.next = _next;

        // TODO add custom `select` return xdTesting.remote()

        /**
         * @callback DeviceCallback
         * @param {WebdriverIO.Client} device
         */

        /**
         * @callback DeviceIdsCallback
         * @return {number|number[]}
         */

        /**
         * @param {string[]|string|DeviceIdsCallback} ids - A single id or an array of ids; can also be a promise
         * @param {DeviceCallback} callback - receives the DeviceCollection as parameter
         */
        client.selectById = function selectById(ids, callback) {
            return client.call(function () {
                // Resolve ids callback
                if (ids instanceof Function) {
                    ids = ids()
                }
                // Normalize ids to array
                if (!Array.isArray(ids)) {
                    ids = [ids]
                }
                // TODO throw TypeError on invalid parameter types
                //if (typeof callback !== 'function') {
                //    throw new Error("Invalid callback");
                //}

                // TODO Refactor this: Merge with multiremote() ?

                let newOptions = {};
                let newMultiDevice = new MultiDevice(newOptions);
                ids.forEach(id => {
                    let instance = multiDevice.instances[id];

                    if(!instance) {
                        throw new Error('browser "' + id + '" is not defined');
                    }

                    newMultiDevice.addInstance(id, instance);
                    newOptions[id] = multiDevice.options[id];
                });
                var newRemote = xdTesting.remote(newOptions, newMultiDevice.getModifier(), newMultiDevice);

                return callback(newRemote);
            })
        };

        /**
         * @param {string[]|string} sizes - A single size or an array of sizes
         * @param {DeviceCallback} callback - receives the DeviceCollection as parameter
         */
        client.selectBySize = function selectBySize(sizes, callback) {
            sizes = Array.isArray(sizes) ? sizes : [sizes];

            var matchingInstanceIds = Object.keys(multiDevice.instances).filter(id => sizes.indexOf(multiDevice.options[id].size) >= 0);

            return client.selectById(matchingInstanceIds, callback);
        }

        /**
         * @param {string[]|string} types - A single type or an array of types
         * @param {DeviceCallback} callback - receives the DeviceCollection as parameter
         */
        client.selectByType = function selectByType(types, callback) {
            types = Array.isArray(types) ? types : [types];

            var matchingInstanceIds = Object.keys(multiDevice.instances).filter(id => types.indexOf(multiDevice.options[id].type) >= 0);

            return client.selectById(matchingInstanceIds, callback);
        }

        /**
         * Select all devices matching the selector parameter and execute the callback on them.
         * @param {string} selector - A css selector as used in WebdriverIO
         * @param {DeviceCallback} callback - receives the DeviceCollection as parameter
         */
        client.selectByElement = function selectByElement(selector, callback) {
            selector = selector || null

            let matchingInstanceIds = []

            return client
                .forEach(device => device
                    .elements(selector)
                    .then(response => {
                        if (response.value.length) {
                            matchingInstanceIds.push(device.options.id)
                        }
                    })
                )
                // Provide ids per callback, otherwise the array is read before it is filled
                .selectById(() => matchingInstanceIds, callback)
        }

        /**
         * Select any single device and execute the callback on it.
         * @param {DeviceCallback} callback - receives a single device as parameter
         */
        client.selectAny = function selectAny(callback) {
            let ids = []
            return client
                .forEach(device => ids.push(device.options.id))
                // Execute callback on the first device
                .selectById(() => ids[0], callback)
        }

        /**
         * @callback DeviceCallbackWithIndex
         * @param {WebdriverIO.Client} device
         * @param {number} index
         */

        /**
         * @param {DeviceCallbackWithIndex} callback
         */
        client.forEach = (callback) => {
            return client.call(function () {
                return q.all(Object.keys(multiDevice.instances).map(
                    (key, index) => callback(multiDevice.instances[key], index))
                );
            });
        };

        /**
         * @returns {number}
         */
        client.getCount = () => {
            let count = 0

            return client.forEach(device => {
                count++
            }).then(() => {
                return count
            })
        }

        return client;
    }
}

module.exports = MultiDevice
<|endoftext|>


<commit_before>/*1487176174,,JIT Construction: v2835688,en_US*/

/**
 * Copyright Facebook Inc.
 *
 * Licensed under the Apache License, Version 2.0
 * http://www.apache.org/licenses/LICENSE-2.0
 */
try {(function(a,b,c,d){var e=a._fbq||(a._fbq=[]);if(e.push!==Array.prototype.push)return;var f=/^\d+$/,g='https://www.facebook.com/tr/',h={},i=[],j=c.href,k=b.referrer,l=a.top!==a;function m(v){var w=[];for(var x=0,y=v.length;x<y;x++)w.push(v[x][0]+'='+encodeURIComponent(v[x][1]));return w.join('&');}function n(v,w){var x=function y(){if(v.detachEvent){v.detachEvent('onload',y);}else v.onload=null;w();};if(v.attachEvent){v.attachEvent('onload',x);}else v.onload=x;}function o(v,w){var x='fb'+Math.random().toString().replace('.',''),y=b.createElement('form');y.method='post';y.action=v;y.target=x;y.acceptCharset='utf-8';y.style.display='none';var z=!!(a.attachEvent&&!a.addEventListener),aa=z?'<iframe name="'+x+'">':'iframe',ba=b.createElement(aa);ba.src='javascript:false';ba.id=x;ba.name=x;y.appendChild(ba);n(ba,function(){for(var ca=0,da=w.length;ca<da;ca++){var ea=b.createElement('input');ea.name=w[ca][0];ea.value=w[ca][1];y.appendChild(ea);}n(ba,function(){y.parentNode.removeChild(y);});y.submit();});b.body.appendChild(y);}h.addPixelId=function(v){i.push(v);};h.track=function(v,w){var x=typeof v;if(x!=='string'&&x!=='number')return false;if(f.test(v)){p(null,v,w);return true;}for(var y=0,z=i.length;y<z;y++)p(i[y],v,w);return i.length>0;};function p(v,w,x){var y=[];y.push(['id',v]);y.push(['ev',w]);y.push(['dl',j]);y.push(['rl',k]);y.push(['if',l]);y.push(['ts',new Date().valueOf()]);if(x&&typeof x==='object')for(var z in x)if(x.hasOwnProperty(z)){var aa=x[z],ba=aa===null?'null':typeof aa;if(ba in {number:1,string:1,boolean:1}){y.push(['cd['+encodeURIComponent(z)+']',aa]);}else if(ba==='object'){aa=typeof JSON==='undefined'?String(aa):JSON.stringify(aa);y.push(['cd['+encodeURIComponent(z)+']',aa]);}}var ca=m(y);if(2048>(g+'?'+ca).length){var da=new Image();da.src=g+'?'+ca;}else o(g,y);}var q=function v(w){if(Object.prototype.toString.call(w)!=='[object Array]')return false;var x=w.shift();if(!x)return false;var y=h[x];if(typeof y!=='function')return false;if(a._fbds){var z=a._fbds.pixelId;if(f.test(z)){i.push(z);delete a._fbds.pixelId;}}return y.apply(h,w);};for(var r=0,s=e.length;r<s;++r)q(e[r]);e.push=q;if(e.disablePushState===true)return;if(!d.pushState||!d.replaceState)return;var t=function v(){k=j;j=c.href;e.push(['track','PixelInitialized']);},u=function v(w,x,y){var z=w[x];w[x]=function(){var aa=z.apply(this,arguments);y.apply(this,arguments);return aa;};};u(d,'pushState',t);u(d,'replaceState',t);a.addEventListener('popstate',t,false);})(window,document,location,history);} catch (e) {new Image().src="https:\/\/www.facebook.com\/" + 'common/scribe_endpoint.php?c=jssdk_error&m='+encodeURIComponent('{"error":"LOAD", "extra": {"name":"'+e.name+'","line":"'+(e.lineNumber||e.line)+'","script":"'+(e.fileName||e.sourceURL||e.script)+'","stack":"'+(e.stackTrace||e.stack)+'","revision":"2835688","namespace":"FB","message":"'+e.message+'"}}');}<commit_msg>Deleted Remind_files/fbds.js<commit_after><|endoftext|>


<commit_before>Divvy.Buckets = {};

Divvy.Buckets.init = function()
{
	this.win = Ti.UI.createWindow({
		title: 'Buckets',
		barColor: Divvy.winBarColor,
		barImage: Divvy.winBarImage,
	});

	this.addButton = Ti.UI.createButton({
		systemButton: Ti.UI.iPhone.SystemButton.ADD
	});

	this.addDialog = Ti.UI.createOptionDialog({
		options: ['Join Existing Bucket', 'Create A Bucket', 'Cancel'],
		cancel: 2
	});

	this.addDialog.addEventListener('click', function(e){
		if (e.index == 0)
			Divvy.Join.open();
		else if (e.index == 1)
			Divvy.Create.open();
	});

	this.addButton.addEventListener('click', function(e){
		Divvy.Buckets.addDialog.show();
	});

	this.win.rightNavButton = this.addButton;

	this.tableview = Ti.UI.createTableView();
	this.tableview.addEventListener('click', function(e) {
		Divvy.View.open(e.row.bucketName, e.row.bucketId);
	});

	this.win.add(this.tableview);
};

Divvy.Buckets.open = function()
{
	this.refresh();
};

Divvy.Buckets.refresh = function()
{
	this.tableview.setData([]);
	var buckets = Ti.App.Properties.getList('buckets');

	if (buckets == null)
		return;

	for (var i = 0; i < buckets.length; i++)
	{
		this.tableview.appendRow(this.generateRow(buckets[i].name, buckets[i].id, 'http://lh4.ggpht.com/-d9CkOpNkGrE/TOS0XPbrf9I/AAAAAAAAADo/NQshQqW5Kkc/Thumbnail-100x100.png'));
	}
};

Divvy.Buckets.addBucket = function(name, id)
{
	//TODO: make sure the bucket doesn't exist first

	var currBuckets = Ti.App.Properties.getList('buckets');
	if (currBuckets == null)
		currBuckets = [];

	currBuckets.push({name: name, id: id});
	Ti.App.Properties.setList('buckets', currBuckets);
	Divvy.Buckets.refresh();
};

Divvy.Buckets.generateRow = function(name, id, image)
{
	var row = Ti.UI.createTableViewRow({
		className: 'bucketRow',
		height: 'auto',
		hasChild: true,
		bucketName: name,
		bucketId: id
	});

	row.add(Ti.UI.createImageView({
		width: '50', height: '50',
		top: 0, left: 0,
		image: image,
		hires: true
	}));

	row.add(Ti.UI.createLabel({
		text: name,
		height: 20,
		width: '230',
		top: 15, bottom: 15, left: 60,
		font: { fontWeight: 'bold', fontSize: 18 }
	}));

	return row;
};<commit_msg>Buckets now does image caching.<commit_after>Divvy.Buckets = {};

Divvy.Buckets.init = function()
{
	this.win = Ti.UI.createWindow({
		title: 'Buckets',
		barColor: Divvy.winBarColor,
		barImage: Divvy.winBarImage,
	});

	this.addButton = Ti.UI.createButton({
		systemButton: Ti.UI.iPhone.SystemButton.ADD
	});

	this.addDialog = Ti.UI.createOptionDialog({
		options: ['Join Existing Bucket', 'Create A Bucket', 'Cancel'],
		cancel: 2
	});

	this.addDialog.addEventListener('click', function(e){
		if (e.index == 0)
			Divvy.Join.open();
		else if (e.index == 1)
			Divvy.Create.open();
	});

	this.addButton.addEventListener('click', function(e){
		Divvy.Buckets.addDialog.show();
	});

	this.win.rightNavButton = this.addButton;

	this.tableview = Ti.UI.createTableView();
	this.tableview.addEventListener('click', function(e) {
		Divvy.View.open(e.row.bucketName, e.row.bucketId);
	});

	this.win.add(this.tableview);
};

Divvy.Buckets.open = function()
{
	this.refresh();
};

Divvy.Buckets.refresh = function()
{
	this.tableview.setData([]);
	var buckets = Ti.App.Properties.getList('buckets');

	if (buckets == null)
		return;

	for (var i = 0; i < buckets.length; i++)
	{
		this.tableview.appendRow(
			this.generateRow(
				buckets[i].name,
				buckets[i].id,
				'http://lh4.ggpht.com/-d9CkOpNkGrE/TOS0XPbrf9I/AAAAAAAAADo/NQshQqW5Kkc/Thumbnail-100x100.png'
			)
		);
	}
};

Divvy.Buckets.addBucket = function(name, id)
{
	//TODO: make sure the bucket doesn't exist first

	var currBuckets = Ti.App.Properties.getList('buckets');
	if (currBuckets == null)
		currBuckets = [];

	currBuckets.push({name: name, id: id});
	Ti.App.Properties.setList('buckets', currBuckets);
	Divvy.Buckets.refresh();
};

Divvy.Buckets.generateRow = function(name, id, image)
{
	var row = Ti.UI.createTableViewRow({
		className: 'bucketRow',
		height: 'auto',
		hasChild: true,
		bucketName: name,
		bucketId: id
	});

	var imageView = Ti.UI.createImageView({
		width: '50', height: '50',
		top: 0, left: 0,
		hires: true
	});

	row.add(imageView);

	Network.cache.run(
		image,
		168, //1 week
		Divvy.Buckets.onImageCacheSuccess,
		Divvy.Buckets.onImageCacheError,
		imageView
	);

	row.add(Ti.UI.createLabel({
		text: name,
		height: 20,
		width: '230',
		top: 15, bottom: 15, left: 60,
		font: { fontWeight: 'bold', fontSize: 18 }
	}));

	return row;
};

Divvy.Buckets.onImageCacheSuccess = function(data, date, status, user, xhr)
{
	user.image = data;
};

Divvy.Buckets.onImageCacheError = function(status, httpStatus)
{
	//do nothing
};<|endoftext|>