<commit_before>/*
 * grunt-less-to-json
 * https://github.com/jleonard/grunt-less-to-json
 *
 * Copyright (c) 2013 jleonard
 * Licensed under the MIT license.
 */

'use strict';

module.exports = function(grunt) {

  // Please see the Grunt documentation for more information regarding task
  // creation: http://gruntjs.com/creating-tasks

  grunt.registerMultiTask('less_to_json', 'The best Grunt plugin ever.', function() {
    // Merge task-specific and/or target-specific options with these defaults.
    var options = this.options({
      punctuation: '.',
      separator: ', '
    });

    // Iterate over all specified file groups.
    this.files.forEach(function(fileObj){
      var files = grunt.file.expand({nonull: true}, fileObj.src);
      var dest = options.dest;
      var src = files.map(function(filepath){
        if (!grunt.file.exists(filepath)) {

        }else{
          var file = grunt.file.read(filepath);
          file = removeComments(file);
          file = file.replace(/ /g,"").replace(/\t/g,"").replace(/\n/g,"");
          var arr = file.split(";");
          console.log('your array is ',arr);
          var len = arr.length;
          var obj = {};
          for (var i = 0; i < len -1; i++) {
            var key_val = arr[i].split(":");
            if(key_val.length === 1){ continue; }
            obj[key_val[0]] = key_val[0];
          }

          for (var key in obj) {
             if (obj.hasOwnProperty(key)) {
                var value = obj[key];
                if(value.indexOf('@') === 1){
                  obj[key] = obj[value];
                }
             }
          }
          console.log('your object is ',obj);
          //grunt.file.write(dest,html);
        }
      });

    });

    function removeComments(str) {

        var uid = '_' + +new Date(),
            primatives = [],
            primIndex = 0;

        return (
            str
            /* Remove strings */
            .replace(/(['"])(\\\1|.)+?\1/g, function(match){
                primatives[primIndex] = match;
                return (uid + '') + primIndex++;
            })

            /* Remove Regexes */
            .replace(/([^\/])(\/(?!\*|\/)(\\\/|.)+?\/[gim]{0,3})/g, function(match, $1, $2){
                primatives[primIndex] = $2;
                return $1 + (uid + '') + primIndex++;
            })

            /*
            - Remove single-line comments that contain would-be multi-line delimiters
                E.g. // Comment /* <--
            - Remove multi-line comments that contain would be single-line delimiters
                E.g. /* // <--
           */
            .replace(/\/\/.*?\/?\*.+?(?=\n|\r|$)|\/\*[\s\S]*?\/\/[\s\S]*?\*\//g, '')

            /*
            Remove single and multi-line comments,
            no consideration of inner-contents
           */
            .replace(/\/\/.+?(?=\n|\r|$)|\/\*[\s\S]+?\*\//g, '')

            /*
            Remove multi-line comments that have a replaced ending (string/regex)
            Greedy, so no inner strings/regexes will stop it.
           */
            .replace(RegExp('\\/\\*[\\s\\S]+' + uid + '\\d+', 'g'), '')

            /* Bring back strings & regexes */
            .replace(RegExp(uid + '(\\d+)', 'g'), function(match, n){
                return primatives[n];
            })
        );

    }
  });
}
<commit_msg>bug fix<commit_after>/*
 * grunt-less-to-json
 * https://github.com/jleonard/grunt-less-to-json
 *
 * Copyright (c) 2013 jleonard
 * Licensed under the MIT license.
 */

'use strict';

module.exports = function(grunt) {

  // Please see the Grunt documentation for more information regarding task
  // creation: http://gruntjs.com/creating-tasks

  grunt.registerMultiTask('less_to_json', 'The best Grunt plugin ever.', function() {
    // Merge task-specific and/or target-specific options with these defaults.
    var options = this.options({
      punctuation: '.',
      separator: ', '
    });

    // Iterate over all specified file groups.
    this.files.forEach(function(fileObj){
      var files = grunt.file.expand({nonull: true}, fileObj.src);
      var dest = options.dest;
      var src = files.map(function(filepath){
        if (!grunt.file.exists(filepath)) {

        }else{
          var file = grunt.file.read(filepath);
          file = removeComments(file);
          file = file.replace(/ /g,"").replace(/\t/g,"").replace(/\n/g,"");
          var arr = file.split(";");
          console.log('your array is ',arr);
          var len = arr.length;
          var obj = {};
          for (var i = 0; i < len -1; i++) {
            var key_val = arr[i].split(":");
            if(key_val.length === 1){ continue; }
            obj[key_val[0]] = key_val[0];
          }

          for (var key in obj) {
             if (obj.hasOwnProperty(key)) {
                var value = obj[key];
                if(value.indexOf('@') === 1){
                  console.log('value ',value);
                  obj[key] = obj[value];
                }
             }
          }
          console.log('your object is ',obj);
          //grunt.file.write(dest,html);
        }
      });

    });

    function removeComments(str) {

        var uid = '_' + +new Date(),
            primatives = [],
            primIndex = 0;

        return (
            str
            /* Remove strings */
            .replace(/(['"])(\\\1|.)+?\1/g, function(match){
                primatives[primIndex] = match;
                return (uid + '') + primIndex++;
            })

            /* Remove Regexes */
            .replace(/([^\/])(\/(?!\*|\/)(\\\/|.)+?\/[gim]{0,3})/g, function(match, $1, $2){
                primatives[primIndex] = $2;
                return $1 + (uid + '') + primIndex++;
            })

            /*
            - Remove single-line comments that contain would-be multi-line delimiters
                E.g. // Comment /* <--
            - Remove multi-line comments that contain would be single-line delimiters
                E.g. /* // <--
           */
            .replace(/\/\/.*?\/?\*.+?(?=\n|\r|$)|\/\*[\s\S]*?\/\/[\s\S]*?\*\//g, '')

            /*
            Remove single and multi-line comments,
            no consideration of inner-contents
           */
            .replace(/\/\/.+?(?=\n|\r|$)|\/\*[\s\S]+?\*\//g, '')

            /*
            Remove multi-line comments that have a replaced ending (string/regex)
            Greedy, so no inner strings/regexes will stop it.
           */
            .replace(RegExp('\\/\\*[\\s\\S]+' + uid + '\\d+', 'g'), '')

            /* Bring back strings & regexes */
            .replace(RegExp(uid + '(\\d+)', 'g'), function(match, n){
                return primatives[n];
            })
        );

    }
  });
}
<|endoftext|>


<commit_before>// this is adapated from https://github.com/gregrperkins/grunt-mocha-hack

"use strict";

module.exports = function(grunt) {
  var createDomain = require('domain').create;
  var mocha = require('./lib/mocha-runner');
  var mochaReporterBase = require('mocha/lib/reporters/base');
  var wd = require('wd');
  var appiumLauncher = require('./lib/appium-launcher');
  var _ = grunt.util._;

  grunt.registerMultiTask('mochaAppium', 'Run functional tests with mocha', function() {
    var done = this.async();
    // Retrieve options from the grunt task.
    var options = this.options({
      usePromises: false
    });

    // We want color in our output, but when grunt-contrib-watch is used,
    //  mocha will detect that it's being run to a pipe rather than tty.
    // Mocha provides no way to force the use of colors, so, again, hack it.
    var priorUseColors = mochaReporterBase.useColors;
    if (options.useColors) {
      mochaReporterBase.useColors = true;
    }

    // More agnostic -- just remove *all* the uncaughtException handlers;
    //  they're almost certainly going to exit the process, which,
    //  in this case, is definitely not what we want.
    var uncaughtExceptionHandlers = process.listeners('uncaughtException');
    process.removeAllListeners('uncaughtException');
    var unmanageExceptions = function() {
      uncaughtExceptionHandlers.forEach(
        process.on.bind(process, 'uncaughtException'));
    };
    // Better, deals with more than just grunt?

    // Restore prior state.
    var restore = function() {
      mochaReporterBase.useColors = priorUseColors;
      unmanageExceptions();
      done();
    };

    grunt.util.async.forEachSeries(this.files, function(fileGroup, next){
      runTests(fileGroup, options, next);
    }, restore);
  });

  function runTests(fileGroup, options, next){

    // When we're done with mocha, dispose the domain
    var mochaDone = function(errCount) {
      var withoutErrors = (errCount === 0);
      // Indicate whether we failed to the grunt task runner
      next(withoutErrors);
    };

    // launch appium
    appiumLauncher(_.pick(options, 'appiumPath', 'appiumArgs'), function(err, appium){
      grunt.log.writeln('Appium Running');
      if(err){
        appium.kill();
        grunt.fail.fatal(err);
        return;
      }

      appium.stdout.on('data', function(data){
        grunt.log.debug('Appium > '+ data.toString().replace('\n', ''));
      });

      appium.stderr.on('data', function(data){
        // Appium has debug logging to stderr, so supress these logs with
        // --verbose since they're not actual errors.
        grunt.log.verbose.error('Appium > '+ data);
      });

      var remote = options.usePromises ? 'promiseChainRemote' : 'remote';
      if(options.lib){
        var libs = require('fs').readdirSync(options.lib)
        for(var i = 0;i<libs.length;i++){
          require(options.lib + "/" + libs[i])(wd)
        }
      }

      var browser = wd[remote](appium.host, appium.port);

      var opts = _.omit(options, 'usePromises', 'appiumPath');

      browser.on('status', function(info){
        grunt.log.writeln('\x1b[36m%s\x1b[0m', info);
      });

      browser.on('command', function(meth, path, data){
        grunt.log.debug(' > \x1b[33m%s\x1b[0m: %s', meth, path, data || '');
      });

      browser.init(opts, function(err){
        if(err){
          grunt.fail.fatal(err);
          return;
        }

        var runner = mocha(options,browser,wd, grunt, fileGroup);
        // Create the domain, and pass any errors to the mocha runner
        var domain = createDomain();
        domain.on('error', runner.uncaught.bind(runner));

        // Give selenium some breathing room
        setTimeout(function(){
          // Selenium Download and Launch
          domain.run(function() {
            runner.run(function(err){
              browser.quit(function(){
                appium.kill();
                mochaDone(err);
              });
            });
          });
        }, 300);
      });

    });

  }
};
<commit_msg>ios_webkit support added<commit_after>// this is adapated from https://github.com/gregrperkins/grunt-mocha-hack

"use strict";

module.exports = function(grunt) {
  var createDomain = require('domain').create;
  var mocha = require('./lib/mocha-runner');
  var mochaReporterBase = require('mocha/lib/reporters/base');
  var spawn = require('child_process').spawn;
  var wd = require('wd');
  var appiumLauncher = require('./lib/appium-launcher');
  var _ = grunt.util._;
  var ios_webkit;

  grunt.registerMultiTask('mochaAppium', 'Run functional tests with mocha', function() {
    var done = this.async();
    // Retrieve options from the grunt task.
    var options = this.options({
      usePromises: false
    });

    // We want color in our output, but when grunt-contrib-watch is used,
    //  mocha will detect that it's being run to a pipe rather than tty.
    // Mocha provides no way to force the use of colors, so, again, hack it.
    var priorUseColors = mochaReporterBase.useColors;
    if (options.useColors) {
      mochaReporterBase.useColors = true;
    }

    // More agnostic -- just remove *all* the uncaughtException handlers;
    //  they're almost certainly going to exit the process, which,
    //  in this case, is definitely not what we want.
    var uncaughtExceptionHandlers = process.listeners('uncaughtException');
    process.removeAllListeners('uncaughtException');
    var unmanageExceptions = function() {
      uncaughtExceptionHandlers.forEach(
        process.on.bind(process, 'uncaughtException'));
    };
    // Better, deals with more than just grunt?

    // Restore prior state.
    var restore = function() {
      mochaReporterBase.useColors = priorUseColors;
      unmanageExceptions();
      done();
    };

    grunt.util.async.forEachSeries(this.files, function(fileGroup, next){
      runTests(fileGroup, options, next);
    }, restore);
  });

  function runTests(fileGroup, options, next){

    // When we're done with mocha, dispose the domain
    var mochaDone = function(errCount) {
      var withoutErrors = (errCount === 0);
      // Indicate whether we failed to the grunt task runner
      next(withoutErrors);
    };

    // launch appium
    if(options.platformName == 'iOS'){
      ios_webkit = spawn('ios_webkit_debug_proxy',['-c', options.udid+':27753','-d'])
      ios_webkit.stdout.on('data', function(data){
        //grunt.log.debug('ios > '+ data.toString().replace('\n', ''));
      });
      ios_webkit.stderr.on('data', function(data){
        //grunt.log.verbose.error('ios > '+ data);
      });
    }

    appiumLauncher(_.pick(options, 'appiumPath', 'appiumArgs'), function(err, appium){
      grunt.log.writeln('Appium Running');
      if(err){
        appium.kill();
        if(ios_webkit)
          ios_webkit.kill();
        grunt.fail.fatal(err);
        return;
      }

      appium.stdout.on('data', function(data){
        grunt.log.debug('Appium > '+ data.toString().replace('\n', ''));
      });

      appium.stderr.on('data', function(data){
        // Appium has debug logging to stderr, so supress these logs with
        // --verbose since they're not actual errors.
        grunt.log.verbose.error('Appium > '+ data);
      });

      var remote = options.usePromises ? 'promiseChainRemote' : 'remote';
      if(options.lib){
        var libs = require('fs').readdirSync(options.lib)
        for(var i = 0;i<libs.length;i++){
          require(options.lib + "/" + libs[i])(wd)
        }
      }

      var browser = wd[remote](appium.host, appium.port);

      var opts = _.omit(options, 'usePromises', 'appiumPath');

      browser.on('status', function(info){
        grunt.log.writeln('\x1b[36m%s\x1b[0m', info);
      });

      browser.on('command', function(meth, path, data){
        grunt.log.debug(' > \x1b[33m%s\x1b[0m: %s', meth, path, data || '');
      });

      browser.init(opts, function(err){
        if(err){
          grunt.fail.fatal(err);
          return;
        }

        var runner = mocha(options,browser,wd, grunt, fileGroup);
        // Create the domain, and pass any errors to the mocha runner
        var domain = createDomain();
        domain.on('error', runner.uncaught.bind(runner));

        // Give selenium some breathing room
        setTimeout(function(){
          // Selenium Download and Launch
          domain.run(function() {
            runner.run(function(err){
              browser.quit(function(){
                appium.kill();
                if(ios_webkit)
                  ios_webkit.kill();
                mochaDone(err);
              });
            });
          });
        }, 300);
      });

    });

  }
};
<|endoftext|>


<commit_before>import type { Action } from './types';
import { Actions } from 'react-native-router-flux';

export const GET_QUESTIONS        = 'GET_QUESTIONS';
export const SET_QUESTION         = 'SET_QUESTION';

export const CREATE_ANSWER_OBJECT = 'CREATE_ANSWER_OBJECT';
export const SET_ANSWER           = 'SET_ANSWER';
export const RESET_RATING         = 'RESET_RATING';
export const ANSWER_CHANGED       = 'ANSWER_CHANGED';
export const TEXT_INPUT_CHANGED   = 'TEXT_INPUT_CHANGED';
export const SYMPTOM_INPUT_CHANGED   = 'SYMPTOM_INPUT_CHANGED';

export const SET_SYMPTOM          = 'SET_SYMPTOM';
export const SYMPTOM_CHANGED      = 'SYMPTOM_CHANGED';
export const CREATE_SYMPTOM       = 'CREATE_SYMPTOM';
export const ADD_SYMPTOM          = 'ADD_SYMPTOM';

export const getQuestions = ({ token }) => {
      return (dispatch) => {
          fetch(myUrl + '/api/questions', {
                method: 'GET',
                headers: {
                'Accept': 'application/json',
                'Content-Type': 'application/json',
                'Authorization': 'JWT '+token,
                },
                })
                .then(response => {
                     const str = JSON.stringify(eval('(' + response._bodyInit + ')'));
                     const parsed = JSON.parse(str);
                     console.log('Question: ' + parsed);
                     setQuestions(dispatch, parsed);
                 });
     };
};

const setQuestions = (dispatch, questions) => {
    dispatch({
        type: GET_QUESTIONS,
        payload: questions
    });
};

export const setQuestion = (question) => {
    return {
        type: SET_QUESTION,
        payload: question
    };
}

export const textChanged = (text) => {
    return {
        type: TEXT_INPUT_CHANGED,
        payload: text
    };
};

export const symptomChanged = (text) => {
    return {
        type: SYMPTOM_INPUT_CHANGED,
        payload: text
    };
};

export function add(item) {
	return {
		type: ADD_SYMPTOM,
		item
	}
}
export const answerChanged = (rating, question) => {
    console.log(rating, question)
    if (parseInt(question) < 9) {
        const options = {
            'Not at all':     0,
            'Slightly':       1,
            'Moderately':     2,
            'Severely':       3,
            'Overwhelmingly': 4,
            'Ntanarimwe':     0,
            'Bukeya':         1,
            'Buringaniye':    2,
            'Byinshi':        3,
            'Byinshi cyane':  4
        };

        return {
            type: ANSWER_CHANGED,
            payload: options[rating]
        };
    }
    else {
        const options = {
            'Yes':              0,
            'Most of the time': 1,
            'Sometimes':        2,
            'Occasionally':     3,
            'Not at all':       4,
            'Yego':             0,
            'Kenshi cyane':     1,
            'Rimwe narimwe':    2,
            'Sikenshi':         3,
            'Ntanarimwe':       4
        };

        return {
            type: ANSWER_CHANGED,
            payload: options[rating]
        };

    }

};

export const resetRating = (rating) => {
    rating = '';

    return {
        type: RESET_RATING,
        payload: rating
    };
};

export const setAnswer = ({ record, question, textInput, rating }) => {
    return {
        type: SET_ANSWER,
        payload: { prop, value }
    };
};

export const createAnswerObject = ({ record, question, text_input, rating }) => {
    if ((rating === undefined) || (rating === '')) {
        rating = null;
    }

    if (text_input === undefined) {
        text_input = '';
    }

    let answerObj = new Object();

    answerObj = {
        "answer":   rating,
        "text":     text_input,
        "question": question,
        "record":   record
    };

    return {
        type: CREATE_ANSWER_OBJECT,
        payload: answerObj
    };
};

export const setSymptom = ({ record, symptom, rating }) => {
    return {
        type: SET_SYMPTOM,
        payload: { prop, value }
    };
};

export const createSymptomObject = ({ record, symptom, rating }) => {
    if (rating === undefined) {
        rating = 0;
    }

    if (symptom === undefined) {
        symptom = '';
    }

    let symptomObj = new Object();

    symptomObj = {
        "answer":   rating,
        "symptom":  symptom,
        "record":   record
    };

    return {
        type: CREATE_SYMPTOM,
        payload: symptomObj
    };
};

export const updateAnswer = ({ token, record, question, rating, text }) => {
    return (dispatch) => {
        console.log("Updating the answer and calling the api to send the answer responses");
        fetch(myUrl + '/api/edit_answer/' + record + '/' + question, {
                   method: 'PUT',
                   headers: {
                   'Accept': 'application/json',
                   'Content-Type': 'application/json',
                   'Authorization': 'JWT '+token,
                   },

                   body: JSON.stringify({
                   text: text,
                   answer: rating
                   })
                   })
                   .then((response) => {
                        console.log('UPDATED',response);
                        if (response.status === 200) {
                            dispatch({ type: ANSWER_CREATE });
                        }
                   });
    };
};<commit_msg>remove comment in answer file<commit_after>import type { Action } from './types';
import { Actions } from 'react-native-router-flux';

export const GET_QUESTIONS        = 'GET_QUESTIONS';
export const SET_QUESTION         = 'SET_QUESTION';

export const CREATE_ANSWER_OBJECT = 'CREATE_ANSWER_OBJECT';
export const SET_ANSWER           = 'SET_ANSWER';
export const RESET_RATING         = 'RESET_RATING';
export const ANSWER_CHANGED       = 'ANSWER_CHANGED';
export const TEXT_INPUT_CHANGED   = 'TEXT_INPUT_CHANGED';
export const SYMPTOM_INPUT_CHANGED   = 'SYMPTOM_INPUT_CHANGED';

export const SET_SYMPTOM          = 'SET_SYMPTOM';
export const SYMPTOM_CHANGED      = 'SYMPTOM_CHANGED';
export const CREATE_SYMPTOM       = 'CREATE_SYMPTOM';
export const ADD_SYMPTOM          = 'ADD_SYMPTOM';

export const getQuestions = ({ token }) => {
      return (dispatch) => {
          fetch(myUrl + '/api/questions', {
                method: 'GET',
                headers: {
                'Accept': 'application/json',
                'Content-Type': 'application/json',
                'Authorization': 'JWT '+token,
                },
                })
                .then(response => {
                     const str = JSON.stringify(eval('(' + response._bodyInit + ')'));
                     const parsed = JSON.parse(str);
                     console.log('Question: ' + parsed);
                     setQuestions(dispatch, parsed);
                 });
     };
};

const setQuestions = (dispatch, questions) => {
    dispatch({
        type: GET_QUESTIONS,
        payload: questions
    });
};

export const setQuestion = (question) => {
    return {
        type: SET_QUESTION,
        payload: question
    };
}

export const textChanged = (text) => {
    return {
        type: TEXT_INPUT_CHANGED,
        payload: text
    };
};

export const symptomChanged = (text) => {
    return {
        type: SYMPTOM_INPUT_CHANGED,
        payload: text
    };
};

export function add(item) {
	return {
		type: ADD_SYMPTOM,
		item
	}
}
export const answerChanged = (rating, question) => {
    if (parseInt(question) < 9) {
        const options = {
            'Not at all':     0,
            'Slightly':       1,
            'Moderately':     2,
            'Severely':       3,
            'Overwhelmingly': 4,
            'Ntanarimwe':     0,
            'Bukeya':         1,
            'Buringaniye':    2,
            'Byinshi':        3,
            'Byinshi cyane':  4
        };

        return {
            type: ANSWER_CHANGED,
            payload: options[rating]
        };
    }
    else {
        const options = {
            'Yes':              0,
            'Most of the time': 1,
            'Sometimes':        2,
            'Occasionally':     3,
            'Not at all':       4,
            'Yego':             0,
            'Kenshi cyane':     1,
            'Rimwe narimwe':    2,
            'Sikenshi':         3,
            'Ntanarimwe':       4
        };

        return {
            type: ANSWER_CHANGED,
            payload: options[rating]
        };

    }

};

export const resetRating = (rating) => {
    rating = '';

    return {
        type: RESET_RATING,
        payload: rating
    };
};

export const setAnswer = ({ record, question, textInput, rating }) => {
    return {
        type: SET_ANSWER,
        payload: { prop, value }
    };
};

export const createAnswerObject = ({ record, question, text_input, rating }) => {
    if ((rating === undefined) || (rating === '')) {
        rating = null;
    }

    if (text_input === undefined) {
        text_input = '';
    }

    let answerObj = new Object();

    answerObj = {
        "answer":   rating,
        "text":     text_input,
        "question": question,
        "record":   record
    };

    return {
        type: CREATE_ANSWER_OBJECT,
        payload: answerObj
    };
};

export const setSymptom = ({ record, symptom, rating }) => {
    return {
        type: SET_SYMPTOM,
        payload: { prop, value }
    };
};

export const createSymptomObject = ({ record, symptom, rating }) => {
    if (rating === undefined) {
        rating = 0;
    }

    if (symptom === undefined) {
        symptom = '';
    }

    let symptomObj = new Object();

    symptomObj = {
        "answer":   rating,
        "symptom":  symptom,
        "record":   record
    };

    return {
        type: CREATE_SYMPTOM,
        payload: symptomObj
    };
};

export const updateAnswer = ({ token, record, question, rating, text }) => {
    return (dispatch) => {
        console.log("Updating the answer and calling the api to send the answer responses");
        fetch(myUrl + '/api/edit_answer/' + record + '/' + question, {
                   method: 'PUT',
                   headers: {
                   'Accept': 'application/json',
                   'Content-Type': 'application/json',
                   'Authorization': 'JWT '+token,
                   },

                   body: JSON.stringify({
                   text: text,
                   answer: rating
                   })
                   })
                   .then((response) => {
                        console.log('UPDATED',response);
                        if (response.status === 200) {
                            dispatch({ type: ANSWER_CREATE });
                        }
                   });
    };
};<|endoftext|>


<commit_before>/**
 * grunt-npm-validate
 * https://github.com/joshuaspence/grunt-npm-validate
 *
 * Copyright (c) 2014 Joshua Spence
 * Licensed under the MIT license.
 */

'use strict';

var chalk = require('chalk'),
    PJV = require('package-json-validator').PJV;

function unary(fn) {
    return function(first) {
        return fn(first);
    };
}

module.exports = function(grunt) {
    grunt.registerTask('npm-validate', 'Opinionated package.json validator', function() {
        var options = this.options({
            file: grunt.config('pkgFile') || 'package.json'
        });

        var pkg = grunt.file.read(options.file);
        var result = PJV.validate(pkg);

        if (result.errors && result.errors.length) {
            grunt.log.subhead(chalk.bold(chalk.red('Errors:')));
            result.errors.forEach(unary(grunt.log.error));
        }

        if (result.warnings && result.warnings.length) {
            grunt.log.subhead(chalk.bold(chalk.yellow('Warnings:')));
            result.warnings.forEach(unary(grunt.log.warn));
        }

        if (result.recommendations && result.recommendations.length) {
            grunt.log.subhead(chalk.bold(chalk.yellow('Recommendations:')));
            result.recommendations.forEach(unary(grunt.log.warn));
        }
    });
};
<commit_msg>Fail if validate returned errors or warnings.<commit_after>/**
 * grunt-npm-validate
 * https://github.com/joshuaspence/grunt-npm-validate
 *
 * Copyright (c) 2014 Joshua Spence
 * Licensed under the MIT license.
 */

'use strict';

var chalk = require('chalk'),
    PJV = require('package-json-validator').PJV;

function unary(fn) {
    return function(first) {
        return fn(first);
    };
}

module.exports = function(grunt) {
    grunt.registerTask('npm-validate', 'Opinionated package.json validator', function() {
        var options = this.options({
            file: grunt.config('pkgFile') || 'package.json'
        });

        var pkg = grunt.file.read(options.file);
        var result = PJV.validate(pkg);

        if (result.errors && result.errors.length) {
            grunt.log.subhead(chalk.bold(chalk.red('Errors:')));
            result.errors.forEach(unary(grunt.log.error));
        }

        if (result.warnings && result.warnings.length) {
            grunt.log.subhead(chalk.bold(chalk.yellow('Warnings:')));
            result.warnings.forEach(unary(grunt.log.warn));
        }

        if (result.recommendations && result.recommendations.length) {
            grunt.log.subhead(chalk.bold(chalk.yellow('Recommendations:')));
            result.recommendations.forEach(unary(grunt.log.warn));
        }

        return result.errors || result.warnings;
    });
};
<|endoftext|>


<commit_before>define(["Ti/_", "Ti/_/dom", "Ti/_/lang"], function(_, dom, lang) {

	var global = window,
		sessionId = sessionStorage.getItem("ti:sessionId"),
		doc = document,
		cfg = require.config,
		analyticsEnabled = cfg.app.analytics,
		analyticsStorageName = "ti:analyticsEvents",
		analyticsEventSeq = 1,
		analyticsLastSent = null,
		analyticsUrl = "https://api.appcelerator.net/p/v2/mobile-web-track";

	sessionId || sessionStorage.setItem("ti:sessionId", sessionId = _.uuid());

	return _.analytics = {

		add: function(eventType, eventEvent, data, isUrgent) {
			if (analyticsEnabled) {
				// store event
				var storage = localStorage.getItem(analyticsStorageName);
					now = new Date(),
					tz = now.getTimezoneOffset(),
					atz = Math.abs(tz),
					formatZeros = function(v, n){
						var d = (v+'').length;
						return (d < n ? (new Array(++n - d)).join("0") : "") + v;
					};

				storage = storage ? JSON.parse(storage) : [];
				storage.push({
					eventId: _.uuid(),
					eventType: eventType,
					eventEvent: eventEvent,
					eventTimestamp: now.toISOString().replace('Z', (tz < 0 ? '-' : '+') + (atz < 100 ? "00" : (atz < 1000 ? "0" : "")) + atz),
					eventPayload: data
				});
				localStorage.setItem(analyticsStorageName, JSON.stringify(storage));
				this.send(isUrgent);
			}
		},

		send: function(isUrgent) {
			if (analyticsEnabled) {
				var i,
					evt,
					storage = JSON.parse(localStorage.getItem(analyticsStorageName)),
					now = (new Date()).getTime(),
					jsonStrs = [],
					ids = [];

				if (storage === null || (!isUrgent && analyticsLastSent !== null && now - analyticsLastSent < 300000 /* 5 minutes */)) {
					return;
				}

				analyticsLastSent = now;

				for (i = 0; i < storage.length; i++) {
					evt = storage[i];
					ids.push(evt.eventId);
					jsonStrs.push(JSON.stringify({
						seq: analyticsEventSeq++,
						ver: "2",
						id: evt.eventId,
						type: evt.eventType,
						event: evt.eventEvent,
						ts: evt.eventTimestamp,
						mid: Ti.Platform.id,
						sid: sessionId,
						aguid: cfg.guid,
						data: require.is(evt.eventPayload, "object") ? JSON.stringify(evt.eventPayload) : evt.eventPayload
					}));
				}

				function onSuccess() {
					// remove sent events on successful sent
					var j, k, found,
						storage = localStorage.getItem(analyticsStorageName),
						ev,
						evs = [];

					for (j = 0; j < storage.length; j++) {
						ev = storage[j];
						found = 0;
						for (k = 0; k < ids.length; k++) {
							if (ev.eventId == ids[k]) {
								found = 1;
								ids.splice(k, 1);
								break;
							}
						}
						found || evs.push(ev);
					}

					localStorage.setItem(analyticsStorageName, JSON.stringify(evs));
				}

				if (require.has("analytics-use-xhr")) {
					var xhr = new XmlHttpRequest;
					xhr.onreadystatechange = function() {
						if (xhr.readyState === 4 && xhr.status === 200) {
							try {
								var response = eval('(' + xhr.responseText + ')');
								response && response.success && onSuccess();
							} catch (e) {}
						}
					};
					xhr.open("POST", analyticsUrl, true);
					xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
					xhr.send(lang.urlEncode({ content: jsonStrs }));
				} else {
					var body = doc.body,
						rand = Math.floor(Math.random() * 1e6),
						iframeName = "analytics" + rand,
						callback = "mobileweb_jsonp" + rand,
						iframe = dom.create("iframe", {
							id: iframeName,
							name: iframeName,
							style: {
								display: "none"
							}
						}, body),
						form = dom.create("form", {
							action: analyticsUrl + "?callback=" + callback,
							method: "POST",
							style: {
								display: "none"
							},
							target: iframeName
						}, body);

					dom.create("input", {
						name: "content",
						type: "hidden",
						value: "[" + jsonStrs.join(",") + "]"
					}, form);

					global[callback] = function(response) {
						response && response.success && onSuccess();
					};

					// need to delay attaching of iframe events so they aren't prematurely called
					setTimeout(function() {
						function onIframeLoaded() {
							dom.destroy(form);
							dom.destroy(iframe);
						}
						iframe.onload = onIframeLoaded;
						iframe.onerror = onIframeLoaded;
						form.submit();
					}, 25);
				}
			}
		}

	};

});<commit_msg>[TIMOB-8002] Code cleanup.<commit_after>define(["Ti/_", "Ti/_/dom", "Ti/_/lang", "Ti/Platform"], function(_, dom, lang, Platform) {

	var global = window,
		sessionId = sessionStorage.getItem("ti:sessionId"),
		doc = document,
		cfg = require.config,
		analyticsEnabled = cfg.app.analytics,
		analyticsStorageName = "ti:analyticsEvents",
		analyticsEventSeq = 1,
		analyticsLastSent = null,
		analyticsUrl = "https://api.appcelerator.net/p/v2/mobile-web-track";

	sessionId || sessionStorage.setItem("ti:sessionId", sessionId = _.uuid());

	return _.analytics = {

		add: function(eventType, eventEvent, data, isUrgent) {
			if (analyticsEnabled) {
				// store event
				var storage = localStorage.getItem(analyticsStorageName);
					now = new Date(),
					tz = now.getTimezoneOffset(),
					atz = Math.abs(tz),
					formatZeros = function(v, n){
						var d = (v+'').length;
						return (d < n ? (new Array(++n - d)).join("0") : "") + v;
					};

				storage = storage ? JSON.parse(storage) : [];
				storage.push({
					eventId: _.uuid(),
					eventType: eventType,
					eventEvent: eventEvent,
					eventTimestamp: now.toISOString().replace('Z', (tz < 0 ? '-' : '+') + (atz < 100 ? "00" : (atz < 1000 ? "0" : "")) + atz),
					eventPayload: data
				});
				localStorage.setItem(analyticsStorageName, JSON.stringify(storage));
				this.send(isUrgent);
			}
		},

		send: function(isUrgent) {
			if (analyticsEnabled) {
				var i,
					evt,
					storage = JSON.parse(localStorage.getItem(analyticsStorageName)),
					now = (new Date()).getTime(),
					jsonStrs = [],
					ids = [];

				if (storage === null || (!isUrgent && analyticsLastSent !== null && now - analyticsLastSent < 300000 /* 5 minutes */)) {
					return;
				}

				analyticsLastSent = now;

				for (i = 0; i < storage.length; i++) {
					evt = storage[i];
					ids.push(evt.eventId);
					jsonStrs.push(JSON.stringify({
						seq: analyticsEventSeq++,
						ver: "2",
						id: evt.eventId,
						type: evt.eventType,
						event: evt.eventEvent,
						ts: evt.eventTimestamp,
						mid: Platform.id,
						sid: sessionId,
						aguid: cfg.guid,
						data: require.is(evt.eventPayload, "object") ? JSON.stringify(evt.eventPayload) : evt.eventPayload
					}));
				}

				function onSuccess() {
					// remove sent events on successful sent
					var j, k, found,
						storage = localStorage.getItem(analyticsStorageName),
						ev,
						evs = [];

					for (j = 0; j < storage.length; j++) {
						ev = storage[j];
						found = 0;
						for (k = 0; k < ids.length; k++) {
							if (ev.eventId == ids[k]) {
								found = 1;
								ids.splice(k, 1);
								break;
							}
						}
						found || evs.push(ev);
					}

					localStorage.setItem(analyticsStorageName, JSON.stringify(evs));
				}

				if (require.has("analytics-use-xhr")) {
					var xhr = new XmlHttpRequest;
					xhr.onreadystatechange = function() {
						if (xhr.readyState === 4 && xhr.status === 200) {
							try {
								var response = eval('(' + xhr.responseText + ')');
								response && response.success && onSuccess();
							} catch (e) {}
						}
					};
					xhr.open("POST", analyticsUrl, true);
					xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
					xhr.send(lang.urlEncode({ content: jsonStrs }));
				} else {
					var body = doc.body,
						rand = Math.floor(Math.random() * 1e6),
						iframeName = "analytics" + rand,
						callback = "mobileweb_jsonp" + rand,
						iframe = dom.create("iframe", {
							id: iframeName,
							name: iframeName,
							style: {
								display: "none"
							}
						}, body),
						form = dom.create("form", {
							action: analyticsUrl + "?callback=" + callback,
							method: "POST",
							style: {
								display: "none"
							},
							target: iframeName
						}, body);

					dom.create("input", {
						name: "content",
						type: "hidden",
						value: "[" + jsonStrs.join(",") + "]"
					}, form);

					global[callback] = function(response) {
						response && response.success && onSuccess();
					};

					// need to delay attaching of iframe events so they aren't prematurely called
					setTimeout(function() {
						function onIframeLoaded() {
							dom.destroy(form);
							dom.destroy(iframe);
						}
						iframe.onload = onIframeLoaded;
						iframe.onerror = onIframeLoaded;
						form.submit();
					}, 25);
				}
			}
		}

	};

});<|endoftext|>


<commit_before>// resources.js
//  This module should be responsable for loading things.
// every request made by the engine should be centralized in
// this module.

var resources = {
    init: {},
    tileset: null,
    playerChara: null,
    printerset: null,
    playerCharaset: null,
    faceset: null,
    feedback: {},
    items: {},
    levels: {},
    charasets: {},
    charas: {},
    hms: {}
};

resources.harvest = function(callback) {
    // the idea here is to loadInit, and then
    // analyze the init file in loadAfterInit
    // and scheduleLoad of all needed json files.
    //
    // than, ask for the loading of all of them with
    // loadFromSchedule.
    //
    // doLoad should be asked in the return and
    // if checkAllLoaded, should load all needed
    // images and then, after all images are loaded
    // throw the finalCallback
    //
    //

    resources.finalCallback = callback;
    var DESCRIPTORS = "descriptors/";
    var CHARASETS = "charaset/";
    var LEVELS = "levels/";
    var MUSIC = "audio/music/";

    this.faceset = document.getElementById("faceset");
    this.charasetimg = document.getElementById("charasetimg");
    this.printerset = document.getElementById("printerimg");
    this.monsterimg = document.getElementById("monsterbattleimg");
    this.tile = {};
    this.pictures = {};
    this.syspictures = {};
    this.music = {};
    this.syspictures.title = document.getElementById("titleimg");
    this.syspictures.keys1 = document.getElementById("keys1");
    this.syspictures.keys2 = document.getElementById("keys2");
    this.syspictures.controllers = document.getElementById("controllers");

    this.tileslist = [];

    this.loadingList = [];

    var audioSupport = function() {
        var audioTest = (typeof Audio !== 'undefined') ? new Audio() : null;

        if (!audioTest || typeof audioTest.canPlayType !== 'function') {
        return {
            mp3: false,
            ogg: false,
            wav: false,
            aac: false
          };
        }

        var mpegTest = audioTest.canPlayType('audio/mpeg;').replace(/^no$/, '');

        return {
            mp3: !!(mpegTest || audioTest.canPlayType('audio/mp3;').replace(/^no$/, '')),
            ogg: !!audioTest.canPlayType('audio/ogg; codecs="vorbis"').replace(/^no$/, ''),
            wav: !!audioTest.canPlayType('audio/wav; codecs="1"').replace(/^no$/, ''),
            aac: !!audioTest.canPlayType('audio/aac;').replace(/^no$/, '')
        };

    };

    this.audioSupport = audioSupport()

    var loadInit = function(){
        var request = new XMLHttpRequest();
        request.onreadystatechange = function() {
            if (this.readyState == 4 && this.status == 200) {
                resources.init = JSON.parse(this.responseText); //this is fake code!!!!
                resources.loadAfterInit();
            }
        };
        request.open('GET', DESCRIPTORS + 'init.json', true);
        request.send();
    };

    var scheduleLoad = function(toWhere, fromUrl, fileType, tinyCallback){
        resources.loadingList.push({
            to: toWhere,
            from: fromUrl,
            fileType: fileType,
            loaded: false,
            isScheduled: false,
            tinyCallback: tinyCallback
        });
    };

    var loadFromSchedule = function(){
        for(var i=0; i<resources.loadingList.length ; i++){
            resources.doLoad(i);
        }
    };

    var loadAllImages = function(){

        pic_i = 0
        tile_i = 0

        function loadImages(src, callback) {
            if(tile_i < resources.tileslist.length){
                resources.tile[src] = new Image();
                resources.tile[src].onload = function() {
                    tile_i++;
                    if (tile_i < resources.tileslist.length) {
                        loadImages(resources.tileslist[tile_i], callback);
                    } else if (pic_i < resources.pictureList.length){
                        loadImages(resources.pictureList[pic_i], callback);
                    } else {
                        callback();
                    }
                };
                resources.tile[src].src = src;
            } else {
                var name = src;
                resources.pictures[name] = new Image();
                resources.pictures[name].onload = function() {
                    pic_i++;
                    if(pic_i < resources.pictureList.length){
                        loadImages(resources.pictureList[pic_i], callback);
                    } else {
                        callback();
                    }
                };
                resources.pictures[name].src = 'img/pictures/'+name+'.png';
            }
        }

        loadImages(resources.tileslist[tile_i], resources.finalCallback);
    };

    this.checkAllLoaded = function(){
        var allLoaded = true;
        for(var i=0; i<resources.loadingList.length ; i++){
            var resDict = resources.loadingList[i];
            allLoaded = allLoaded && resDict.loaded;
        }

        if(allLoaded){
            loadAllImages();
        }
    };

    this.doLoad = function(i){
        var resDict = resources.loadingList[i];
        if(resDict.isScheduled){
            return;
        }

        if(resDict.fileType == 'json'){
            var request = new XMLHttpRequest();
            request.onreadystatechange = function() {
                if (this.readyState == 4 && this.status == 200) {
                    if(resDict.to[0]=='charasets'){
                        resources['charasets'] = JSON.parse(this.responseText)['Charaset'];
                    } else if (resDict.to[0]=='feedback') {
                        resources['feedback'] = JSON.parse(this.responseText)['Feedback'];
                    } else if (resDict.to[0]=='charas'){
                        resources['charas'] = JSON.parse(this.responseText)['Charas'];
                    } else if (resDict.to[0]=='items'){
                        resources['items'] = JSON.parse(this.responseText)['Items'];
                    } else {
                        if(resDict.to.length == 1){
                            resources[resDict.to[0]] = JSON.parse(this.responseText);
                        } else if(resDict.to.length == 2){
                            resources[resDict.to[0]][resDict.to[1]] = JSON.parse(this.responseText);
                        } else  if(resDict.to.length == 3){
                            resources[resDict.to[0]][resDict.to[1]][resDict.to[2]] = JSON.parse(this.responseText);
                        }
                    }
                    resDict.loaded = true;
                    if(typeof resDict.tinyCallback === 'function'){
                        resDict.tinyCallback();
                    }
                    resources.checkAllLoaded();
                }
            };
            request.open('GET', resDict.from, true);
            request.send();
            resDict.isScheduled = true;
        }
        if(resDict.fileType == 'ogg'){
          var loadeddata = (function(resDict){
              return function() {
                resDict.loaded = true;
                if(typeof resDict.tinyCallback === 'function'){
                    resDict.tinyCallback();
                }
                resources.checkAllLoaded();
                resources[resDict.to[0]][resDict.to[1]].removeEventListener('loadeddata',loadeddata);
              }
            })(resDict);

          resources[resDict.to[0]][resDict.to[1]]  = document.createElement('audio');
          resources[resDict.to[0]][resDict.to[1]].id = resDict.to[1];
          resources[resDict.to[0]][resDict.to[1]].loop = true;
          resources[resDict.to[0]][resDict.to[1]].addEventListener('error', function failed(e) {
             // audio playback failed - show a message saying why
             // to get the source of the audio element use $(this).src
             switch (e.target.error.code) {
               case e.target.error.MEDIA_ERR_ABORTED:
                 alert('You aborted the video playback.');
                 break;
               case e.target.error.MEDIA_ERR_NETWORK:
                 alert('A network error caused the audio download to fail.');
                 break;
               case e.target.error.MEDIA_ERR_DECODE:
                 alert('The audio playback was aborted due to a corruption problem or because the video used features your browser did not support.');
                 break;
               case e.target.error.MEDIA_ERR_SRC_NOT_SUPPORTED:
                 alert('The video audio not be loaded, either because the server or network failed or because the format is not supported.');
                 break;
               default:
                 alert('An unknown error occurred.');
                 break;
             }
           }, true);
          resources[resDict.to[0]][resDict.to[1]].addEventListener('loadeddata',loadeddata);
          resources[resDict.to[0]][resDict.to[1]].src = resDict.from;
          resources[resDict.to[0]][resDict.to[1]].preload = 'auto';
          resources[resDict.to[0]][resDict.to[1]].load(); //triggers download for browsers that don't detect change of src
          resDict.isScheduled = true;
        }
    };

    this.loadAfterInit = function(){
        resources.pictureList = resources.init['PictureList']
        var LevelsList = resources.init['LevelsList'];
        for (var level in LevelsList) {
            var levelItem = LevelsList[level];
            scheduleLoad(['levels',level],
                         DESCRIPTORS + LEVELS + levelItem,
                         'json',
                         (function(level){
                              return function(){
                                  var tileimage = resources['levels'][level]['Level']['tileImage'];
                                  if (resources.tileslist.indexOf(tileimage) < 0) {
                                      resources.tileslist.push(tileimage);
                                  }
                              };})(level)
                         );
        }
        var CharasetFileList = this.init['CharasetFileList'];
        for (var charasetfilep in CharasetFileList) {
            var charasetfile = CharasetFileList[charasetfilep];
            scheduleLoad(['charasets'],
                         DESCRIPTORS + CHARASETS + charasetfile,
                         'json',
                          function(){
                              resources.playerCharaset = resources['charasets'][resources.init['Player']['charaSet']];
                          });

        }
        scheduleLoad(['charas'],
                     DESCRIPTORS + "charas.json",
                     'json');
        scheduleLoad(['feedback'],
                     DESCRIPTORS + "feedback.json",
                     'json');
        scheduleLoad(['hms'],
                     DESCRIPTORS + resources.init["HMSFile"],
                     'json');
        scheduleLoad(['items'],
                     DESCRIPTORS + resources.init["itemsFile"],
                    'json');

        var MusicList = this.init['MusicList'];
        for (var music in MusicList) {
            var musicFile = MusicList[music];
            if(this.audioSupport.ogg && 'ogg' in musicFile){
              scheduleLoad(['music',music],
                           MUSIC + musicFile.ogg,
                           'ogg');
            } else if(this.audioSupport.mp3 && 'mp3' in musicFile){
              scheduleLoad(['music',music],
                           MUSIC + musicFile.mp3,
                           'ogg');
            } else if(this.audioSupport.wav && 'wav' in musicFile){
              scheduleLoad(['music',music],
                           MUSIC + musicFile.wav,
                           'ogg');
            }
        }

        loadFromSchedule();

    };

    loadInit()
}

// MIT LICENSE
// Copyright (c) 2016 Érico Vieira Porto
//
// Permission is hereby granted, free of charge, to any
// person obtaining a copy of this software and associated
// documentation files (the "Software"), to deal in the
// Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute,
// sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// You can't claim ownership, use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell any software, images or
// documents that includes characters, assets, or story elements
// of the game distributed along with this engine.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
<commit_msg>adding multiple file formats for audio<commit_after>// resources.js
//  This module should be responsable for loading things.
// every request made by the engine should be centralized in
// this module.

var resources = {
    init: {},
    tileset: null,
    playerChara: null,
    printerset: null,
    playerCharaset: null,
    faceset: null,
    feedback: {},
    items: {},
    levels: {},
    charasets: {},
    charas: {},
    hms: {}
};

resources.harvest = function(callback) {
    // the idea here is to loadInit, and then
    // analyze the init file in loadAfterInit
    // and scheduleLoad of all needed json files.
    //
    // than, ask for the loading of all of them with
    // loadFromSchedule.
    //
    // doLoad should be asked in the return and
    // if checkAllLoaded, should load all needed
    // images and then, after all images are loaded
    // throw the finalCallback
    //
    //

    resources.finalCallback = callback;
    var DESCRIPTORS = "descriptors/";
    var CHARASETS = "charaset/";
    var LEVELS = "levels/";
    var MUSIC = "audio/music/";

    this.faceset = document.getElementById("faceset");
    this.charasetimg = document.getElementById("charasetimg");
    this.printerset = document.getElementById("printerimg");
    this.monsterimg = document.getElementById("monsterbattleimg");
    this.tile = {};
    this.pictures = {};
    this.syspictures = {};
    this.music = {};
    this.syspictures.title = document.getElementById("titleimg");
    this.syspictures.keys1 = document.getElementById("keys1");
    this.syspictures.keys2 = document.getElementById("keys2");
    this.syspictures.controllers = document.getElementById("controllers");

    this.tileslist = [];

    this.loadingList = [];

    var audioSupport = function() {
        var audioTest = (typeof Audio !== 'undefined') ? new Audio() : null;

        if (!audioTest || typeof audioTest.canPlayType !== 'function') {
        return {
            mp3: false,
            ogg: false,
            wav: false,
            aac: false
          };
        }

        var mpegTest = audioTest.canPlayType('audio/mpeg;').replace(/^no$/, '');

        return {
            mp3: !!(mpegTest || audioTest.canPlayType('audio/mp3;').replace(/^no$/, '')),
            ogg: !!audioTest.canPlayType('audio/ogg; codecs="vorbis"').replace(/^no$/, ''),
            wav: !!audioTest.canPlayType('audio/wav; codecs="1"').replace(/^no$/, ''),
            aac: !!audioTest.canPlayType('audio/aac;').replace(/^no$/, '')
        };

    };

    this.audioSupport = audioSupport()

    var loadInit = function(){
        var request = new XMLHttpRequest();
        request.onreadystatechange = function() {
            if (this.readyState == 4 && this.status == 200) {
                resources.init = JSON.parse(this.responseText); //this is fake code!!!!
                resources.loadAfterInit();
            }
        };
        request.open('GET', DESCRIPTORS + 'init.json', true);
        request.send();
    };

    var scheduleLoad = function(toWhere, fromUrl, fileType, tinyCallback){
        resources.loadingList.push({
            to: toWhere,
            from: fromUrl,
            fileType: fileType,
            loaded: false,
            isScheduled: false,
            tinyCallback: tinyCallback
        });
    };

    var loadFromSchedule = function(){
        for(var i=0; i<resources.loadingList.length ; i++){
            resources.doLoad(i);
        }
    };

    var loadAllImages = function(){

        pic_i = 0
        tile_i = 0

        function loadImages(src, callback) {
            if(tile_i < resources.tileslist.length){
                resources.tile[src] = new Image();
                resources.tile[src].onload = function() {
                    tile_i++;
                    if (tile_i < resources.tileslist.length) {
                        loadImages(resources.tileslist[tile_i], callback);
                    } else if (pic_i < resources.pictureList.length){
                        loadImages(resources.pictureList[pic_i], callback);
                    } else {
                        callback();
                    }
                };
                resources.tile[src].src = src;
            } else {
                var name = src;
                resources.pictures[name] = new Image();
                resources.pictures[name].onload = function() {
                    pic_i++;
                    if(pic_i < resources.pictureList.length){
                        loadImages(resources.pictureList[pic_i], callback);
                    } else {
                        callback();
                    }
                };
                resources.pictures[name].src = 'img/pictures/'+name+'.png';
            }
        }

        loadImages(resources.tileslist[tile_i], resources.finalCallback);
    };

    this.checkAllLoaded = function(){
        var allLoaded = true;
        for(var i=0; i<resources.loadingList.length ; i++){
            var resDict = resources.loadingList[i];
            allLoaded = allLoaded && resDict.loaded;
        }

        if(allLoaded){
            loadAllImages();
        }
    };

    this.doLoad = function(i){
        var resDict = resources.loadingList[i];
        if(resDict.isScheduled){
            return;
        }

        if(resDict.fileType == 'json'){
            var request = new XMLHttpRequest();
            request.onreadystatechange = function() {
                if (this.readyState == 4 && this.status == 200) {
                    if(resDict.to[0]=='charasets'){
                        resources['charasets'] = JSON.parse(this.responseText)['Charaset'];
                    } else if (resDict.to[0]=='feedback') {
                        resources['feedback'] = JSON.parse(this.responseText)['Feedback'];
                    } else if (resDict.to[0]=='charas'){
                        resources['charas'] = JSON.parse(this.responseText)['Charas'];
                    } else if (resDict.to[0]=='items'){
                        resources['items'] = JSON.parse(this.responseText)['Items'];
                    } else {
                        if(resDict.to.length == 1){
                            resources[resDict.to[0]] = JSON.parse(this.responseText);
                        } else if(resDict.to.length == 2){
                            resources[resDict.to[0]][resDict.to[1]] = JSON.parse(this.responseText);
                        } else  if(resDict.to.length == 3){
                            resources[resDict.to[0]][resDict.to[1]][resDict.to[2]] = JSON.parse(this.responseText);
                        }
                    }
                    resDict.loaded = true;
                    if(typeof resDict.tinyCallback === 'function'){
                        resDict.tinyCallback();
                    }
                    resources.checkAllLoaded();
                }
            };
            request.open('GET', resDict.from, true);
            request.send();
            resDict.isScheduled = true;
        }
        if(resDict.fileType == 'ogg' || resDict.fileType == 'mp3' || resDict.fileType == 'wav' ){
          var internetMediaType={'ogg':'audio/ogg','mp3':'audio/mpeg','wav':'audio/wav'}
          var loadeddata = (function(resDict){
              return function() {
                resDict.loaded = true;
                if(typeof resDict.tinyCallback === 'function'){
                    resDict.tinyCallback();
                }
                resources.checkAllLoaded();
                resources[resDict.to[0]][resDict.to[1]].removeEventListener('loadeddata',loadeddata);
                resources[resDict.to[0]][resDict.to[1]].childNodes[0].removeEventListener('loadeddata',loadeddata);
              }
            })(resDict);

          var checkError = function failed(e) {
             // audio playback failed - show a message saying why
             // to get the source of the audio element use $(this).src
             switch (e.target.error.code) {
               case e.target.error.MEDIA_ERR_ABORTED:
                 alert('1 - You aborted the video playback.');
                 break;
               case e.target.error.MEDIA_ERR_NETWORK:
                 alert('2 - A network error caused the audio download to fail.');
                 break;
               case e.target.error.MEDIA_ERR_DECODE:
                 alert('3 - The audio playback was aborted due to a corruption problem or because the video used features your browser did not support.');
                 break;
               case e.target.error.MEDIA_ERR_SRC_NOT_SUPPORTED:
                 alert('4 - The video audio not be loaded, either because the server or network failed or because the format is not supported.');
                 break;
               default:
                 alert('5 - An unknown error occurred.');
                 break;
             }
           };

          resources[resDict.to[0]][resDict.to[1]]  = document.createElement('audio');
          resources[resDict.to[0]][resDict.to[1]].id = resDict.to[1];
          resources[resDict.to[0]][resDict.to[1]].loop = true;
          resources[resDict.to[0]][resDict.to[1]].addEventListener('error',checkError , true);
          resources[resDict.to[0]][resDict.to[1]].addEventListener('loadeddata',loadeddata);
          var source = document.createElement('source');
          source.type = internetMediaType[resDict.fileType];
          source.src = resDict.from;

          resources[resDict.to[0]][resDict.to[1]].appendChild(source);
          resources[resDict.to[0]][resDict.to[1]].preload = 'auto';
          resources[resDict.to[0]][resDict.to[1]].load(); //triggers download for browsers that don't detect change of src
          resDict.isScheduled = true;
        }
    };

    this.loadAfterInit = function(){
        resources.pictureList = resources.init['PictureList']
        var LevelsList = resources.init['LevelsList'];
        for (var level in LevelsList) {
            var levelItem = LevelsList[level];
            scheduleLoad(['levels',level],
                         DESCRIPTORS + LEVELS + levelItem,
                         'json',
                         (function(level){
                              return function(){
                                  var tileimage = resources['levels'][level]['Level']['tileImage'];
                                  if (resources.tileslist.indexOf(tileimage) < 0) {
                                      resources.tileslist.push(tileimage);
                                  }
                              };})(level)
                         );
        }
        var CharasetFileList = this.init['CharasetFileList'];
        for (var charasetfilep in CharasetFileList) {
            var charasetfile = CharasetFileList[charasetfilep];
            scheduleLoad(['charasets'],
                         DESCRIPTORS + CHARASETS + charasetfile,
                         'json',
                          function(){
                              resources.playerCharaset = resources['charasets'][resources.init['Player']['charaSet']];
                          });

        }
        scheduleLoad(['charas'],
                     DESCRIPTORS + "charas.json",
                     'json');
        scheduleLoad(['feedback'],
                     DESCRIPTORS + "feedback.json",
                     'json');
        scheduleLoad(['hms'],
                     DESCRIPTORS + resources.init["HMSFile"],
                     'json');
        scheduleLoad(['items'],
                     DESCRIPTORS + resources.init["itemsFile"],
                    'json');

        var MusicList = this.init['MusicList'];
        for (var music in MusicList) {
            var musicFile = MusicList[music];
            if(this.audioSupport.ogg && 'ogg' in musicFile){
              scheduleLoad(['music',music],
                           MUSIC + musicFile.ogg,
                           'ogg');
            } else if(this.audioSupport.mp3 && 'mp3' in musicFile){
              scheduleLoad(['music',music],
                           MUSIC + musicFile.mp3,
                           'ogg');
            } else if(this.audioSupport.wav && 'wav' in musicFile){
              scheduleLoad(['music',music],
                           MUSIC + musicFile.wav,
                           'ogg');
            }
        }

        loadFromSchedule();

    };

    loadInit()
}

// MIT LICENSE
// Copyright (c) 2016 Érico Vieira Porto
//
// Permission is hereby granted, free of charge, to any
// person obtaining a copy of this software and associated
// documentation files (the "Software"), to deal in the
// Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute,
// sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// You can't claim ownership, use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell any software, images or
// documents that includes characters, assets, or story elements
// of the game distributed along with this engine.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
<|endoftext|>


<commit_before>/* This file has been generated by ox-ui-module generator.
 * Please only apply minor changes (better no changes at all) to this file
 * if you want to be able to run the generator again without much trouble.
 *
 * If you really have to change this file for whatever reason, try to contact
 * the core team and describe your use-case. May be, your changes can be
 * integrated into the templates to be of use for everybody.
 */
'use strict';

module.exports = function (grunt) {

    if (!grunt.isPeerDependencyInstalled('grunt-contrib-watch')) {
        grunt.verbose.warn('Skipping optional watch tasks');
        return;
    }

    var conf = grunt.config().local.appserver;
    var proto = (conf && conf.protocol === 'https') ? 'https' : 'http';

    var net = require('net');
    var server = net.createServer();
    server.on('error', function () {
        grunt.verbose.writeln('Livereload instance running, will enable send_livereload task.');
    });
    server.listen(35729, function () {
        var lrConf = true;
        grunt.verbose.writeln('No Livereload instance running, will configure watch to start one.');
        if (proto === 'https') {
            lrConf = {
                key: grunt.config('connect.server.options.key') || grunt.file.read('node_modules/grunt-contrib-connect/tasks/certs/server.key'),
                cert: grunt.config('connect.server.options.cert') || grunt.file.read('node_modules/grunt-contrib-connect/tasks/certs/server.crt')
            };
        }
        grunt.config.set('watch.manifests.options.livereload', lrConf);
        grunt.config.set('watch.all.options.livereload', lrConf);
        if (grunt.task.current.name === 'watch') {
            grunt.task.run('watch');
        }
        server.close();
    });

    grunt.registerTask('send_livereload', function () {
        var done = this.async();
        if (!!grunt.config('watch.all.options.livereload')) {
            grunt.verbose.writeln('Using livereload from watch');
            done();
            return;
        }
        var http = require(proto);
        var req = http.request({
            hostname: 'localhost',
            port: 35729,
            path: '/changed',
            method: 'POST',
            rejectUnauthorized: false
        }, function () {
            grunt.verbose.writeln('Livereload request sent');
            done();
        });
        req.on('error', function (err) {
            grunt.log.warn('Could not send livereload:', err);
            done();
        });
        req.write(JSON.stringify({ files: ['boot.js'] }));
        req.end();
    });

    grunt.config.merge({
        watch: {
            options: {
                interval: 500,
                interrupt: true,
                debounceDelay: 500
            },
            manifests: {
                files: 'apps/**/manifest.json',
                tasks: ['manifests', 'force_update', 'send_livereload'],
                options: {}
            },
            karma: {
                files: ['spec/**/*.js'],
                tasks: ['lint:specs', 'testrun']
            },
            configs: {
                options: { reload: true },
                files: [
                    'Gruntfile.js',
                    'grunt/tasks/*.js',
                    'grunt/local.conf.json'
                ],
                tasks: ['default']
            },
            all: {
                files: [
                    'apps/**/*.{js,less}',
                    'src/*',
                    'lib/**/*.js',
                    'bower.json',
                    'package.json'
                ],
                tasks: ['default', 'force_update', 'send_livereload', 'testrun'],
                options: {}
            }
        }
    });

    grunt.loadNpmTasks('grunt-contrib-watch');
};
<commit_msg>move bower.json and package.json from watch:all to watch:configs<commit_after>/* This file has been generated by ox-ui-module generator.
 * Please only apply minor changes (better no changes at all) to this file
 * if you want to be able to run the generator again without much trouble.
 *
 * If you really have to change this file for whatever reason, try to contact
 * the core team and describe your use-case. May be, your changes can be
 * integrated into the templates to be of use for everybody.
 */
'use strict';

module.exports = function (grunt) {

    if (!grunt.isPeerDependencyInstalled('grunt-contrib-watch')) {
        grunt.verbose.warn('Skipping optional watch tasks');
        return;
    }

    var conf = grunt.config().local.appserver;
    var proto = (conf && conf.protocol === 'https') ? 'https' : 'http';

    var net = require('net');
    var server = net.createServer();
    server.on('error', function () {
        grunt.verbose.writeln('Livereload instance running, will enable send_livereload task.');
    });
    server.listen(35729, function () {
        var lrConf = true;
        grunt.verbose.writeln('No Livereload instance running, will configure watch to start one.');
        if (proto === 'https') {
            lrConf = {
                key: grunt.config('connect.server.options.key') || grunt.file.read('node_modules/grunt-contrib-connect/tasks/certs/server.key'),
                cert: grunt.config('connect.server.options.cert') || grunt.file.read('node_modules/grunt-contrib-connect/tasks/certs/server.crt')
            };
        }
        grunt.config.set('watch.manifests.options.livereload', lrConf);
        grunt.config.set('watch.all.options.livereload', lrConf);
        if (grunt.task.current.name === 'watch') {
            grunt.task.run('watch');
        }
        server.close();
    });

    grunt.registerTask('send_livereload', function () {
        var done = this.async();
        if (!!grunt.config('watch.all.options.livereload')) {
            grunt.verbose.writeln('Using livereload from watch');
            done();
            return;
        }
        var http = require(proto);
        var req = http.request({
            hostname: 'localhost',
            port: 35729,
            path: '/changed',
            method: 'POST',
            rejectUnauthorized: false
        }, function () {
            grunt.verbose.writeln('Livereload request sent');
            done();
        });
        req.on('error', function (err) {
            grunt.log.warn('Could not send livereload:', err);
            done();
        });
        req.write(JSON.stringify({ files: ['boot.js'] }));
        req.end();
    });

    grunt.config.merge({
        watch: {
            options: {
                interval: 500,
                interrupt: true,
                debounceDelay: 500
            },
            manifests: {
                files: 'apps/**/manifest.json',
                tasks: ['manifests', 'force_update', 'send_livereload'],
                options: {}
            },
            karma: {
                files: ['spec/**/*.js'],
                tasks: ['lint:specs', 'testrun']
            },
            configs: {
                options: { reload: true },
                files: [
                    'Gruntfile.js',
                    'grunt/tasks/*.js',
                    'grunt/local.conf.json',
                    'bower.json',
                    'package.json'
                ],
                tasks: ['clean', 'repair:bower_install', 'repair:npm_install', 'default', 'force_update', 'send_livereload']
            },
            all: {
                files: [
                    'apps/**/*.{js,less}',
                    'src/*',
                    'lib/**/*.js'
                ],
                tasks: ['default', 'force_update', 'send_livereload', 'testrun'],
                options: {}
            }
        }
    });

    grunt.loadNpmTasks('grunt-contrib-watch');
};
<|endoftext|>


<commit_before>/*
 * grunt-static-inline
 * https://github.com/dayvson/grunt-static-inline
 *
 * Copyright (c) 2013 Maxwell Da Silva
 * Licensed under the MIT license.
 */

'use strict';

module.exports = function(grunt) {
  var datauri = require('datauri');
  var path = require('path');

  var resolveFilePath = function(templatePath, src, basepath) {
    var srcPath;
    if (!grunt.file.isPathAbsolute(src)) {
      srcPath = path.resolve(path.dirname(templatePath), src);
    } else if (grunt.file.isPathAbsolute(src) && basepath) {
      srcPath = path.resolve(basepath + src);
    }
    return srcPath;
  };

  var readFile = function (templatePath, src, basepath) {
    var result = '';
    var srcPath = resolveFilePath(templatePath, src, basepath);
    if (srcPath) {
      result = grunt.file.read(srcPath).trim();
    }
    return result;
  };

  var baseTagReplace = function(templatePath, tag, src, basepath) {
    var result = '';
    var srcContents = readFile(templatePath, src, basepath);
    if (srcContents) {
      result = '<' + tag + '>' + srcContents + '</' + tag + '>';
    }
    return result;
  };

  var findReplaceScript = function(templatePath, content, basepath) {
    return content.replace(/<script[^<]*src=['"]([^'"]+)['"][^<]*inline=['"]true['"][^<]*\/?><\/script>/g, function(match, src) {

      // Remove attributes and closing </script>
      match = match.replace(/\ssrc=['"]([^'"]+)['"]/, '').
        replace(/\sinline=['"]true['"]/, '').
        replace(/<\/script>/, '');

      return match + readFile(templatePath, src, basepath) + '</script>';
    });
  };

  var findReplaceLink = function(templatePath, content, basepath) {
    return content.replace(/<link[^<]*href=['"]([^'"]+)['"][^<]*inline=['"]true['"][^<]*\/?\s*>/g, function(match, src) {
      return baseTagReplace(templatePath, 'style', src, basepath);
    });
  };

  var findReplaceImg = function(templatePath, content, basepath) {
    return content.replace(/<img[^<]*src=['"]([^'"]+)['"][^<]*inline=['"]true['"][^<]*\/?\s*>/g, function(match, src) {
        var srcPath = resolveFilePath(templatePath, src, basepath);
        if (srcPath) {
          return match.replace(/inline=['"]true['"]/g, '').replace(src, datauri(srcPath));
        }
        return '';
    });
  };

  var findReplaceVariables = function(options, content) {
    Object.keys(options.vars).forEach(function(key) {
      var re = new RegExp(options.prefix + key + options.suffix, 'g');
      content = content.replace(re, options.vars[key]);
    });
    return content;
  };

  var findAndReplace = function(options, templatePath, content) {
    var result = findReplaceLink(templatePath, content, options.basepath);
    result = findReplaceScript(templatePath, result, options.basepath);
    result = findReplaceImg(templatePath, result, options.basepath);
    return findReplaceVariables(options, result);
  };

  var staticInlineTask = function() {
    var options = this.options({
        prefix: '@{',
        suffix: '}@',
        vars: {}
      });

    this.files.forEach(function(f) {
      var srcFile = f.src;
      var destFile = f.dest;
      var content = grunt.file.read(srcFile);
      content = findAndReplace(options, srcFile, content);
      grunt.file.write(destFile, content);
    });
  };

  grunt.registerMultiTask('staticinline', 'A grunt plugin to replace url from static files such as images, CSS, JS, and put inline in a template', staticInlineTask);

};
<commit_msg>Quickly fix the issue with relative to root paths.<commit_after>/*
 * grunt-static-inline
 * https://github.com/dayvson/grunt-static-inline
 *
 * Copyright (c) 2013 Maxwell Da Silva
 * Licensed under the MIT license.
 */

'use strict';

module.exports = function(grunt) {
  var datauri = require('datauri');
  var path = require('path');

  var resolveFilePath = function(templatePath, src, basepath) {
    var srcPath;
    if (!grunt.file.isPathAbsolute(src) && basepath) {
      srcPath = path.resolve(basepath + src);
    } else if (!grunt.file.isPathAbsolute(src)) {
      srcPath = path.resolve(path.dirname(templatePath), src);
    } else if (grunt.file.isPathAbsolute(src) && basepath) {
      srcPath = path.resolve(basepath + src);
    }
    return srcPath;
  };

  var readFile = function (templatePath, src, basepath) {
    var result = '';
    var srcPath = resolveFilePath(templatePath, src, basepath);
    if (srcPath) {
      result = grunt.file.read(srcPath).trim();
    }
    return result;
  };

  var baseTagReplace = function(templatePath, tag, src, basepath) {
    var result = '';
    var srcContents = readFile(templatePath, src, basepath);
    if (srcContents) {
      result = '<' + tag + '>' + srcContents + '</' + tag + '>';
    }
    return result;
  };

  var findReplaceScript = function(templatePath, content, basepath) {
    return content.replace(/<script[^<]*src=['"]([^'"]+)['"][^<]*inline=['"]true['"][^<]*\/?><\/script>/g, function(match, src) {

      // Remove attributes and closing </script>
      match = match.replace(/\ssrc=['"]([^'"]+)['"]/, '').
        replace(/\sinline=['"]true['"]/, '').
        replace(/<\/script>/, '');

      return match + readFile(templatePath, src, basepath) + '</script>';
    });
  };

  var findReplaceLink = function(templatePath, content, basepath) {
    return content.replace(/<link[^<]*href=['"]([^'"]+)['"][^<]*inline=['"]true['"][^<]*\/?\s*>/g, function(match, src) {
      return baseTagReplace(templatePath, 'style', src, basepath);
    });
  };

  var findReplaceImg = function(templatePath, content, basepath) {
    return content.replace(/<img[^<]*src=['"]([^'"]+)['"][^<]*inline=['"]true['"][^<]*\/?\s*>/g, function(match, src) {
        var srcPath = resolveFilePath(templatePath, src, basepath);
        if (srcPath) {
          return match.replace(/inline=['"]true['"]/g, '').replace(src, datauri(srcPath));
        }
        return '';
    });
  };

  var findReplaceVariables = function(options, content) {
    Object.keys(options.vars).forEach(function(key) {
      var re = new RegExp(options.prefix + key + options.suffix, 'g');
      content = content.replace(re, options.vars[key]);
    });
    return content;
  };

  var findAndReplace = function(options, templatePath, content) {
    var result = findReplaceLink(templatePath, content, options.basepath);
    result = findReplaceScript(templatePath, result, options.basepath);
    result = findReplaceImg(templatePath, result, options.basepath);
    return findReplaceVariables(options, result);
  };

  var staticInlineTask = function() {
    var options = this.options({
        prefix: '@{',
        suffix: '}@',
        vars: {}
      });

    this.files.forEach(function(f) {
      var srcFile = f.src;
      var destFile = f.dest;
      var content = grunt.file.read(srcFile);
      content = findAndReplace(options, srcFile, content);
      grunt.file.write(destFile, content);
    });
  };

  grunt.registerMultiTask('staticinline', 'A grunt plugin to replace url from static files such as images, CSS, JS, and put inline in a template', staticInlineTask);

};
<|endoftext|>


<commit_before>/*
 * grunt-twig-gettext
 * http://grunt-twig-gettext.monomelodies.nl
 *
 * Copyright (c) 2015 Marijn Ophorst
 * Licensed under the MIT license.
 */

'use strict';

module.exports = function (grunt) {

    grunt.registerMultiTask('twig_gettext', 'Extract i18n strings from Twig templates', function () {
        var options = this.options({
            charset: 'ASCII',
            encoding: '8bit'
        });

        this.files.forEach(function (f) {
            var matches = [];
            f.src.filter(function(filepath) {
                if (!grunt.file.exists(filepath)) {
                    grunt.log.warn('Source file "' + filepath + '" not found.');
                    return false;
                } else {
                    return true;
                }
            }).map(function(filepath) {
                var twig = grunt.file.read(filepath);
                var result;
                var inline = /{% trans "(.*?)" %}/g;
                var multiline = /{% trans %}((\n|.)*?){% endtrans %}/g;
                var submatches = [];
                while ((result = inline.exec(twig)) || (result = multiline.exec(twig))) {
                    submatches.push(result);
                }
                matches = matches.concat(submatches.sort(function (a, b) {
                    return a.index < b.index ? -1 : 1;
                }));
            });

            // Replace variables
            matches = matches.map(function (trans) {
                return trans[1].replace(/{{\s*(.*?)\s*}}/g, '%$1%');
            });
            // Format according to .pot
            matches = matches.map(function (trans) {
                var lines = trans.trim().split("\n");
                lines = lines.map(function (line) {
                    line = ('' + line).replace(/\s$/, '');
                    line = '"' + line.replace(/"/g, '\\"') + '"';
                    return line;
                });
                trans = lines.join("\n");
                return "msgid " + trans + "\nmsgstr \"\"";
            });
            // Make unique (at least inside the file :))
            var unique = [];
            matches.map(function (match) {
                if (unique.indexOf(match) == -1) {
                    unique.push(match);
                }
            });
            var src = "#, fuzzy\n" +
                "msgid \"\"\n" +
                "msgstr \"\"\n" +
                "\"Language: \\n\"\n" +
                "\"MIME-Version: 1.0\\n\"\n" +
                "\"Content-Type: text/plain; charset=" + options.charset + "\\n\"\n" +
                "\"Content-Transfer-Encoding: " + options.encoding + "\\n\"\n\n" + unique.join("\n\n") + "\n";

            // Write the destination file.
            grunt.file.write(f.dest, src);

            // Print a success message.
            grunt.log.writeln('File "' + f.dest + '" created.');
        });
    });

};
<commit_msg>needs newline<commit_after>/*
 * grunt-twig-gettext
 * http://grunt-twig-gettext.monomelodies.nl
 *
 * Copyright (c) 2015 Marijn Ophorst
 * Licensed under the MIT license.
 */

'use strict';

module.exports = function (grunt) {

    grunt.registerMultiTask('twig_gettext', 'Extract i18n strings from Twig templates', function () {
        var options = this.options({
            charset: 'ASCII',
            encoding: '8bit'
        });

        this.files.forEach(function (f) {
            var matches = [];
            f.src.filter(function(filepath) {
                if (!grunt.file.exists(filepath)) {
                    grunt.log.warn('Source file "' + filepath + '" not found.');
                    return false;
                } else {
                    return true;
                }
            }).map(function(filepath) {
                var twig = grunt.file.read(filepath);
                var result;
                var inline = /{% trans "(.*?)" %}/g;
                var multiline = /{% trans %}((\n|.)*?){% endtrans %}/g;
                var submatches = [];
                while ((result = inline.exec(twig)) || (result = multiline.exec(twig))) {
                    submatches.push(result);
                }
                matches = matches.concat(submatches.sort(function (a, b) {
                    return a.index < b.index ? -1 : 1;
                }));
            });

            // Replace variables
            matches = matches.map(function (trans) {
                return trans[1].replace(/{{\s*(.*?)\s*}}/g, '%$1%');
            });
            // Format according to .pot
            matches = matches.map(function (trans) {
                var lines = trans.trim().split("\n");
                lines = lines.map(function (line) {
                    line = ('' + line).replace(/\s$/, '');
                    line = '"' + line.replace(/"/g, '\\"') + '\n"';
                    return line;
                });
                trans = lines.join("\n");
                return "msgid " + trans + "\nmsgstr \"\"";
            });
            // Make unique (at least inside the file :))
            var unique = [];
            matches.map(function (match) {
                if (unique.indexOf(match) == -1) {
                    unique.push(match);
                }
            });
            var src = "#, fuzzy\n" +
                "msgid \"\"\n" +
                "msgstr \"\"\n" +
                "\"Language: \\n\"\n" +
                "\"MIME-Version: 1.0\\n\"\n" +
                "\"Content-Type: text/plain; charset=" + options.charset + "\\n\"\n" +
                "\"Content-Transfer-Encoding: " + options.encoding + "\\n\"\n\n" + unique.join("\n\n") + "\n";

            // Write the destination file.
            grunt.file.write(f.dest, src);

            // Print a success message.
            grunt.log.writeln('File "' + f.dest + '" created.');
        });
    });

};
<|endoftext|>


<commit_before>const endpoint = 'https://gist.githubusercontent.com/Miserlou/c5cd8364bf9b2420bb29/raw/2bf258763cdddd704f8ffd3ea9a3e81d25e2c6f6/cities.json';

const cities = []
// fetch json data
fetch(endpoint).then(blob => blob.json()).then(data => cities.push(...data));

function search(keyword) {
    return cities.filter(place => {
        // convert keyword var into regexp since match method takes regex
        const regex = new RegExp(keyword, 'gi');
        return place.city.match(regex) || place.state.match(regex);
    })
}

function displaySearchResult() {
    const resultArr  = search(this.value);
    const html = resultArr.map(place => {
        const regex = new RegExp(this.value, 'gi');
        const cityName = place.city.replace(regex, `<span class='hl'>${this.value}</span>`);
        const stateName = place.state.replace(regex, `<span class='hl'>${this.value}</span>`);
        return `

            ${cityName}, ${stateName}
            ${place.population}

        `
    }).join('');
    suggestions.innerHTML = html;
}

const suggestions = document.querySelector('.suggestions');
const searchBox = document.querySelector('.search');
searchBox.addEventListener('keyup', displaySearchResult);
<commit_msg>added some code comments<commit_after>const endpoint = 'https://gist.githubusercontent.com/Miserlou/c5cd8364bf9b2420bb29/raw/2bf258763cdddd704f8ffd3ea9a3e81d25e2c6f6/cities.json';

const cities = []
// fetch json data
fetch(endpoint).then(blob => blob.json()).then(data => cities.push(...data));

const suggestions = document.querySelector('.suggestions');
const searchBox = document.querySelector('.search');

/**
 * Get an array of cities that matched the search keyword
 * @param {*} keyword
 */
function search(keyword) {
    return cities.filter(place => {
        // convert keyword var into regexp since match method takes regex
        const regex = new RegExp(keyword, 'gi');
        return place.city.match(regex) || place.state.match(regex);
    })
}

/**
 * Go through the result list > apply some css and display it
 */
function displaySearchResult() {
    const resultArr  = search(this.value);
    const html = resultArr.map(place => {
        // highlight the found keyword
        const regex = new RegExp(this.value, 'gi');
        const cityName = place.city.replace(regex, `<span class='hl'>${this.value}</span>`);
        const stateName = place.state.replace(regex, `<span class='hl'>${this.value}</span>`);
        return `

            ${cityName}, ${stateName}
            ${place.population}

        `
    }).join('');
    suggestions.innerHTML = html;
}

searchBox.addEventListener('keyup', displaySearchResult);
<|endoftext|>