<commit_before>function ExUpload(explorer, url, params) {
    var exUpload = {
        explorerContainer: explorerContainer,
        useAutomaticId: false,
        url: url,
        params: params,
        debugMode: false,
        callback: undefined,
        explorer: explorer,
		allowedExtensions: undefined,
        MSG_INVALID_EXT: "You cannot upload {ext} files here.",
        ERROR_INVALID_FILE: 1,
        ERROR_NO_ID_FOUND: 2,
        start: function () {
            try{
                exUpload.validate();
                exUpload.explorerContainer = exUpload.explorer.container;
                exUpload.handleEvents();
            }catch(e){
                exUpload.log(e);
            }
        },
        validate: function (){
            if(exUpload.params === undefined){
                exUpload.params =  {"fileParam": "file"};
                exUpload.info("uploadParam was not defined, so its default value ('file') will be set.");
            }
            if(exUpload.explorer === undefined || exUpload.explorer.ROOT === undefined){
                throw "ExUpload will not work if you do not set Explorer's instance.";
            }
            if(exUpload.url === undefined){
                throw "ExUpload will not work if you do not set an url.";
            }
        },
        log: function (str) {
            if(exUpload.debugMode){
                console.warn(str);
            }
        },
        info: function (str) {
            if(exUpload.debugMode){
                console.info(str);
            }
        },
        validadeExtension: function (ext){
			if(exUpload.allowedExtensions !== undefined ){
                return exUpload.allowedExtensions.indexOf(ext.toLowerCase()) != -1;
            }
            var extIndex = AVAILABLE_ICON_EXTENSIONS.indexOf(ext.toLowerCase());
            if(extIndex == -1 && AVAILABLE_ICON_EXTENSIONS.indexOf("_".concat(ext.toLowerCase())) == -1){
                return false;
            }
            return true;
        },
        handleEvents: function () {
            var dropArea = document.getElementById(exUpload.explorerContainer.substring(1));
            dropArea.addEventListener('dragenter', function (e) {
                e.currentTarget.classList.add('drop');
            });
            dropArea.addEventListener('dragleave', function (e) {
                e.currentTarget.classList.remove('drop');
            });
            dropArea.addEventListener('dragover', function (e) {
                e.preventDefault();
                e.stopPropagation();
                e.dataTransfer.dropEffect = 'copy';
            });
            dropArea.addEventListener('drop', function (e) {
                e.preventDefault();
                e.stopPropagation();
                var file = e.dataTransfer.files[0];//file to upload
                var ext = file.name.substr(file.name.lastIndexOf('.')+1);
                var num = 100;
                var fakeId = "fake" + num;
                while (exUpload.explorer.checkIfExists(fakeId) != -1) fakeId = "fake" + (++num);
                var fakeFile = new File(fakeId, file.name, ext, exUpload.explorer.currentParent == -1 ? 0 : exUpload.explorer.currentParent);
                var upload = new exUpload.Upload(file, fakeFile);
                exUpload.explorer.addFiles(fakeFile); // adding the file to Explorer
                if(exUpload.validadeExtension(fakeFile.ext) === false){
                    var msg = {message:  exUpload.MSG_INVALID_EXT.replace("{ext}", "."+ext), error: exUpload.ERROR_INVALID_FILE};
                    upload.createProgressStructure(fakeFile.id);
                    exUpload.error(msg, fakeFile);
                }else{
                  upload.upload(file, fakeFile);
                }
            });
        },
        error: function(msg, fakeFile){
          var errorStyle = $("#" + fakeFile.id).find(".errorStyle");
          var item = $("#" + fakeFile.id);
          item.find(".exUpload").fadeOut("fast");
          item.find(".abortStyle").fadeOut("fast");
          errorStyle.fadeIn("slow");
          errorStyle.on("mouseover", function () {
              errorStyle.css("cursor", "pointer");
              errorStyle.prop("title", "Click to Hide");
              item.find(".errorFont").text("Remove?");
          })
          .on("mouseout", function () {
              item.find(".errorFont").text("Upload has Failed");
          })
          .on("mousedown", function () {
              item.fadeOut("slow");
          });
          if (exUpload.callback !== undefined) {
              exUpload.callback(msg, false);
          }
          exUpload.log(msg);
        },
		Upload: function (file, fakeFile) {
            var object = {
                fakeFile: fakeFile,
                file: file,
                myXhr: undefined,
                upload: function () {
                    //var XHR = new window.XMLHttpRequest();
                    var formData = new FormData();
                    formData.append(exUpload.params.fileParam, object.file);
                    formData.append("dirId", exUpload.explorer.currentParent);
                    // delete exUpload.params.fileParam;
                    for (var paramName in exUpload.params) {
                        if (paramName == "fileParam") {
                            continue;
                        }
                        formData.append(paramName, exUpload.params[paramName]);
                    }
                    $.ajax({
                        url: exUpload.url,  //Server script to process data
                        type: 'POST',
                        xhr: function () {  // Custom XMLHttpRequest
                            object.myXhr = $.ajaxSettings.xhr();
                            if (object.myXhr.upload) { // Check if upload property exists
                                object.myXhr.upload.addEventListener('progress', object.progressEvent, false); // For handling the progress of the upload
                            }
                            return object.myXhr;
                        },
                        beforeSend: function (xhr) {
                            object.fakeFile.date = Math.round(new Date() / 1000);
                        },
                        success: function (data) {//retorno do servidor
                            var def = $.Deferred();
                            var fakeFileIndex = exUpload.explorer.checkIfExists(object.fakeFile.id);
                            if (data.id !== undefined && data.id !== null) {//caso o servidor tenha retornado o id do arquivo upado
                                //altera o id fake para o id retornado do banco no html e na lista de Explorer
                                let fakeId = object.fakeFile.id;
                                $("#" + fakeId).attr("id", data.id);
                                $("#" + fakeId).find("#selec_id".concat(fakeId)).attr("id", "selec_id".concat(data.id));
                                exUpload.explorer.fileList[fakeFileIndex].id = data.id;
                            } else if(exUpload.useAutomaticId){
                                data.id = object.fakeFile.id;
                            }else{
                              var msg = {messages: "Your server did not return any ID, not did you enable the use of automatic id (exUpload.useAutomaticId).", error: exUpload.ERROR_NO_ID_FOUND};
                              if (exUpload.callback !== undefined) {
                                  exUpload.callback(msg, false);
                              }
                              this.error(msg, object.fakeFile);
                              return;
                            }
                            def.resolve();
                            $.when(def).then(function () {
                                var item = $("#" + data.id);
                                item.find(".abortStyle").unbind("mouseover");
                                item.find(".abortStyle").css("display", "none");
                                item.removeClass("uploading");
                                setTimeout(function () {
                                    item.find(".exUpload").fadeOut("slow");
                                }, 2000);
                                if (exUpload.callback !== undefined) {
                                    exUpload.callback(data, true);
                                }
                            });
                        },
                        error: function (e) {
                            exUpload.error(e, object.fakeFile);
                        },
                        data: formData,
                        //Options to tell jQuery not to process data or worry about content-type.
                        cache: false,
                        contentType: false,
                        processData: false,
                        dataType: 'json'
                    });
                },
                createProgressStructure: function (id) {
                    var item = {id: $("#" + id), abortStyle: $("#" + id).find(".abortStyle")};
                    if (!item.id.hasClass("uploading")) {
                        item.id.addClass("uploading");
                    }
                    if (!item.id.find("#progressBar").length) {
                        item.id.append('

'
                            + '

Upload has Failed

'
                            + '

Abort?

'
                            + '
'
                            + '
'
                            + ''
                            + '
'
                            + '0 Kbps'
                            + '
');
                        item.abortStyle.find(".abortFont").on("mouseup", function () {
                            item.abortStyle.unbind("mouseover");
                            item.abortStyle.css("display", "none");
                            object.myXhr.abort();
                        });
                        item.abortStyle.on("mouseover", function () {
                            item.abortStyle.css("opacity", 0.8);
                        });
                        item.abortStyle.on("mouseout", function () {
                            item.abortStyle.css("opacity", 0);
                        });
                    }
                },
                progressEvent: function (e) {
                    if (e.lengthComputable) {
                        var item = $("#" + object.fakeFile.id);
                        var spentTime = Math.round(new Date() / 1000) - object.fakeFile.date;
                        object.createProgressStructure(object.fakeFile.id);
                        var percentLoaded = Math.round((e.loaded * 100) / e.total);
                        if (percentLoaded >= 100) {
                            item.find(".uploadSpeed").css("color", "white");
                            item.find("#" + object.fakeFile.id).removeClass("uploading");
                        } else if (percentLoaded >= 50) {
                            item.find(".percentCounterContainer").css("color", "white");
                        } else if (percentLoaded >= 10) {
                            item.find(".uploadSpeed").css("color", "white");
                        }

                        item.find(".percentConcluido").html(percentLoaded + "%");
                        item.find(".progressBar").css("height", percentLoaded + "%");
                        item.find(".uploadSpeed").html("^ " + Math.floor((e.loaded / 1024) / spentTime) + " Kbps");
                    }
                }
            };
            return object;
		}
    };
    return exUpload;
}<commit_msg>Atualização de uma mensagem em ExUpload<commit_after>function ExUpload(explorer, url, params) {
    var exUpload = {
        explorerContainer: explorerContainer,
        useAutomaticId: false,
        url: url,
        params: params,
        debugMode: false,
        callback: undefined,
        explorer: explorer,
		allowedExtensions: undefined,
        MSG_INVALID_EXT: "{ext} files are not allowed.",
        ERROR_INVALID_FILE: 1,
        ERROR_NO_ID_FOUND: 2,
        start: function () {
            try{
                exUpload.validate();
                exUpload.explorerContainer = exUpload.explorer.container;
                exUpload.handleEvents();
            }catch(e){
                exUpload.log(e);
            }
        },
        validate: function (){
            if(exUpload.params === undefined){
                exUpload.params =  {"fileParam": "file"};
                exUpload.info("uploadParam was not defined, so its default value ('file') will be set.");
            }
            if(exUpload.explorer === undefined || exUpload.explorer.ROOT === undefined){
                throw "ExUpload will not work if you do not set Explorer's instance.";
            }
            if(exUpload.url === undefined){
                throw "ExUpload will not work if you do not set an url.";
            }
        },
        log: function (str) {
            if(exUpload.debugMode){
                console.warn(str);
            }
        },
        info: function (str) {
            if(exUpload.debugMode){
                console.info(str);
            }
        },
        validadeExtension: function (ext){
			if(exUpload.allowedExtensions !== undefined ){
                return exUpload.allowedExtensions.indexOf(ext.toLowerCase()) != -1;
            }
            var extIndex = AVAILABLE_ICON_EXTENSIONS.indexOf(ext.toLowerCase());
            if(extIndex == -1 && AVAILABLE_ICON_EXTENSIONS.indexOf("_".concat(ext.toLowerCase())) == -1){
                return false;
            }
            return true;
        },
        handleEvents: function () {
            var dropArea = document.getElementById(exUpload.explorerContainer.substring(1));
            dropArea.addEventListener('dragenter', function (e) {
                e.currentTarget.classList.add('drop');
            });
            dropArea.addEventListener('dragleave', function (e) {
                e.currentTarget.classList.remove('drop');
            });
            dropArea.addEventListener('dragover', function (e) {
                e.preventDefault();
                e.stopPropagation();
                e.dataTransfer.dropEffect = 'copy';
            });
            dropArea.addEventListener('drop', function (e) {
                e.preventDefault();
                e.stopPropagation();
                var file = e.dataTransfer.files[0];//file to upload
                var ext = file.name.substr(file.name.lastIndexOf('.')+1);
                var num = 100;
                var fakeId = "fake" + num;
                while (exUpload.explorer.checkIfExists(fakeId) != -1) fakeId = "fake" + (++num);
                var fakeFile = new File(fakeId, file.name, ext, exUpload.explorer.currentParent == -1 ? 0 : exUpload.explorer.currentParent);
                var upload = new exUpload.Upload(file, fakeFile);
                exUpload.explorer.addFiles(fakeFile); // adding the file to Explorer
                if(exUpload.validadeExtension(fakeFile.ext) === false){
                    var msg = {message:  exUpload.MSG_INVALID_EXT.replace("{ext}", "."+ext), error: exUpload.ERROR_INVALID_FILE};
                    upload.createProgressStructure(fakeFile.id);
                    exUpload.error(msg, fakeFile);
                }else{
                  upload.upload(file, fakeFile);
                }
            });
        },
        error: function(msg, fakeFile){
          var errorStyle = $("#" + fakeFile.id).find(".errorStyle");
          var item = $("#" + fakeFile.id);
          item.find(".exUpload").fadeOut("fast");
          item.find(".abortStyle").fadeOut("fast");
          errorStyle.fadeIn("slow");
          errorStyle.on("mouseover", function () {
              errorStyle.css("cursor", "pointer");
              errorStyle.prop("title", "Click to Hide");
              item.find(".errorFont").text("Remove?");
          })
          .on("mouseout", function () {
              item.find(".errorFont").text("Upload has Failed");
          })
          .on("mousedown", function () {
              item.fadeOut("slow");
          });
          if (exUpload.callback !== undefined) {
              exUpload.callback(msg, false);
          }
          exUpload.log(msg);
        },
		Upload: function (file, fakeFile) {
            var object = {
                fakeFile: fakeFile,
                file: file,
                myXhr: undefined,
                upload: function () {
                    //var XHR = new window.XMLHttpRequest();
                    var formData = new FormData();
                    formData.append(exUpload.params.fileParam, object.file);
                    formData.append("dirId", exUpload.explorer.currentParent);
                    // delete exUpload.params.fileParam;
                    for (var paramName in exUpload.params) {
                        if (paramName == "fileParam") {
                            continue;
                        }
                        formData.append(paramName, exUpload.params[paramName]);
                    }
                    $.ajax({
                        url: exUpload.url,  //Server script to process data
                        type: 'POST',
                        xhr: function () {  // Custom XMLHttpRequest
                            object.myXhr = $.ajaxSettings.xhr();
                            if (object.myXhr.upload) { // Check if upload property exists
                                object.myXhr.upload.addEventListener('progress', object.progressEvent, false); // For handling the progress of the upload
                            }
                            return object.myXhr;
                        },
                        beforeSend: function (xhr) {
                            object.fakeFile.date = Math.round(new Date() / 1000);
                        },
                        success: function (data) {//retorno do servidor
                            var def = $.Deferred();
                            var fakeFileIndex = exUpload.explorer.checkIfExists(object.fakeFile.id);
                            if (data.id !== undefined && data.id !== null) {//caso o servidor tenha retornado o id do arquivo upado
                                //altera o id fake para o id retornado do banco no html e na lista de Explorer
                                let fakeId = object.fakeFile.id;
                                $("#" + fakeId).attr("id", data.id);
                                $("#" + fakeId).find("#selec_id".concat(fakeId)).attr("id", "selec_id".concat(data.id));
                                exUpload.explorer.fileList[fakeFileIndex].id = data.id;
                            } else if(exUpload.useAutomaticId){
                                data.id = object.fakeFile.id;
                            }else{
                              var msg = {messages: "Your server did not return any ID, not did you enable the use of automatic id (exUpload.useAutomaticId).", error: exUpload.ERROR_NO_ID_FOUND};
                              if (exUpload.callback !== undefined) {
                                  exUpload.callback(msg, false);
                              }
                              this.error(msg, object.fakeFile);
                              return;
                            }
                            def.resolve();
                            $.when(def).then(function () {
                                var item = $("#" + data.id);
                                item.find(".abortStyle").unbind("mouseover");
                                item.find(".abortStyle").css("display", "none");
                                item.removeClass("uploading");
                                setTimeout(function () {
                                    item.find(".exUpload").fadeOut("slow");
                                }, 2000);
                                if (exUpload.callback !== undefined) {
                                    exUpload.callback(data, true);
                                }
                            });
                        },
                        error: function (e) {
                            exUpload.error(e, object.fakeFile);
                        },
                        data: formData,
                        //Options to tell jQuery not to process data or worry about content-type.
                        cache: false,
                        contentType: false,
                        processData: false,
                        dataType: 'json'
                    });
                },
                createProgressStructure: function (id) {
                    var item = {id: $("#" + id), abortStyle: $("#" + id).find(".abortStyle")};
                    if (!item.id.hasClass("uploading")) {
                        item.id.addClass("uploading");
                    }
                    if (!item.id.find("#progressBar").length) {
                        item.id.append('

'
                            + '

Upload has Failed

'
                            + '

Abort?

'
                            + '
'
                            + '
'
                            + ''
                            + '
'
                            + '0 Kbps'
                            + '
');
                        item.abortStyle.find(".abortFont").on("mouseup", function () {
                            item.abortStyle.unbind("mouseover");
                            item.abortStyle.css("display", "none");
                            object.myXhr.abort();
                        });
                        item.abortStyle.on("mouseover", function () {
                            item.abortStyle.css("opacity", 0.8);
                        });
                        item.abortStyle.on("mouseout", function () {
                            item.abortStyle.css("opacity", 0);
                        });
                    }
                },
                progressEvent: function (e) {
                    if (e.lengthComputable) {
                        var item = $("#" + object.fakeFile.id);
                        var spentTime = Math.round(new Date() / 1000) - object.fakeFile.date;
                        object.createProgressStructure(object.fakeFile.id);
                        var percentLoaded = Math.round((e.loaded * 100) / e.total);
                        if (percentLoaded >= 100) {
                            item.find(".uploadSpeed").css("color", "white");
                            item.find("#" + object.fakeFile.id).removeClass("uploading");
                        } else if (percentLoaded >= 50) {
                            item.find(".percentCounterContainer").css("color", "white");
                        } else if (percentLoaded >= 10) {
                            item.find(".uploadSpeed").css("color", "white");
                        }

                        item.find(".percentConcluido").html(percentLoaded + "%");
                        item.find(".progressBar").css("height", percentLoaded + "%");
                        item.find(".uploadSpeed").html("^ " + Math.floor((e.loaded / 1024) / spentTime) + " Kbps");
                    }
                }
            };
            return object;
		}
    };
    return exUpload;
}<|endoftext|>


<commit_before>import gameApi from '../../lichess/game';
import ground from './ground';
import xhr from './roundXhr';
import sound from '../../sound';
import session from '../../session';
import utils from '../../utils';
import socket from '../../socket';

export default function(ctrl, onFeatured) {

  var handlers = {
    takebackOffers: function(o) {
      ctrl.data.player.proposingTakeback = o[ctrl.data.player.color];
      ctrl.data.opponent.proposingTakeback = o[ctrl.data.opponent.color];
      m.redraw();
    },
    move: function(o) {
      ctrl.apiMove(o);
    },
    checkCount: function(e) {
      var isWhite = ctrl.data.player.color === 'white';
      ctrl.data.player.checks = isWhite ? e.white : e.black;
      ctrl.data.opponent.checks = isWhite ? e.black : e.white;
      m.redraw();
    },
    reload: function() {
      xhr.reload(ctrl).then(ctrl.reload);
    },
    redirect: function(e) {
      if (!ctrl.data.tv) m.route('/game/' + e.id);
    },
    resync: function() {
      xhr.reload(ctrl).then(function(data) {
        socket.setVersion(data.player.version);
        ctrl.reload(data);
      }, function(err) {
        utils.handleXhrError(err);
      });
    },
    clock: function(o) {
      if (ctrl.clock) ctrl.clock.update(o.white, o.black);
    },
    end: function(winner) {
      ctrl.data.game.winner = winner;
      ground.end(ctrl.chessground);
      xhr.reload(ctrl).then(ctrl.reload);
      if (!ctrl.data.player.spectator) sound.dong();
      window.plugins.insomnia.allowSleepAgain();
      // refresh current games card list
      if (session.isConnected()) session.refresh();
      setTimeout(function() {
        ctrl.showActions();
        m.redraw();
      }, 1000);
    },
    gone: function(isGone) {
      if (!ctrl.data.opponent.ai) {
        gameApi.setIsGone(ctrl.data, ctrl.data.opponent.color, isGone);
        m.redraw();
      }
    },
    message: function(m) {
      if (ctrl.chat) ctrl.chat.append(m);
    },
    featured: function(o) {
      if (ctrl.data.tv && onFeatured) onFeatured(o);
    },
    crowd: function(o) {
      ['white', 'black'].forEach(function(c) {
        gameApi.setOnGame(ctrl.data, c, o[c]);
      });
      m.redraw();
    }
  };

  return function(type, data) {
    if (handlers[type]) {
      handlers[type](data);
      return true;
    }
    return false;
  };
}
<commit_msg>update TV websocket API<commit_after>import gameApi from '../../lichess/game';
import ground from './ground';
import xhr from './roundXhr';
import sound from '../../sound';
import session from '../../session';
import utils from '../../utils';
import socket from '../../socket';

export default function(ctrl, onFeatured) {

  var handlers = {
    takebackOffers: function(o) {
      ctrl.data.player.proposingTakeback = o[ctrl.data.player.color];
      ctrl.data.opponent.proposingTakeback = o[ctrl.data.opponent.color];
      m.redraw();
    },
    move: function(o) {
      ctrl.apiMove(o);
    },
    checkCount: function(e) {
      var isWhite = ctrl.data.player.color === 'white';
      ctrl.data.player.checks = isWhite ? e.white : e.black;
      ctrl.data.opponent.checks = isWhite ? e.black : e.white;
      m.redraw();
    },
    reload: function() {
      xhr.reload(ctrl).then(ctrl.reload);
    },
    redirect: function(e) {
      if (!ctrl.data.tv) m.route('/game/' + e.id);
    },
    resync: function() {
      xhr.reload(ctrl).then(function(data) {
        socket.setVersion(data.player.version);
        ctrl.reload(data);
      }, function(err) {
        utils.handleXhrError(err);
      });
    },
    clock: function(o) {
      if (ctrl.clock) ctrl.clock.update(o.white, o.black);
    },
    end: function(winner) {
      ctrl.data.game.winner = winner;
      ground.end(ctrl.chessground);
      xhr.reload(ctrl).then(ctrl.reload);
      if (!ctrl.data.player.spectator) sound.dong();
      window.plugins.insomnia.allowSleepAgain();
      // refresh current games card list
      if (session.isConnected()) session.refresh();
      setTimeout(function() {
        ctrl.showActions();
        m.redraw();
      }, 1000);
    },
    gone: function(isGone) {
      if (!ctrl.data.opponent.ai) {
        gameApi.setIsGone(ctrl.data, ctrl.data.opponent.color, isGone);
        m.redraw();
      }
    },
    message: function(m) {
      if (ctrl.chat) ctrl.chat.append(m);
    },
    tvSelect: function(o) {
      if (ctrl.data.tv && ctrl.data.tv.channel == 'best' & onFeatured) onFeatured(o);
    },
    crowd: function(o) {
      ['white', 'black'].forEach(function(c) {
        gameApi.setOnGame(ctrl.data, c, o[c]);
      });
      m.redraw();
    }
  };

  return function(type, data) {
    if (handlers[type]) {
      handlers[type](data);
      return true;
    }
    return false;
  };
}
<|endoftext|>


<commit_before>/**
 * TMP2 Build Script
 * Version: 0.0.1
 */

module.exports = function( grunt ) {

    // Project configuration.
    grunt.initConfig({
        pkg: grunt.file.readJSON('package.json'),
        meta: {
            banner:   '// ==========================================================================\n' +
                        '// Project:   The M-Project - Mobile HTML5 Application Framework\n' +
                        '// Version:   <%= pkg.version %>\n' +
                        '// Copyright: (c) <%= grunt.template.today("yyyy") %> M-Way Solutions GmbH. All rights reserved.\n' +
                        '// Date:      <%= grunt.template.today() %>\n' +
                        '// License:   Dual licensed under the MIT or GPL Version 2 licenses.\n' +
                        '//            http://github.com/mwaylabs/The-M-Project/blob/master/MIT-LICENSE\n' +
                        '//            http://github.com/mwaylabs/The-M-Project/blob/master/GPL-LICENSE\n' +
                        '// ==========================================================================\n',
            bannerCSS: '/*\n<%= meta.banner %>*/'
        },
        jsonlint: {
            sample: {
                src: [ 'package.json' ]
            }
        },
        jshint: {
            options: {
                jshintrc: '.jshintrc'
            },
            framework: [ 'src/**/*.js' ]
        },
        preprocess: {
            options: {
                context: {
                    DEBUG: false
                }
            },
            core: {
                files: {
                    'dist/tmp2.js': 'src/build.js',
                    'dist/tmp2.data.js': 'src/build.data.js',
                }
            },
            css: {
                files: {
                    'dist/tmp2.css': 'src/build.css'
                }
            }
        },
        uglify: {
            options: {
                banner: '<%= meta.banner %>'
            },
            core: {
                src: 'dist/tmp2.js',
                dest: 'dist/tmp2.min.js',
                options: {
                    sourceMap: 'dist/tmp2.map',
                    sourceMappingURL: 'tmp2.map',
                    sourceMapPrefix: 1
                }
            }
        },
        cssmin: {
            add_banner: {
                options: {
                    banner: '<%= meta.bannerCSS %>'
                },
                files: {
                    'dist/tmp2.min.css': ['dist/tmp2.css']
                }
            }
        },
        watch: {
            scripts: {
                files: ['src/**/*'],
                tasks: ['default'],
                options: {
                    spawn: false
                }
            }
        },
        mocha: {
            all: ['test/test.html']
        }
    });

    grunt.loadNpmTasks('grunt-jsonlint');
    grunt.loadNpmTasks('grunt-preprocess');
    grunt.loadNpmTasks('grunt-contrib-jshint');
    grunt.loadNpmTasks('grunt-contrib-watch');
    grunt.loadNpmTasks('grunt-contrib-uglify');
    grunt.loadNpmTasks('grunt-contrib-cssmin');
    grunt.loadNpmTasks('grunt-mocha');

    // TODO run jshint task
    //grunt.registerTask('test', ['jshint', 'mocha']);
    grunt.registerTask('test', ['mocha']);
    grunt.registerTask('dev', ['test', 'watch']);
    grunt.registerTask('default', ['preprocess', 'uglify', 'cssmin']);
};<commit_msg>add dev task<commit_after>/**
 * TMP2 Build Script
 * Version: 0.0.1
 */

module.exports = function( grunt ) {

    // Project configuration.
    grunt.initConfig({
        pkg: grunt.file.readJSON('package.json'),
        meta: {
            banner:   '// ==========================================================================\n' +
                        '// Project:   The M-Project - Mobile HTML5 Application Framework\n' +
                        '// Version:   <%= pkg.version %>\n' +
                        '// Copyright: (c) <%= grunt.template.today("yyyy") %> M-Way Solutions GmbH. All rights reserved.\n' +
                        '// Date:      <%= grunt.template.today() %>\n' +
                        '// License:   Dual licensed under the MIT or GPL Version 2 licenses.\n' +
                        '//            http://github.com/mwaylabs/The-M-Project/blob/master/MIT-LICENSE\n' +
                        '//            http://github.com/mwaylabs/The-M-Project/blob/master/GPL-LICENSE\n' +
                        '// ==========================================================================\n',
            bannerCSS: '/*\n<%= meta.banner %>*/'
        },
        jsonlint: {
            sample: {
                src: [ 'package.json' ]
            }
        },
        jshint: {
            options: {
                jshintrc: '.jshintrc'
            },
            framework: [ 'src/**/*.js' ]
        },
        preprocess: {
            options: {
                context: {
                    DEBUG: false
                }
            },
            core: {
                files: {
                    'dist/tmp2.js': 'src/build.js',
                    'dist/tmp2.data.js': 'src/build.data.js',
                }
            },
            css: {
                files: {
                    'dist/tmp2.css': 'src/build.css'
                }
            }
        },
        uglify: {
            options: {
                banner: '<%= meta.banner %>'
            },
            core: {
                src: 'dist/tmp2.js',
                dest: 'dist/tmp2.min.js',
                options: {
                    sourceMap: 'dist/tmp2.map',
                    sourceMappingURL: 'tmp2.map',
                    sourceMapPrefix: 1
                }
            }
        },
        cssmin: {
            add_banner: {
                options: {
                    banner: '<%= meta.bannerCSS %>'
                },
                files: {
                    'dist/tmp2.min.css': ['dist/tmp2.css']
                }
            }
        },
        watch: {
            framework: {
                files: ['src/**/*', 'test/**/*.js'],
                tasks: ['preprocess', 'dev'],
                options: {
                    spawn: false
                }
            }
        },
        mocha: {
            all: ['test/test.html']
        }
    });

    grunt.loadNpmTasks('grunt-jsonlint');
    grunt.loadNpmTasks('grunt-preprocess');
    grunt.loadNpmTasks('grunt-contrib-jshint');
    grunt.loadNpmTasks('grunt-contrib-watch');
    grunt.loadNpmTasks('grunt-contrib-uglify');
    grunt.loadNpmTasks('grunt-contrib-cssmin');
    grunt.loadNpmTasks('grunt-mocha');

    // TODO run jshint task
    //grunt.registerTask('test', ['jshint', 'mocha']);
    grunt.registerTask('test', ['mocha']);
    grunt.registerTask('dev', ['test', 'watch']);
    grunt.registerTask('default', ['preprocess', 'uglify', 'cssmin']);
};<|endoftext|>


<commit_before>import React, { Component } from 'react';
import Editor from 'draft-js-plugins-editor'; // eslint-disable-line import/no-unresolved
import createHashtagPlugin from 'draft-js-hashtag-plugin'; // eslint-disable-line import/no-unresolved
import createStickerPlugin from 'draft-js-sticker-plugin'; // eslint-disable-line import/no-unresolved
import createLinkifyPlugin from 'draft-js-linkify-plugin'; // eslint-disable-line import/no-unresolved
import createMentionPlugin, { defaultSuggestionsFilter } from 'draft-js-mention-plugin'; // eslint-disable-line import/no-unresolved
import createEmojiPlugin from 'draft-js-emoji-plugin'; // eslint-disable-line import/no-unresolved
import createUndoPlugin from 'draft-js-undo-plugin'; // eslint-disable-line import/no-unresolved
import styles from './styles.css';
import stickers from './stickers';
import mentions from './mentions';
import {
  // convertToRaw,
  convertFromRaw,
  ContentState,
  EditorState,
} from 'draft-js';
import initialState from './initialState';

const emojiPlugin = createEmojiPlugin();
const hashtagPlugin = createHashtagPlugin();
const linkifyPlugin = createLinkifyPlugin();
const mentionPlugin = createMentionPlugin();
const undoPlugin = createUndoPlugin();
const stickerPlugin = createStickerPlugin({
  stickers,
});
const { MentionSuggestions } = mentionPlugin;
const { EmojiSuggestions } = emojiPlugin;
const { StickerSelect } = stickerPlugin;
const { UndoButton, RedoButton } = undoPlugin;

const plugins = [
  emojiPlugin,
  hashtagPlugin,
  stickerPlugin,
  linkifyPlugin,
  mentionPlugin,
  undoPlugin,
];

const contentState = ContentState.createFromBlockArray(convertFromRaw(initialState));

export default class UnicornEditor extends Component {

  state = {
    editorState: EditorState.createWithContent(contentState),
    suggestions: mentions,
  };

  onChange = (editorState) => {
    this.setState({
      editorState,
    });

    // console.log(JSON.stringify(convertToRaw(editorState.getCurrentContent())));
  };

  onMentionSearchChange = ({ value }) => {
    this.setState({
      suggestions: defaultSuggestionsFilter(value, mentions),
    });
  };

  focus = () => {
    this.refs.editor.focus();
  };

  render() {
    return (

          <Editor
            editorState={this.state.editorState}
            onChange={this.onChange}
            plugins={plugins}
            spellCheck
            ref="editor"
          />

          <MentionSuggestions
            onSearchChange={this.onMentionSearchChange}
            suggestions={this.state.suggestions}
          />
          <EmojiSuggestions />

            <StickerSelect editor={this} />

            <UndoButton />

            <RedoButton />

    );
  }
}
<commit_msg>temporarily disable loading the editor content to get the docs working<commit_after>import React, { Component } from 'react';
import Editor from 'draft-js-plugins-editor'; // eslint-disable-line import/no-unresolved
import createHashtagPlugin from 'draft-js-hashtag-plugin'; // eslint-disable-line import/no-unresolved
import createStickerPlugin from 'draft-js-sticker-plugin'; // eslint-disable-line import/no-unresolved
import createLinkifyPlugin from 'draft-js-linkify-plugin'; // eslint-disable-line import/no-unresolved
import createMentionPlugin, { defaultSuggestionsFilter } from 'draft-js-mention-plugin'; // eslint-disable-line import/no-unresolved
import createEmojiPlugin from 'draft-js-emoji-plugin'; // eslint-disable-line import/no-unresolved
import createUndoPlugin from 'draft-js-undo-plugin'; // eslint-disable-line import/no-unresolved
import styles from './styles.css';
import stickers from './stickers';
import mentions from './mentions';
import {
  // convertToRaw,
  // convertFromRaw,
  ContentState,
  EditorState,
} from 'draft-js';
// import initialState from './initialState';

const emojiPlugin = createEmojiPlugin();
const hashtagPlugin = createHashtagPlugin();
const linkifyPlugin = createLinkifyPlugin();
const mentionPlugin = createMentionPlugin();
const undoPlugin = createUndoPlugin();
const stickerPlugin = createStickerPlugin({
  stickers,
});
const { MentionSuggestions } = mentionPlugin;
const { EmojiSuggestions } = emojiPlugin;
const { StickerSelect } = stickerPlugin;
const { UndoButton, RedoButton } = undoPlugin;

const plugins = [
  emojiPlugin,
  hashtagPlugin,
  stickerPlugin,
  linkifyPlugin,
  mentionPlugin,
  undoPlugin,
];

// const contentState = ContentState.createFromBlockArray(convertFromRaw(initialState));
const contentState = ContentState.createFromText('Initial text …');

export default class UnicornEditor extends Component {

  state = {
    editorState: EditorState.createWithContent(contentState),
    suggestions: mentions,
  };

  onChange = (editorState) => {
    this.setState({
      editorState,
    });

    // console.log(JSON.stringify(convertToRaw(editorState.getCurrentContent())));
  };

  onMentionSearchChange = ({ value }) => {
    this.setState({
      suggestions: defaultSuggestionsFilter(value, mentions),
    });
  };

  focus = () => {
    this.refs.editor.focus();
  };

  render() {
    return (

          <Editor
            editorState={this.state.editorState}
            onChange={this.onChange}
            plugins={plugins}
            spellCheck
            ref="editor"
          />

          <MentionSuggestions
            onSearchChange={this.onMentionSearchChange}
            suggestions={this.state.suggestions}
          />
          <EmojiSuggestions />

            <StickerSelect editor={this} />

            <UndoButton />

            <RedoButton />

    );
  }
}
<|endoftext|>


<commit_before>import PropTypes from 'prop-types'
import React, { Component } from 'react'
import { bindActionCreators } from 'redux'
import { connect } from 'react-redux'
import Navbar from './components/Navbar'
import { AppsActions } from './store/apps'
import { Box, Flex, Type } from 'blockstack-ui'
import { Hover } from 'react-powerplug'
import { Spinner } from '@components/ui/components/spinner'

const Loading = ({ ...rest }) => (
  <Flex
    flexDirection="column"
    alignItems="center"
    width={1}
    justifyContent="center"
    p={4}
    {...rest}
  >
    <Box width="48px" mx="auto">
      <Spinner color="black" size={48} />
    </Box>
    <Box py={4} textAlign="center">
      <Type fontWeight="500" fontSize={2} opacity={0.5}>
        Fetching apps...
      </Type>
    </Box>
  </Flex>
)

const Content = ({ topApps, allApps, ...rest }) => (
  <Box maxWidth={1280} width="100%" mx="auto" p={[1, 2, 4]} {...rest}>
    <AppsSection title="Top Ranked Apps" apps={topApps} limit={24} />
    {allApps.map(category => (
      <AppsSection title={category.label} apps={category.apps} limit={15} />
    ))}
  </Box>
)

const AppsSection = ({ title, apps, limit, category, ...rest }) => {
  let appsList = apps.filter(app => app.imgixImageUrl)
  if (limit) {
    appsList = appsList.filter((app, i) => i <= limit - 1)
  }
  if (category) {
    appsList = appsList.filter(app => app.category === category)
  }
  return (
    <Box
      width={1}
      mx="auto"
      p={4}
      mb={4}
      borderBottom="1px solid rgba(15,15,15,0.1)"
      {...rest}
    >
      <Box textAlign="center">

{title}

      </Box>
      <Flex
        pt={4}
        justifyContent={['space-between', 'center']}
        alignItems="flex-start"
        flexWrap="wrap"
      >
        {appsList.map(app => (
          <AppItem
            key={app.name}
            name={app.name}
            imgixImageUrl={app.imgixImageUrl}
            website={app.website}
            description={app.description}
          />
        ))}
      </Flex>
    </Box>
  )
}

const Image = props => (
  <Box
    is="img"
    borderRadius="15px"
    boxShadow="0px 0px 35px 0px rgba(0, 0, 0, 0.15)"
    bg="white"
    {...props}
  />
)

const AppItem = ({ website, imgixImageUrl, name, description }) => {
  const descMaxLength = 55
  let desc = description.trim()

  if (description[description.length - 1] !== '.') {
    desc += '.'
  }

  if (description.length > descMaxLength) {
    desc = <>{desc.substring(0, descMaxLength).trim()}…</>
  }

  return (
    <Hover>
      {({ bind, hovered }) => (
        <Box
          width={['calc(50% - 10px)', 1 / 3, 1 / 3, 1 / 4]}
          maxWidth={['160px', 'unset', 'unset', 'unset']}
          pr={[0, 3, 3, 4]}
          flexShrink={0}
          mb={[5]}
          transition="0.15s all ease-in-out"
          transform={hovered ? 'translateY(-5px)' : 'none'}
          color="blue.dark"
          {...bind}
        >
          <Flex
            maxWidth="100%"
            width={1}
            is="a"
            href={website}
            target="_blank"
            alignItems="center"
            flexDirection={['column', 'row', 'row', 'row']}
            textAlign={['center', 'left', 'left', 'left']}
            style={{
              textDecoration: 'none',
              color: 'black !important'
            }}
          >
            <Image
              maxWidth="100%"
              width="64px"
              display="block"
              flexShrink="0"
              src={imgixImageUrl}
              alt={name}
            />
            <Box ml={[0, 3, 3, 3]} mt={[3, 0, 0, 0]}>
              <Box>
                <Type
                  is="h3"
                  fontSize={[2]}
                  lineHeight={1.45}
                  fontWeight="600"
                  color="black !important"
                  mb={1}
                >
                  {name}
                </Type>
              </Box>
              <Box
                opacity={0.75}
                color="black !important"
                style={{
                  hyphens: 'auto'
                }}
              >
                {desc}
              </Box>
            </Box>
          </Flex>
        </Box>
      )}
    </Hover>
  )
}

const HomeScreenPage = props => {
  const loading = props.apps && props.apps.loading && !props.apps.topApps.length
  return (
    <Box>
      <Navbar hideBackToHomeLink activeTab="home" />
      <Box className="home-screen">
        {loading ? (
          <Loading />
        ) : (
          <Content
            allApps={!loading && props.apps.appsByCategory}
            topApps={!loading && props.apps.topApps}
          />
        )}
      </Box>
    </Box>
  )
}

Content.propTypes = {
  topApps: PropTypes.array.isRequired,
  allApps: PropTypes.array.isRequired
}

AppsSection.propTypes = {
  title: PropTypes.string.isRequired,
  apps: PropTypes.array.isRequired,
  limit: PropTypes.number.isRequired,
  category: PropTypes.string.isRequired
}
AppItem.propTypes = {
  website: PropTypes.string.isRequired,
  imgixImageUrl: PropTypes.string.isRequired,
  name: PropTypes.string.isRequired,
  description: PropTypes.string.isRequired
}

HomeScreenPage.propTypes = {
  apps: PropTypes.object.isRequired,
  refreshAppList: PropTypes.func.isRequired,
  doFetchApps: PropTypes.func.isRequired,
  appListLastUpdated: PropTypes.number,
  api: PropTypes.object.isRequired,
  instanceIdentifier: PropTypes.string,
  instanceCreationDate: PropTypes.number
}

const mapStateToProps = state => ({
  apps: state.apps,
  appListLastUpdated: state.apps.lastUpdated,
  api: state.settings.api,
  instanceIdentifier: state.apps.instanceIdentifier,
  instanceCreationDate: state.apps.instanceCreationDate
})

const mapDispatchToProps = dispatch =>
  bindActionCreators({ ...AppsActions }, dispatch)

export default connect(
  mapStateToProps,
  mapDispatchToProps
)(HomeScreenPage)
<commit_msg>square icons<commit_after>import PropTypes from 'prop-types'
import React, { Component } from 'react'
import { bindActionCreators } from 'redux'
import { connect } from 'react-redux'
import Navbar from './components/Navbar'
import { AppsActions } from './store/apps'
import { Box, Flex, Type } from 'blockstack-ui'
import { Hover } from 'react-powerplug'
import { Spinner } from '@components/ui/components/spinner'

const Loading = ({ ...rest }) => (
  <Flex
    flexDirection="column"
    alignItems="center"
    width={1}
    justifyContent="center"
    p={4}
    {...rest}
  >
    <Box width="48px" mx="auto">
      <Spinner color="black" size={48} />
    </Box>
    <Box py={4} textAlign="center">
      <Type fontWeight="500" fontSize={2} opacity={0.5}>
        Fetching apps...
      </Type>
    </Box>
  </Flex>
)

const Content = ({ topApps, allApps, ...rest }) => (
  <Box maxWidth={1280} width="100%" mx="auto" p={[1, 2, 4]} {...rest}>
    <AppsSection title="Top Ranked Apps" apps={topApps} limit={24} />
    {allApps.map(category => (
      <AppsSection title={category.label} apps={category.apps} limit={15} />
    ))}
  </Box>
)

const AppsSection = ({ title, apps, limit, category, ...rest }) => {
  let appsList = apps.filter(app => app.imgixImageUrl)
  if (limit) {
    appsList = appsList.filter((app, i) => i <= limit - 1)
  }
  if (category) {
    appsList = appsList.filter(app => app.category === category)
  }
  return (
    <Box
      width={1}
      mx="auto"
      p={4}
      mb={4}
      borderBottom="1px solid rgba(15,15,15,0.1)"
      {...rest}
    >
      <Box textAlign="center">

{title}

      </Box>
      <Flex
        pt={4}
        justifyContent={['space-between', 'center']}
        alignItems="flex-start"
        flexWrap="wrap"
      >
        {appsList.map(app => (
          <AppItem
            key={app.name}
            name={app.name}
            imgixImageUrl={app.imgixImageUrl}
            website={app.website}
            description={app.description}
          />
        ))}
      </Flex>
    </Box>
  )
}

const Image = props => (
  <Box
    is="img"
    borderRadius="15px"
    boxShadow="0px 0px 35px 0px rgba(0, 0, 0, 0.15)"
    bg="white"
    {...props}
  />
)

const AppItem = ({ website, imgixImageUrl, name, description }) => {
  const descMaxLength = 55
  let desc = description.trim()

  if (description[description.length - 1] !== '.') {
    desc += '.'
  }

  if (description.length > descMaxLength) {
    desc = <>{desc.substring(0, descMaxLength).trim()}…</>
  }

  return (
    <Hover>
      {({ bind, hovered }) => (
        <Box
          width={['calc(50% - 10px)', 1 / 3, 1 / 3, 1 / 4]}
          maxWidth={['160px', 'unset', 'unset', 'unset']}
          pr={[0, 3, 3, 4]}
          flexShrink={0}
          mb={[5]}
          transition="0.15s all ease-in-out"
          transform={hovered ? 'translateY(-5px)' : 'none'}
          color="blue.dark"
          {...bind}
        >
          <Flex
            maxWidth="100%"
            width={1}
            is="a"
            href={website}
            target="_blank"
            alignItems="center"
            flexDirection={['column', 'row', 'row', 'row']}
            textAlign={['center', 'left', 'left', 'left']}
            style={{
              textDecoration: 'none',
              color: 'black !important'
            }}
          >
            <Image
              maxWidth="100%"
              size="64px"
              display="block"
              flexShrink="0"
              src={imgixImageUrl}
              alt={name}
            />
            <Box ml={[0, 3, 3, 3]} mt={[3, 0, 0, 0]}>
              <Box>
                <Type
                  is="h3"
                  fontSize={[2]}
                  lineHeight={1.45}
                  fontWeight="600"
                  color="black !important"
                  mb={1}
                >
                  {name}
                </Type>
              </Box>
              <Box
                opacity={0.75}
                color="black !important"
                style={{
                  hyphens: 'auto'
                }}
              >
                {desc}
              </Box>
            </Box>
          </Flex>
        </Box>
      )}
    </Hover>
  )
}

const HomeScreenPage = props => {
  const loading = props.apps && props.apps.loading && !props.apps.topApps.length
  return (
    <Box>
      <Navbar hideBackToHomeLink activeTab="home" />
      <Box className="home-screen">
        {loading ? (
          <Loading />
        ) : (
          <Content
            allApps={!loading && props.apps.appsByCategory}
            topApps={!loading && props.apps.topApps}
          />
        )}
      </Box>
    </Box>
  )
}

Content.propTypes = {
  topApps: PropTypes.array.isRequired,
  allApps: PropTypes.array.isRequired
}

AppsSection.propTypes = {
  title: PropTypes.string.isRequired,
  apps: PropTypes.array.isRequired,
  limit: PropTypes.number.isRequired,
  category: PropTypes.string.isRequired
}
AppItem.propTypes = {
  website: PropTypes.string.isRequired,
  imgixImageUrl: PropTypes.string.isRequired,
  name: PropTypes.string.isRequired,
  description: PropTypes.string.isRequired
}

HomeScreenPage.propTypes = {
  apps: PropTypes.object.isRequired,
  refreshAppList: PropTypes.func.isRequired,
  doFetchApps: PropTypes.func.isRequired,
  appListLastUpdated: PropTypes.number,
  api: PropTypes.object.isRequired,
  instanceIdentifier: PropTypes.string,
  instanceCreationDate: PropTypes.number
}

const mapStateToProps = state => ({
  apps: state.apps,
  appListLastUpdated: state.apps.lastUpdated,
  api: state.settings.api,
  instanceIdentifier: state.apps.instanceIdentifier,
  instanceCreationDate: state.apps.instanceCreationDate
})

const mapDispatchToProps = dispatch =>
  bindActionCreators({ ...AppsActions }, dispatch)

export default connect(
  mapStateToProps,
  mapDispatchToProps
)(HomeScreenPage)
<|endoftext|>


<commit_before>class Base {}
const Trait = function(traitFunc) {
	traitFunc.__trait__ = true;
	return traitFunc;
};
const withTraits = function(baseClassOrFirstTrait, ...traits) {
	var baseClass = baseClassOrFirstTrait.__trait__ ? baseClassOrFirstTrait(Base) : baseClassOrFirstTrait;
	return traits.reduce((parentClass, trait) => trait(parentClass), baseClass);
}

if (typeof module !== 'undefined') {
	module.exports = {
		Trait: Trait,
		withTraits: withTraits
	};
}

if (require.main === module) {
	class Animal {}
	let Flying = Trait(function(parentClass) {
		return class Flying extends parentClass {
			constructor(...args) {
				super(...args);
				this.wings = ["left wing", "right wing"];
			}
			fly() {
				console.log("flap flap with the " + this.wings.join("and"));
			}
		};
	});
	let Walking = Trait(function(parentClass) {
		return class Walking extends parentClass {
			constructor(...args) {
				super(...args);
				this.legs = []; // there must be legs, we don't know how many

				// Also to be researched (as an alternative to the above):
				// Legged.check(this);
			}
			walk() {
				console.log("walking on legs " + this.legs.join(" and "));
			}
		};
	});
	let Biped = Trait(function(parentClass) {
		return class Biped extends parentClass {
			constructor(...args) {
				super(...args);
				this.legs = ["left leg", "right leg"];
			}
		};
	});
	let Quadruped = Trait(function(parentClass) {
		return class Quadruped extends parentClass {
			constructor(...args) {
				super(...args);
				this.legs = ["front left leg", "front right leg", "rear left leg", "rear right leg"];
			}
		};
	});

	// @TODO why does it work for Walking, Biped, but not for Biped, Walking ?
	class Dog extends withTraits(Animal, Quadruped, Walking) {}
	class Bird extends withTraits(Animal, Walking, Biped, Flying) {}

	let dog = new Dog();
	dog.walk();
	let bird = new Bird();
	bird.walk();
	bird.fly();
}
<commit_msg>src/es6-with-traits.js: Fixed and improved example code<commit_after>class Base {}
const Trait = function(traitFunc) {
	traitFunc.__trait__ = true;
	return traitFunc;
};
const withTraits = function(baseClassOrFirstTrait, ...traits) {
	var baseClass = baseClassOrFirstTrait.__trait__ ? baseClassOrFirstTrait(Base) : baseClassOrFirstTrait;
	return traits.reduce((parentClass, trait) => trait(parentClass), baseClass);
}

if (typeof module !== 'undefined') {
	module.exports = {
		Trait: Trait,
		withTraits: withTraits
	};
}

if (require.main === module) {
	class Animal {}
	let Flying = Trait(function(parentClass) {
		return class Flying extends parentClass {
			constructor(...args) {
				super(...args);
				this.wings = ["left wing", "right wing"];
			}
			fly() {
				console.log("flap flap with the " + this.wings.join(" and "));
			}
		};
	});
	let Walking = Trait(function(parentClass) {
		return class Walking extends parentClass {
			constructor(...args) {
				super(...args);
				this.legs = this.legs || []; // there must be legs, by default we don't know how many

				// Also to be researched (as an alternative to the above):
				// Legged.check(this);
			}
			walk() {
				console.log("walking on legs " + this.legs.join(" and "));
			}
		};
	});
	let Biped = Trait(function(parentClass) {
		return class Biped extends parentClass {
			constructor(...args) {
				super(...args);
				this.legs = ["left leg", "right leg"];
			}
		};
	});
	let Quadruped = Trait(function(parentClass) {
		return class Quadruped extends parentClass {
			constructor(...args) {
				super(...args);
				this.legs = ["front left leg", "front right leg", "rear left leg", "rear right leg"];
			}
		};
	});

	class Dog extends withTraits(Animal, Quadruped, Walking) {}
	class Bird extends withTraits(Animal, Biped, Walking, Flying) {}

	let dog = new Dog();
	console.log("dog.walk():");
	dog.walk();
	let bird = new Bird();
	console.log("bird.walk():");
	bird.walk();
	console.log("bird.fly():");
	bird.fly();
}
<|endoftext|>


<commit_before>/**
 * @class EarthTrekData
 * @module EarthTrek
 * @author SATrek
 * @author Alejandro Sanchez <alejandro.sanchez.trek@gmail.com>
 * @description EarthTrek - NASA Space Apps 2017 23 APR 2017.
 */

var earthTrekData = earthTrekData || {};
define([
    'underscore',
    'earthtrek-satellite'
], function (_, earthTrekSatellitez) {
    'use strict';

    var satelliteIds = [];

    /**
     *
     */
    earthTrekData.getSatelliteIds = function () {
        if (satelliteIds != null) {
            return satelliteIds;
        }
        earthTrekData.getSatellites().then(function(satellites) {
            var satIds = [];
            satellites.data.forEach(function (satellite) {
                satIds.push(satellite.satId);
            })
            satelliteIds = satIds;
            return satIds;
        });
    }
    /**
     *
     */
    earthTrekData.getSatellites = function () {
        return $.ajax("http://api.orbitaldesign.tk/satellites");
    }

    /**
     *
     */
    earthTrekData.getTLEs = function (ids, options) {
        var params = [];
        params.push('ids=' + ids.join(','));
        if (options.startDate) {
            var startDate = options.startDate;
            if (startDate instanceof Date) {
                startDate = startDate.getUTCFullYear() + '-' + (startDate.getUTCMonth() + 1) + '-' +  startDate.getUTCDate();
            }
            params.push('startDate=' + startDate);
            if (options.endDate) {
                var endDate = options.endDate;
                if (endDate instanceof Date) {
                    endDate = endDate.getUTCFullYear() + '-' + (endDate.getUTCMonth() + 1) + '-' +  endDate.getUTCDate();
                }
                params.push('endDate=' + endDate);
            }
        }
        return $.ajax("http://api.orbitaldesign.tk/tles?" + params.join('&'));
    }

    /**
     *
     */
    earthTrekData.getFullData = function (options, callback) {
        var promise = earthTrekData.getSatellites();

        var tlePromise = promise.then(function(satellites) {
            var satIds = [];
            satellites.data.forEach(function (satellite) {
                satIds.push(satellite.satId);
            })
            satelliteIds = satIds;
            return earthTrekData.getTLEs(satIds, options);
        });
        Promise.all([promise, tlePromise]).then(function(tles) {
            /**
             * @TODO -TEMPORAL
             */
            var finalJson = [];
            tles[0].data.forEach(function (satellite) {
                tles[1].data.forEach(function(satTle) {
                    if (satellite.satId == satTle.satId) {
                        finalJson.push(_.extend(satTle, satellite));
                    }
                });
            });
            callback(finalJson);
        });
    }
});<commit_msg>StartDate fix<commit_after>/**
 * @class EarthTrekData
 * @module EarthTrek
 * @author SATrek
 * @author Alejandro Sanchez <alejandro.sanchez.trek@gmail.com>
 * @description EarthTrek - NASA Space Apps 2017 23 APR 2017.
 */

var earthTrekData = earthTrekData || {};
define([
    'underscore',
    'earthtrek-satellite'
], function (_, earthTrekSatellitez) {
    'use strict';

    var satelliteIds = [];

    /**
     *
     */
    earthTrekData.getSatelliteIds = function () {
        if (satelliteIds != null) {
            return satelliteIds;
        }
        earthTrekData.getSatellites().then(function(satellites) {
            var satIds = [];
            satellites.data.forEach(function (satellite) {
                satIds.push(satellite.satId);
            })
            satelliteIds = satIds;
            return satIds;
        });
    }
    /**
     *
     */
    earthTrekData.getSatellites = function () {
        return $.ajax("http://api.orbitaldesign.tk/satellites");
    }

    /**
     *
     */
    earthTrekData.getTLEs = function (ids, options) {
        var params = [];
        params.push('ids=' + ids.join(','));
        if (options.startDate) {
            var startDate = options.startDate;

            if (!(startDate instanceof Date)) {
                var startDate = new Date(startDate);
                startDate.setDate(startDate.getDate() - 1);
            }

            if (startDate instanceof Date) {
                startDate = startDate.getUTCFullYear() + '-' + (startDate.getUTCMonth() + 1) + '-' +  startDate.getUTCDate();
            }
            params.push('startDate=' + startDate);
            if (options.endDate) {
                var endDate = options.endDate;
                if (endDate instanceof Date) {
                    endDate = endDate.getUTCFullYear() + '-' + (endDate.getUTCMonth() + 1) + '-' +  endDate.getUTCDate();
                }
                params.push('endDate=' + endDate);
            }
        }
        return $.ajax("http://api.orbitaldesign.tk/tles?" + params.join('&'));
    }

    /**
     *
     */
    earthTrekData.getFullData = function (options, callback) {
        var promise = earthTrekData.getSatellites();

        var tlePromise = promise.then(function(satellites) {
            var satIds = [];
            satellites.data.forEach(function (satellite) {
                satIds.push(satellite.satId);
            })
            satelliteIds = satIds;
            return earthTrekData.getTLEs(satIds, options);
        });
        Promise.all([promise, tlePromise]).then(function(tles) {
            /**
             * @TODO -TEMPORAL
             */
            var finalJson = [];
            tles[0].data.forEach(function (satellite) {
                tles[1].data.forEach(function(satTle) {
                    if (satellite.satId == satTle.satId) {
                        finalJson.push(_.extend(satTle, satellite));
                    }
                });
            });
            callback(finalJson);
        });
    }
});<|endoftext|>


<commit_before>'use strict'

const fastseries = require('fastseries')
const EE = require('events').EventEmitter
const inherits = require('inherits')

function Boot (server, done) {
  if (!(this instanceof Boot)) {
    return new Boot(server, done)
  }

  if (typeof server === 'function') {
    done = server
    server = null
  }

  server = server || this

  this._series = fastseries()

  this._current = null

  this._process = (toLoad, cb) => {
    const func = toLoad.plugin
    this._current = toLoad
    this._current.onFinish = cb
    func(server, toLoad.opts, (err) => {
      if (err) {
        toLoad.callback(err)
        process.nextTick(cb, err)
        return
      }

      if (!toLoad.deferred) {
        this._current = null
        process.nextTick(clear, this, (err) => {
          if (err) {
            this.emit('error', err)
          }
          toLoad.callback(err)
          cb(err)
        })
      }
    })
  }

  if (done) {
    this.on('start', done)
  }

  this._batch = []

  // always trigger start in the next tick
  // if no "use" is called first
  process.nextTick(clear, this, (err) => {
    if (err) {
      this.emit('error', err)
    } else {
      this.emit('start')
    }
  })
}

inherits(Boot, EE)

Boot.prototype.use = function (plugin, opts, callback) {
  if (typeof opts === 'function') {
    callback = opts
    opts = null
  }
  opts = opts || {}
  callback = callback || noop
  const current = this._current

  const obj = {
    plugin,
    opts,
    callback,
    deferred: false
  }

  // defer finishing off the current element if we have a callback
  if (callback !== noop && current && !current.deferred) {
    current.deferred = true
    process.nextTick(clear, this, (err) => {
      if (err) {
        this.emit('error', err)
      }
      current.callback(err)
      current.onFinish(err)
    })
  }

  this._batch.push(obj)
}

// executes all elements in the batch in series
function clear (boot, cb) {
  const batch = boot._batch
  boot._batch = []

  cb = cb || noop

  boot._series(boot, boot._process, batch, cb)
}

function noop () {}

module.exports = Boot
<commit_msg>Always defer.<commit_after>'use strict'

const fastseries = require('fastseries')
const EE = require('events').EventEmitter
const inherits = require('inherits')

function Boot (server, done) {
  if (!(this instanceof Boot)) {
    return new Boot(server, done)
  }

  if (typeof server === 'function') {
    done = server
    server = null
  }

  server = server || this

  this._series = fastseries()

  this._current = null

  this._process = (toLoad, cb) => {
    const func = toLoad.plugin
    this._current = toLoad
    this._current.onFinish = cb
    func(server, toLoad.opts, (err) => {
      if (err) {
        toLoad.callback(err)
        process.nextTick(cb, err)
        return
      }

      if (!toLoad.deferred) {
        this._current = null
        process.nextTick(clear, this, (err) => {
          if (err) {
            this.emit('error', err)
          }
          toLoad.callback(err)
          cb(err)
        })
      }
    })
  }

  if (done) {
    this.on('start', done)
  }

  this._batch = []

  // always trigger start in the next tick
  // if no "use" is called first
  process.nextTick(clear, this, (err) => {
    if (err) {
      this.emit('error', err)
    } else {
      this.emit('start')
    }
  })
}

inherits(Boot, EE)

Boot.prototype.use = function (plugin, opts, callback) {
  if (typeof opts === 'function') {
    callback = opts
    opts = null
  }
  opts = opts || {}
  callback = callback || noop
  const current = this._current

  const obj = {
    plugin,
    opts,
    callback,
    deferred: false
  }

  // defer finishing off the current element
  if (current && !current.deferred) {
    current.deferred = true
    process.nextTick(clear, this, (err) => {
      if (err) {
        this.emit('error', err)
      }
      current.callback(err)
      current.onFinish(err)
    })
  }

  this._batch.push(obj)
}

// executes all elements in the batch in series
function clear (boot, cb) {
  const batch = boot._batch
  boot._batch = []

  cb = cb || noop

  boot._series(boot, boot._process, batch, cb)
}

function noop () {}

module.exports = Boot
<|endoftext|>


<commit_before><commit_msg>simple backend draft<commit_after><|endoftext|>


<commit_before>var mydata = {

	"chart": {
		"caption": "Comparison of Data",
		"subcaption": "Axis 1,2,3",
		"width": 300,
		"height": 300,
		"chartType": "crosstab", //line,column,crosstab
		"ordering": "default" //default,ascending,descending
	},
	"data": [{
			"time": "21-06",
			"yAxis1": 0.5,
			"yAxis2": 54,
			"yAxis3": 366,
			"yAxis4": 8,
			"yAxis5": 110,
			"yAxis6": 69
		}, {
			"time": "22-06",
			"yAxis1": 0.6,
			"yAxis2": 33,
			"yAxis3": 282,
			"yAxis4": 5,
			"yAxis5": 103,
			"yAxis6": 50
		}, {
			"time": "23-06",
			"yAxis1": 0.9,
			"yAxis2": 44,
			"yAxis3": 354,
			"yAxis4": 2,
			"yAxis6": 85
		}, {
			"time": "24-06",
			"yAxis1": 0.3,
			"yAxis2": 55,
			"yAxis3": 380,
			"yAxis4": 1,
			"yAxis5": 112,
			"yAxis6": 45
		}, {
			"time": "25-06",
			"yAxis1": 0.1,
			"yAxis2": 72,
			"yAxis3": 421,
			"yAxis4": 6,
			"yAxis5": 121,
			"yAxis6": 75
		}, {
			"time": "26-06",
			"yAxis1": 0.2,
			"yAxis2": 76,
			"yAxis3": 698,
			"yAxis4": 3,
			"yAxis5": 115,
			"yAxis6": 36
		}, {
			"time": "27-06",
			"yAxis1": 0.3,
			"yAxis2": 25,
			"yAxis3": 969,
			"yAxis4": 9,
			"yAxis5": 103,
			"yAxis6": 98
		}, {
			"time": "28-06",
			"yAxis1": 0.8,
			"yAxis2": 65,
			"yAxis3": 533,
			"yAxis4": 2,
			"yAxis5": 125,
			"yAxis6": 46
		}, {
			"time": "29-06",
			"yAxis1": 0.1,
			"yAxis2": 45,
			"yAxis3": 545,
			"yAxis4": 4,
			"yAxis5": 113,
			"yAxis6": 80
		}, {
			"time": "30-06",
			"yAxis1": 0.3,
			"yAxis2": 85,
			"yAxis3": 754,
			"yAxis4": 6,
			"yAxis5": 124,
			"yAxis6": 85
		}, {
			"category": "coffee",
			"zone": "central",
			"subcategory": "Amaretto",
			"sop": "5105",
			"sos": "14011"
		}, {
			"category": "coffee",
			"zone": "central",
			"subcategory": "Columbian",
			"sop": "8528",
			"sos": "28913"
		}, {
			"category": "coffee",
			"zone": "central",
			"subcategory": "Decaf Irish Cream",
			"sop": "9632",
			"sos": "26155"
		},

		{
			"category": "coffee",
			"zone": "east",
			"subcategory": "Amaretto",
			"sop": "1009",
			"sos": "2993"
		}, {
			"category": "coffee",
			"zone": "east",
			"subcategory": "Columbian",
			"sop": "27253",
			"sos": "47386"
		}, {
			"category": "coffee",
			"zone": "east",
			"subcategory": "Decaf Irish Cream",
			"sop": "2727",
			"sos": "6261"
		},

		{
			"category": "coffee",
			"zone": "south",
			"subcategory": "Columbian",
			"sop": "8767",
			"sos": "21664"
		}, {
			"category": "coffee",
			"zone": "south",
			"subcategory": "Decaf Irish Cream",
			"sop": "2933",
			"sos": "11592"
		},

		{
			"category": "coffee",
			"zone": "west",
			"subcategory": "Amaretto",
			"sop": "(1225)",
			"sos": "9265"
		}, {
			"category": "coffee",
			"zone": "west",
			"subcategory": "Columbian",
			"sop": "11253",
			"sos": "30357"
		}, {
			"category": "coffee",
			"zone": "west",
			"subcategory": "Decaf Irish Cream",
			"sop": "(1305)",
			"sos": "18235"
		},

		{
			"category": "expresso",
			"zone": "central",
			"subcategory": "Caffe Mocha",
			"sop": "14640",
			"sos": "35218"
		}, {
			"category": "expresso",
			"zone": "central",
			"subcategory": "Decaf Expresso",
			"sop": "8860",
			"sos": "24485"
		},

		{
			"category": "expresso",
			"zone": "east",
			"subcategory": "Caffe Mocha",
			"sop": "(6230)",
			"sos": "16646"
		}, {
			"category": "expresso",
			"zone": "east",
			"subcategory": "Decaf Expresso",
			"sop": "2410",
			"sos": "7722"
		}, {
			"category": "expresso",
			"zone": "east",
			"subcategory": "Regular Expresso",
			"sop": "10062",
			"sos": "24036"
		},

		{
			"category": "expresso",
			"zone": "south",
			"subcategory": "Caffe Latte",
			"sop": "3872",
			"sos": "15442"
		}, {
			"category": "expresso",
			"zone": "south",
			"subcategory": "Caffe Mocha",
			"sop": "5201",
			"sos": "14163"
		}, {
			"category": "expresso",
			"zone": "south",
			"subcategory": "Decaf Expresso",
			"sop": "5930",
			"sos": "15384"
		},

		{
			"category": "expresso",
			"zone": "west",
			"subcategory": "Caffe Latte",
			"sop": "7502",
			"sos": "20458"
		}, {
			"category": "expresso",
			"zone": "west",
			"subcategory": "Caffe Mocha",
			"sop": "4064",
			"sos": "18876"
		}, {
			"category": "expresso",
			"zone": "west",
			"subcategory": "Decaf Expresso",
			"sop": "12302",
			"sos": "30578"
		},

		{
			"category": "herbal tea",
			"zone": "central",
			"subcategory": "Chamomile",
			"sop": "14436",
			"sos": "36570"
		}, {
			"category": "herbal tea",
			"zone": "central",
			"subcategory": "Lemon",
			"sop": "6251",
			"sos": "21978"
		}, {
			"category": "herbal tea",
			"zone": "central",
			"subcategory": "Mint",
			"sop": "4069",
			"sos": "9337"
		},

		{
			"category": "herbal tea",
			"zone": "east",
			"subcategory": "Chamomile",
			"sop": "765",
			"sos": "2194"
		}, {
			"category": "herbal tea",
			"zone": "east",
			"subcategory": "Lemon",
			"sop": "7901",
			"sos": "27176"
		}, {
			"category": "herbal tea",
			"zone": "east",
			"subcategory": "Mint",
			"sop": "(2242)",
			"sos": "11992"
		},

		{
			"category": "herbal tea",
			"zone": "south",
			"subcategory": "Chamomile",
			"sop": "3180",
			"sos": "11186"
		}, {
			"category": "herbal tea",
			"zone": "south",
			"subcategory": "Lemon",
			"sop": "2593",
			"sos": "14497"
		},

		{
			"category": "herbal tea",
			"zone": "west",
			"subcategory": "Chamomile",
			"sop": "8852",
			"sos": "25632"
		}, {
			"category": "herbal tea",
			"zone": "west",
			"subcategory": "Lemon",
			"sop": "13120",
			"sos": "32274"
		}, {
			"category": "herbal tea",
			"zone": "west",
			"subcategory": "Mint",
			"sop": "4330",
			"sos": "14380"
		},

		{
			"category": "tea",
			"zone": "central",
			"subcategory": "Darjeeling",
			"sop": "10772",
			"sos": "30289"
		}, {
			"category": "tea",
			"zone": "central",
			"subcategory": "Earl Grey",
			"sop": "10331",
			"sos": "32881"
		}, {
			"category": "tea",
			"zone": "central",
			"subcategory": "Green Tea",
			"sop": "1227",
			"sos": "5211"
		},

		{
			"category": "tea",
			"zone": "east",
			"subcategory": "Darjeeling",
			"sop": "6497",
			"sos": "14096"
		}, {
			"category": "tea",
			"zone": "east",
			"subcategory": "Earl Grey",
			"sop": "3405",
			"sos": "6505"
		}, {
			"category": "tea",
			"zone": "east",
			"subcategory": "Green Tea",
			"sop": "5654",
			"sos": "11571"
		},

		{
			"category": "tea",
			"zone": "west",
			"subcategory": "Darjeeling",
			"sop": "11780",
			"sos": "28769"
		}, {
			"category": "tea",
			"zone": "west",
			"subcategory": "Earl Grey",
			"sop": "10425",
			"sos": "27387"
		}, {
			"category": "tea",
			"zone": "west",
			"subcategory": "Green Tea",
			"sop": "(7107)",
			"sos": "16063"
		}
	]
};<commit_msg>crossChart.js added, coordinateOb needs to extended<commit_after>var mydata = {

	"chart": {
		"caption": "Comparison of Data",
		"subcaption": "Axis 1,2,3",
		"width": 300,
		"height": 300,
		"chartType": "column", //line,column,crosstab
		"ordering": "default" //default,ascending,descending
	},
	"data": [{
			"time": "21-06",
			"yAxis1": 0.5,
			"yAxis2": 54,
			"yAxis3": 366,
			"yAxis4": 8,
			"yAxis5": 110,
			"yAxis6": 69
		}, {
			"time": "22-06",
			"yAxis1": 0.6,
			"yAxis2": 33,
			"yAxis3": 282,
			"yAxis4": 5,
			"yAxis5": 103,
			"yAxis6": 50
		}, {
			"time": "23-06",
			"yAxis1": 0.9,
			"yAxis2": 44,
			"yAxis3": 354,
			"yAxis4": 2,
			"yAxis6": 85
		}, {
			"time": "24-06",
			"yAxis1": 0.3,
			"yAxis2": 55,
			"yAxis3": 380,
			"yAxis4": 1,
			"yAxis5": 112,
			"yAxis6": 45
		}, {
			"time": "25-06",
			"yAxis1": 0.1,
			"yAxis2": 72,
			"yAxis3": 421,
			"yAxis4": 6,
			"yAxis5": 121,
			"yAxis6": 75
		}, {
			"time": "26-06",
			"yAxis1": 0.2,
			"yAxis2": 76,
			"yAxis3": 698,
			"yAxis4": 3,
			"yAxis5": 115,
			"yAxis6": 36
		}, {
			"time": "27-06",
			"yAxis1": 0.3,
			"yAxis2": 25,
			"yAxis3": 969,
			"yAxis4": 9,
			"yAxis5": 103,
			"yAxis6": 98
		}, {
			"time": "28-06",
			"yAxis1": 0.8,
			"yAxis2": 65,
			"yAxis3": 533,
			"yAxis4": 2,
			"yAxis5": 125,
			"yAxis6": 46
		}, {
			"time": "29-06",
			"yAxis1": 0.1,
			"yAxis2": 45,
			"yAxis3": 545,
			"yAxis4": 4,
			"yAxis5": 113,
			"yAxis6": 80
		}, {
			"time": "30-06",
			"yAxis1": 0.3,
			"yAxis2": 85,
			"yAxis3": 754,
			"yAxis4": 6,
			"yAxis5": 124,
			"yAxis6": 85
		}, {
			"category": "coffee",
			"zone": "central",
			"subcategory": "Amaretto",
			"sop": "5105",
			"sos": "14011"
		}, {
			"category": "coffee",
			"zone": "central",
			"subcategory": "Columbian",
			"sop": "8528",
			"sos": "28913"
		}, {
			"category": "coffee",
			"zone": "central",
			"subcategory": "Decaf Irish Cream",
			"sop": "9632",
			"sos": "26155"
		},

		{
			"category": "coffee",
			"zone": "east",
			"subcategory": "Amaretto",
			"sop": "1009",
			"sos": "2993"
		}, {
			"category": "coffee",
			"zone": "east",
			"subcategory": "Columbian",
			"sop": "27253",
			"sos": "47386"
		}, {
			"category": "coffee",
			"zone": "east",
			"subcategory": "Decaf Irish Cream",
			"sop": "2727",
			"sos": "6261"
		},

		{
			"category": "coffee",
			"zone": "south",
			"subcategory": "Columbian",
			"sop": "8767",
			"sos": "21664"
		}, {
			"category": "coffee",
			"zone": "south",
			"subcategory": "Decaf Irish Cream",
			"sop": "2933",
			"sos": "11592"
		},

		{
			"category": "coffee",
			"zone": "west",
			"subcategory": "Amaretto",
			"sop": "(1225)",
			"sos": "9265"
		}, {
			"category": "coffee",
			"zone": "west",
			"subcategory": "Columbian",
			"sop": "11253",
			"sos": "30357"
		}, {
			"category": "coffee",
			"zone": "west",
			"subcategory": "Decaf Irish Cream",
			"sop": "(1305)",
			"sos": "18235"
		},

		{
			"category": "expresso",
			"zone": "central",
			"subcategory": "Caffe Mocha",
			"sop": "14640",
			"sos": "35218"
		}, {
			"category": "expresso",
			"zone": "central",
			"subcategory": "Decaf Expresso",
			"sop": "8860",
			"sos": "24485"
		},

		{
			"category": "expresso",
			"zone": "east",
			"subcategory": "Caffe Mocha",
			"sop": "(6230)",
			"sos": "16646"
		}, {
			"category": "expresso",
			"zone": "east",
			"subcategory": "Decaf Expresso",
			"sop": "2410",
			"sos": "7722"
		}, {
			"category": "expresso",
			"zone": "east",
			"subcategory": "Regular Expresso",
			"sop": "10062",
			"sos": "24036"
		},

		{
			"category": "expresso",
			"zone": "south",
			"subcategory": "Caffe Latte",
			"sop": "3872",
			"sos": "15442"
		}, {
			"category": "expresso",
			"zone": "south",
			"subcategory": "Caffe Mocha",
			"sop": "5201",
			"sos": "14163"
		}, {
			"category": "expresso",
			"zone": "south",
			"subcategory": "Decaf Expresso",
			"sop": "5930",
			"sos": "15384"
		},

		{
			"category": "expresso",
			"zone": "west",
			"subcategory": "Caffe Latte",
			"sop": "7502",
			"sos": "20458"
		}, {
			"category": "expresso",
			"zone": "west",
			"subcategory": "Caffe Mocha",
			"sop": "4064",
			"sos": "18876"
		}, {
			"category": "expresso",
			"zone": "west",
			"subcategory": "Decaf Expresso",
			"sop": "12302",
			"sos": "30578"
		},

		{
			"category": "herbal tea",
			"zone": "central",
			"subcategory": "Chamomile",
			"sop": "14436",
			"sos": "36570"
		}, {
			"category": "herbal tea",
			"zone": "central",
			"subcategory": "Lemon",
			"sop": "6251",
			"sos": "21978"
		}, {
			"category": "herbal tea",
			"zone": "central",
			"subcategory": "Mint",
			"sop": "4069",
			"sos": "9337"
		},

		{
			"category": "herbal tea",
			"zone": "east",
			"subcategory": "Chamomile",
			"sop": "765",
			"sos": "2194"
		}, {
			"category": "herbal tea",
			"zone": "east",
			"subcategory": "Lemon",
			"sop": "7901",
			"sos": "27176"
		}, {
			"category": "herbal tea",
			"zone": "east",
			"subcategory": "Mint",
			"sop": "(2242)",
			"sos": "11992"
		},

		{
			"category": "herbal tea",
			"zone": "south",
			"subcategory": "Chamomile",
			"sop": "3180",
			"sos": "11186"
		}, {
			"category": "herbal tea",
			"zone": "south",
			"subcategory": "Lemon",
			"sop": "2593",
			"sos": "14497"
		},

		{
			"category": "herbal tea",
			"zone": "west",
			"subcategory": "Chamomile",
			"sop": "8852",
			"sos": "25632"
		}, {
			"category": "herbal tea",
			"zone": "west",
			"subcategory": "Lemon",
			"sop": "13120",
			"sos": "32274"
		}, {
			"category": "herbal tea",
			"zone": "west",
			"subcategory": "Mint",
			"sop": "4330",
			"sos": "14380"
		},

		{
			"category": "tea",
			"zone": "central",
			"subcategory": "Darjeeling",
			"sop": "10772",
			"sos": "30289"
		}, {
			"category": "tea",
			"zone": "central",
			"subcategory": "Earl Grey",
			"sop": "10331",
			"sos": "32881"
		}, {
			"category": "tea",
			"zone": "central",
			"subcategory": "Green Tea",
			"sop": "1227",
			"sos": "5211"
		},

		{
			"category": "tea",
			"zone": "east",
			"subcategory": "Darjeeling",
			"sop": "6497",
			"sos": "14096"
		}, {
			"category": "tea",
			"zone": "east",
			"subcategory": "Earl Grey",
			"sop": "3405",
			"sos": "6505"
		}, {
			"category": "tea",
			"zone": "east",
			"subcategory": "Green Tea",
			"sop": "5654",
			"sos": "11571"
		},

		{
			"category": "tea",
			"zone": "west",
			"subcategory": "Darjeeling",
			"sop": "11780",
			"sos": "28769"
		}, {
			"category": "tea",
			"zone": "west",
			"subcategory": "Earl Grey",
			"sop": "10425",
			"sos": "27387"
		}, {
			"category": "tea",
			"zone": "west",
			"subcategory": "Green Tea",
			"sop": "(7107)",
			"sos": "16063"
		}
	]
};<|endoftext|>


<commit_before><commit_msg>Update iframe resizeing function.<commit_after><|endoftext|>


<commit_before>module("event");

test("bind()", function() {
	expect(12);

	var handler = function(event) {
		ok( event.data, "bind() with data, check passed data exists" );
		ok( event.data.foo == "bar", "bind() with data, Check value of passed data" );
	};
	$("#firstp").bind("click", {foo: "bar"}, handler).click().unbind("click", handler);

	ok( !$("#firstp").get(0).$events, "Event handler unbound when using data." );

	reset();
	var handler = function(event, data) {
		ok( event.data, "check passed data exists" );
		ok( event.data.foo == "bar", "Check value of passed data" );
		ok( data, "Check trigger data" );
		ok( data.bar == "foo", "Check value of trigger data" );
	};
	$("#firstp").bind("click", {foo: "bar"}, handler).trigger("click", [{bar: "foo"}]).unbind(handler);

	reset();
	var handler = function(event) {
		ok ( !event.data, "Check that no data is added to the event object" );
	};
	$("#firstp").bind("click", handler).trigger("click");

	// events don't work with iframes, see #939
	var doc = document.getElementById("iframe").contentDocument;

	doc.body.innerHTML = "<input type='text'/>";

	var input = doc.getElementsByTagName("input")[0];

	$(input).bind("click",function() {
		ok( true, "Binding to element inside iframe" );
	}).click();

	//triggerEvent( input, "click" );

	var counter = 0;
	function selectOnChange(event) {
		equals( event.data, counter++, "Event.data is not a global event object" );
	};
	$("select").each(function(i){
		$(this).bind('change', i, selectOnChange);
	}).trigger('change');
});

test("click()", function() {
	expect(3);
	$('
Change location
').prependTo('#firstUL').find('a').bind('click', function() {
	    var close = $('spanx', this); // same with $(this).find('span');
	    ok( close.length == 0, "Context element does not exist, length must be zero" );
	    ok( !close[0], "Context element does not exist, direct access to element must return undefined" );
	    return false;
	}).click();

	$("#check1").click(function() {
		ok( true, "click event handler for checkbox gets fired twice, see #815" );
	}).click();
});

test("unbind(event)", function() {
	expect(6);
	var el = $("#firstp");
	el.click(function() {
		ok( true, "Fake normal bind" );
	});
	el.click(function(event) {
		el.unbind(event);
		ok( true, "Fake onebind" );
	});
	el.click().click();

	el.click(function() { return; });
	el.unbind('click');
	ok( !el[0].onclick, "Handler is removed" ); // Bug #964

	el.click(function() { return; });
	el.unbind('change',function(){ return; });
	for (var ret in el[0].$events['click']) break;
	ok( ret, "Extra handlers weren't accidentally removed." );

	el.unbind('click');
	ok( !el[0].$events, "Removed the events expando after all handlers are unbound." );
});

test("trigger(event, [data]", function() {
	expect(3);
	var handler = function(event, a, b, c) {
		ok( a == 1, "check passed data" );
		ok( b == "2", "check passed data" );
		ok( c == "abc", "check passed data" );
	};
	$("#firstp").bind("click", handler).trigger("click", [1, "2", "abc"]);
});

test("toggle(Function, Function)", function() {
	expect(4);
	var count = 0,
		fn1 = function(e) { count++; },
		fn2 = function(e) { count--; },
		preventDefault = function(e) { e.preventDefault() },
		link = $('#mark');
	link.click(preventDefault).click().toggle(fn1, fn2).click().click().click().click().click();
	ok( count == 1, "Check for toggle(fn, fn)" );

	var first = 0;
	$("#simon1").one("click", function() {
		ok( true, "Execute event only once" );
		$(this).toggle(function() {
			ok( first++ == 0, "toggle(Function,Function) assigned from within one('xxx'), see #1054" );
		}, function() {
			ok( first == 1, "toggle(Function,Function) assigned from within one('xxx'), see #1054" );
		});
		return false;
	}).click().click().click();
});<commit_msg>broken test in IE<commit_after>module("event");

test("bind()", function() {
	expect(11);

	var handler = function(event) {
		ok( event.data, "bind() with data, check passed data exists" );
		ok( event.data.foo == "bar", "bind() with data, Check value of passed data" );
	};
	$("#firstp").bind("click", {foo: "bar"}, handler).click().unbind("click", handler);

	ok( !$("#firstp").get(0).$events, "Event handler unbound when using data." );

	reset();
	var handler = function(event, data) {
		ok( event.data, "check passed data exists" );
		ok( event.data.foo == "bar", "Check value of passed data" );
		ok( data, "Check trigger data" );
		ok( data.bar == "foo", "Check value of trigger data" );
	};
	$("#firstp").bind("click", {foo: "bar"}, handler).trigger("click", [{bar: "foo"}]).unbind(handler);

	reset();
	var handler = function(event) {
		ok ( !event.data, "Check that no data is added to the event object" );
	};
	$("#firstp").bind("click", handler).trigger("click");

	// events don't work with iframes, see #939 - this test fails in IE because of contentDocument
	// var doc = document.getElementById("iframe").contentDocument;
	//
	// doc.body.innerHTML = "<input type='text'/>";
	//
	// var input = doc.getElementsByTagName("input")[0];
	//
	// $(input).bind("click",function() {
	// 	ok( true, "Binding to element inside iframe" );
	// }).click();

	var counter = 0;
	function selectOnChange(event) {
		equals( event.data, counter++, "Event.data is not a global event object" );
	};
	$("select").each(function(i){
		$(this).bind('change', i, selectOnChange);
	}).trigger('change');
});

test("click()", function() {
	expect(3);
	$('
Change location
').prependTo('#firstUL').find('a').bind('click', function() {
	    var close = $('spanx', this); // same with $(this).find('span');
	    ok( close.length == 0, "Context element does not exist, length must be zero" );
	    ok( !close[0], "Context element does not exist, direct access to element must return undefined" );
	    return false;
	}).click();

	$("#check1").click(function() {
		ok( true, "click event handler for checkbox gets fired twice, see #815" );
	}).click();
});

test("unbind(event)", function() {
	expect(6);
	var el = $("#firstp");
	el.click(function() {
		ok( true, "Fake normal bind" );
	});
	el.click(function(event) {
		el.unbind(event);
		ok( true, "Fake onebind" );
	});
	el.click().click();

	el.click(function() { return; });
	el.unbind('click');
	ok( !el[0].onclick, "Handler is removed" ); // Bug #964

	el.click(function() { return; });
	el.unbind('change',function(){ return; });
	for (var ret in el[0].$events['click']) break;
	ok( ret, "Extra handlers weren't accidentally removed." );

	el.unbind('click');
	ok( !el[0].$events, "Removed the events expando after all handlers are unbound." );
});

test("trigger(event, [data]", function() {
	expect(3);
	var handler = function(event, a, b, c) {
		ok( a == 1, "check passed data" );
		ok( b == "2", "check passed data" );
		ok( c == "abc", "check passed data" );
	};
	$("#firstp").bind("click", handler).trigger("click", [1, "2", "abc"]);
});

test("toggle(Function, Function)", function() {
	expect(4);
	var count = 0,
		fn1 = function(e) { count++; },
		fn2 = function(e) { count--; },
		preventDefault = function(e) { e.preventDefault() },
		link = $('#mark');
	link.click(preventDefault).click().toggle(fn1, fn2).click().click().click().click().click();
	ok( count == 1, "Check for toggle(fn, fn)" );

	var first = 0;
	$("#simon1").one("click", function() {
		ok( true, "Execute event only once" );
		$(this).toggle(function() {
			ok( first++ == 0, "toggle(Function,Function) assigned from within one('xxx'), see #1054" );
		}, function() {
			ok( first == 1, "toggle(Function,Function) assigned from within one('xxx'), see #1054" );
		});
		return false;
	}).click().click().click();
});<|endoftext|>


<commit_before>
/*Object.prototype.keys = function () {
  var keys = [];
  for(i in this) if (this.hasOwnProperty(i))
  {
    keys.push(i);
  }
  return keys;
  }*/

function daysInMonth(year, month) {
  return 32 - new Date(year, month-1, 32).getDate();
}

function daysForMonth(year, month) {
  var N = daysInMonth(year, month);
  var days = [];
  for (var d = 0; d < N; ++d) {
    days[d] = new Date(year, month-1, d + 1);
  }
  return days;
}

function createDateStruct(year, month, day) {
  var date = {};
  date.year = year;
  date.month = month;
  date.day = day;
  return date;
}

function templatePlaceholder(date) {
  return '' + date.year + '_' + date.month + '_' + date.day;
}

function dateFromJsDate(jsdate) {

  var year = jsdate.getFullYear();
  var month = jsdate.getMonth() + 1;
  var day = jsdate.getDate();
  return createDateStruct(year, month, day);
}

function createMonthTemplate(year, month) {

  var days = daysForMonth(year, month);
  var preSync = true;
  var postSync = false;
  var dayOffset = 0;
  var numberOfDaysLeft = days.length;

  var template = "";
  template += '
';
  template += '
Mon	Tue	Wed	Thu	Fri	Sat	Sun
';
  for (var week = 0; (week < 6) && (numberOfDaysLeft > 0); ++week) {

    template += '
';
    for (var dayOfWeek = 0; dayOfWeek < 7; ++dayOfWeek) {

      var i = week*7 + dayOfWeek;
      if (preSync) {
   	if (((days[0].getDay() + 6) % 7)  == i) {
   	  preSync = false;
   	  dayOffset = i;
   	}
      } else {
   	if ((i - dayOffset) >= days.length) {
   	  postSync = true;
   	}
      }

      if (preSync) {
   	template += '	';
      } else if (postSync) {
   	template += '	';
      } else {
	var jsdate = days[i - dayOffset];
	var dateStruct = dateFromJsDate(jsdate);
   	template += '{{{' + templatePlaceholder(dateStruct) + '}}}	';
      }
    }
    template += "
";
  }
  template += "
";
  return template;
}

function transformState(state) {

  var reverseLookup = {};
  var messageLookup = {};
  var keys = state.getKeys();

  for (var i = 0; i < keys.length; ++i) {
    var participantId = keys[i];

    for (var k = 0; k < state.get(participantId).length; ++k) {

      var participantInfo = JSON.parse(state.get(participantId)[k]);

      var date = { year  : participantInfo.year,
		   month : participantInfo.month,
		   day   : participantInfo.day };
      var dateJSON = JSON.stringify(date);

      if (reverseLookup[dateJSON] == undefined) {
	reverseLookup[dateJSON] = [];
      }
      reverseLookup[dateJSON].push(participantId);

      var message = participantInfo.message;
      if (message != undefined) {
	if (messageLookup[dateJSON] == undefined) {
	  messageLookup[dateJSON] = {};
	}
	messageLookup[dateJSON][participantId] = message;
      }
    }
  }

  var transformed = { datesToAttendees : reverseLookup,
		      datesToMessages : messageLookup };
  return transformed;

}

function addDayLink(view, year, month) {

  var days = daysForMonth(year, month);
  for (var i = 0; i < days.length; ++i) {
    var jsdate = days[i];
    var date = dateFromJsDate(jsdate);

    var onclick = 'dayClicked(' + date.year + ',' + date.month + ',' + date.day + ')';
    var html = '
' + date.day +'
';

    view[templatePlaceholder(date)] = html;
  }

}

function viewFromState(yearsAndMonths, viewerId, wave) {

  var transformed = transformState(wave.getState());
  var view = {};

  // The initial view is only the day of the month
  for (var i = 0; i < yearsAndMonths.length; ++i) {
    year = yearsAndMonths[i][0];
    month = yearsAndMonths[i][1];
    addDayLink(view, year, month);
  }

  var dates = transformed.datesToAttendees.keys();
  for (var i = 0; i < dates.length; ++i) {
    var attendeesKey = dates[i];
    var participantIds =  transformed.datesToAttendees[attendeesKey];

    var viewKey = templatePlaceholder(JSON.parse(attendeesKey));
    var html = view[viewKey];
    html += '
';
    for (var k = 0; k < participantIds.length; ++k) {

      var participantId = participantIds[k];
      var participant = wave.getParticipantById(participantId)
      var thumbnailURL = participant.getThumbnailUrl();
      html += '';
    }
    html += '
';

    view[viewKey] = html;
  }
  return view;
}

function containsDate(array, date) {
  for (var i = 0; i < array.length; i++) {
    if (dateStructsEqual(array[i], date)) {
      return true;
    }
  }
  return false;
}

function removeDate(array, date) {
  var newArray = [];
  for (var i = 0; i < array.length; i++) {
    if (!dateStructsEqual(array[i], date)) {
      newArray.push(array[i]);
    }
  }
  return newArray;
}

function dayClicked(year, month, day) {

  var clickedDate = createDateStruct(year, month, day);

  var viewerId = wave.getViewer().getId();
  var daysJSON = wave.getState().get(viewerId, '[]');
  var attendingDays = JSON.parse(daysJSON);

  if (containsDate(attendingDays, clickedDate)) {
    attendingDays = removeDate(attendingDays, clickedDate);
  } else {
    attendingDays.push(clickedDate);
  }

  var delta = {};
  delta[viewerId] = JSON.stringify(attendingDays);
  wave.getState().submitDelta(delta);
}

<commit_msg>testing<commit_after>
function getKeys(hash) {
  var keys = [];
  for(i in hash) if (hash.hasOwnProperty(i)) {
      keys.push(i);
    }
  return keys;
}

function daysInMonth(year, month) {
  return 32 - new Date(year, month-1, 32).getDate();
}

function daysForMonth(year, month) {
  var N = daysInMonth(year, month);
  var days = [];
  for (var d = 0; d < N; ++d) {
    days[d] = new Date(year, month-1, d + 1);
  }
  return days;
}

function createDateStruct(year, month, day) {
  var date = {};
  date.year = year;
  date.month = month;
  date.day = day;
  return date;
}

function templatePlaceholder(date) {
  return '' + date.year + '_' + date.month + '_' + date.day;
}

function dateFromJsDate(jsdate) {

  var year = jsdate.getFullYear();
  var month = jsdate.getMonth() + 1;
  var day = jsdate.getDate();
  return createDateStruct(year, month, day);
}

function createMonthTemplate(year, month) {

  var days = daysForMonth(year, month);
  var preSync = true;
  var postSync = false;
  var dayOffset = 0;
  var numberOfDaysLeft = days.length;

  var template = "";
  template += '
';
  template += '
Mon	Tue	Wed	Thu	Fri	Sat	Sun
';
  for (var week = 0; (week < 6) && (numberOfDaysLeft > 0); ++week) {

    template += '
';
    for (var dayOfWeek = 0; dayOfWeek < 7; ++dayOfWeek) {

      var i = week*7 + dayOfWeek;
      if (preSync) {
   	if (((days[0].getDay() + 6) % 7)  == i) {
   	  preSync = false;
   	  dayOffset = i;
   	}
      } else {
   	if ((i - dayOffset) >= days.length) {
   	  postSync = true;
   	}
      }

      if (preSync) {
   	template += '	';
      } else if (postSync) {
   	template += '	';
      } else {
	var jsdate = days[i - dayOffset];
	var dateStruct = dateFromJsDate(jsdate);
   	template += '{{{' + templatePlaceholder(dateStruct) + '}}}	';
      }
    }
    template += "
";
  }
  template += "
";
  return template;
}

function transformState(state) {

  var reverseLookup = {};
  var messageLookup = {};
  var keys = state.getKeys();

  for (var i = 0; i < keys.length; ++i) {
    var participantId = keys[i];

    for (var k = 0; k < state.get(participantId).length; ++k) {

      var participantInfo = JSON.parse(state.get(participantId)[k]);

      var date = { year  : participantInfo.year,
		   month : participantInfo.month,
		   day   : participantInfo.day };
      var dateJSON = JSON.stringify(date);

      if (reverseLookup[dateJSON] == undefined) {
	reverseLookup[dateJSON] = [];
      }
      reverseLookup[dateJSON].push(participantId);

      var message = participantInfo.message;
      if (message != undefined) {
	if (messageLookup[dateJSON] == undefined) {
	  messageLookup[dateJSON] = {};
	}
	messageLookup[dateJSON][participantId] = message;
      }
    }
  }

  var transformed = { datesToAttendees : reverseLookup,
		      datesToMessages : messageLookup };
  return transformed;

}

function addDayLink(view, year, month) {

  var days = daysForMonth(year, month);
  for (var i = 0; i < days.length; ++i) {
    var jsdate = days[i];
    var date = dateFromJsDate(jsdate);

    var onclick = 'dayClicked(' + date.year + ',' + date.month + ',' + date.day + ')';
    var html = '
' + date.day +'
';

    view[templatePlaceholder(date)] = html;
  }

}

function viewFromState(yearsAndMonths, viewerId, wave) {

  var transformed = transformState(wave.getState());
  var view = {};

  // The initial view is only the day of the month
  for (var i = 0; i < yearsAndMonths.length; ++i) {
    year = yearsAndMonths[i][0];
    month = yearsAndMonths[i][1];
    addDayLink(view, year, month);
  }

  var dates = getKeys(transformed.datesToAttendees);
  for (var i = 0; i < dates.length; ++i) {
    var attendeesKey = dates[i];
    var participantIds =  transformed.datesToAttendees[attendeesKey];

    var viewKey = templatePlaceholder(JSON.parse(attendeesKey));
    var html = view[viewKey];
    html += '
';
    for (var k = 0; k < participantIds.length; ++k) {

      var participantId = participantIds[k];
      var participant = wave.getParticipantById(participantId)
      var thumbnailURL = participant.getThumbnailUrl();
      html += '';
    }
    html += '
';

    view[viewKey] = html;
  }
  return view;
}

function containsDate(array, date) {
  for (var i = 0; i < array.length; i++) {
    if (dateStructsEqual(array[i], date)) {
      return true;
    }
  }
  return false;
}

function removeDate(array, date) {
  var newArray = [];
  for (var i = 0; i < array.length; i++) {
    if (!dateStructsEqual(array[i], date)) {
      newArray.push(array[i]);
    }
  }
  return newArray;
}

function dayClicked(year, month, day) {

  var clickedDate = createDateStruct(year, month, day);

  var viewerId = wave.getViewer().getId();
  var daysJSON = wave.getState().get(viewerId, '[]');
  var attendingDays = JSON.parse(daysJSON);

  if (containsDate(attendingDays, clickedDate)) {
    attendingDays = removeDate(attendingDays, clickedDate);
  } else {
    attendingDays.push(clickedDate);
  }

  var delta = {};
  delta[viewerId] = JSON.stringify(attendingDays);
  wave.getState().submitDelta(delta);
}

<|endoftext|>