<commit_before>exports.BattleMovedex = {
        "triattack": {
                num: 161,
                accuracy: 100,
                basePower: 80,
                category: "Special",
                desc: "Deals damage to one adjacent target with a 20% chance to either burn, freeze, or paralyze it.",
                shortDesc: "20% chance to paralyze or burn or freeze target.",
                id: "triattack",
                isViable: true,
                name: "Tri Attack",
                pp: 10,
                priority: 0,
                multihit: [3,3],
                secondary: {
                        chance: 20,
                        onHit: function(target, source) {
                                var result = this.random(3);
                                if (result===0) {
                                        target.trySetStatus('brn', source);
                                } else if (result===1) {
                                        target.trySetStatus('par', source);
                                } else {
                                        target.trySetStatus('frz', source);
                                }
                        }
                },
                target: "normal",
                type: "Normal"
        },
        "crosschop": {
                num: 238,
                accuracy: 95,
                basePower: 100,
                category: "Physical",
                desc: "Deals damage to one adjacent target with a higher chance for a critical hit. Makes contact.",
                shortDesc: "High critical hit ratio.",
                id: "crosschop",
                isViable: true,
                name: "Cross Chop",
                pp: 10,
                priority: 0,
                isContact: true,
                secondary: {
                        chance: 15,
                        volatileStatus: 'flinch'
                },
                target: "normal",
                type: "Fighting"
        },
        "stoneedge": {
                num: 444,
                accuracy: 95,
                basePower: 100,
                category: "Physical",
                desc: "Deals damage to one adjacent target with a higher chance for a critical hit. Makes contact.",
                shortDesc: "High critical hit ratio.",
                id: "stoneedge",
                isViable: true,
                name: "Stone Edge",
                pp: 10,
                priority: 0,
                isContact: true,
                secondary: {
                        chance: 15,
                        volatileStatus: 'flinch'
                },
                target: "normal",
                type: "Rock"
        },
        "moonblast": {
                num: -6,
                gen: 6,
                accuracy: 100,
                basePower: 100,
                category: "Special",
                desc: "Deals damage to one adjacent target with a 30% chance to lower its Special Attack by 1 stage.",
                shortDesc: "30% chance to lower the target's Sp. Atk by 1.",
                id: "moonblast",
                isViable: true,
                name: "Moonblast",
                pp: 15,
                priority: 0,
                secondary: {
                        chance: 30,
                        boosts: {
                                spa: -1
                        }
                },
                target: "normal",
                type: "Fairy"
        },
        "dazzlinggleam": {
                num: -6,
                gen: 6,
                accuracy: 100,
                basePower: 90,
                category: "Special",
                desc: "Deals damage to all adjacent foes.",
                shortDesc: "No additional effect. Hits adjacent foes.",
                id: "dazzlinggleam",
                isViable: true,
                name: "Dazzling Gleam",
                pp: 10,
                priority: 0,
                secondary: false,
                target: "allAdjacentFoes",
                type: "Fairy"
        },
        "hurricane": {
                num: 542,
                accuracy: 85,
                basePower: 110,
                category: "Special",
                desc: "Deals damage to one adjacent or non-adjacent target with a 30% chance to confuse it. This move can hit a target using Bounce, Fly, or Sky Drop. If the weather is Rain Dance, this move cannot miss. If the weather is Sunny Day, this move's accuracy is 50%.",
                shortDesc: "30% chance to confuse target. Can't miss in rain.",
                id: "hurricane",
                isViable: true,
                name: "Hurricane",
                pp: 10,
                priority: 0,
                onModifyMove: function(move) {
                        if (this.isWeather('raindance')) move.accuracy = true;
                        else if (this.isWeather('sunnyday')) move.accuracy = 50;
                },
                secondary: {
                        chance: 20,
                        volatileStatus: 'confusion'
                },
                target: "any",
                type: "Flying"
        },
        "focusblast": {
                num: 411,
                accuracy: 85,
                basePower: 110,
                category: "Special",
                desc: "Deals damage to one adjacent target with a 10% chance to lower its Special Defense by 1 stage.",
                shortDesc: "20% chance to lower the target's Sp. Def by 1.",
                id: "focusblast",
                isViable: true,
                name: "Focus Blast",
                pp: 5,
                priority: 0,
                isBullet: true,
                secondary: {
                        chance: 20,
                        boosts: {
                                spd: -1
                        }
                },
                target: "normal",
                type: "Fighting"
        },
        "gigadrain": {
                num: 202,
                accuracy: 100,
                basePower: 80,
                category: "Special",
                desc: "Deals damage to one adjacent target. The user recovers half of the HP lost by the target, rounded up. If Big Root is held by the user, the HP recovered is 1.3x normal, rounded half down.",
                shortDesc: "User recovers 50% of the damage dealt.",
                id: "gigadrain",
                isViable: true,
                name: "Giga Drain",
                pp: 10,
                priority: 0,
                drain: [1,2],
                secondary: false,
                target: "normal",
                type: "Grass"
        },
        "paraboliccharge": {
                num: -6,
                gen: 6,
                accuracy: 100,
                basePower: 80,
                category: "Special",
                desc: "Deals damage to all adjacent targets. The user recovers half of the HP lost by the target, rounded up.",
                shortDesc: "User recovers 50% of the damage dealt.",
                id: "paraboliccharge",
                name: "Parabolic Charge",
                pp: 20,
                priority: 0,
                isViable: true,
                drain: [1,2],
                secondary: false,
                target: "allAdjacent",
                type: "Electric"
        },
        "lightbringer": {
                num: -534,
                gen: 6,
                accuracy: 100,
                basePower: 150,
                category: "Special",
                desc: "Deals damage to one adjacent target with a 30% chance to lower its Special Attack by 1 stage.",
                shortDesc: "30% chance to lower the target's Sp. Atk by 1.",
                id: "lgihtbringer",
                isViable: true,
                name: "Light Bringer",
                pp: 5,
                priority: 0,
                recoil: [33,100],
                secondary: false,
                target: "normal",
                type: "Fairy"
        },
        "phantomforce": {
		num: -6,
		gen: 6,
		accuracy: 100,
		basePower: 100,
		category: "Physical",
		desc: "Deals damage to one adjacent target and breaks through Protect and Detect for this turn, allowing other Pokemon to attack the target normally. This attack charges on the first turn and strikes on the second. On the first turn, the user avoids all attacks. The user cannot make a move between turns. If the user is holding a Power Herb, the move completes in one turn. Makes contact.",
		shortDesc: "Disappears turn 1. Hits turn 2. Breaks protection.",
		id: "phantomforce",
		name: "Phantom Force",
		pp: 10,
		priority: 0,
		isContact: true,
		secondary: false,
		target: "normal",
		type: "Ghost"
	},
        "roaroftime": {
                num: 459,
                accuracy: 100,
                basePower: 150,
                category: "Special",
                desc: "Deals damage to one adjacent target. If this move is successful, the user must recharge on the following turn and cannot make a move.",
                shortDesc: "User cannot move next turn.",
                id: "roaroftime",
                name: "Roar of Time",
                pp: 5,
                priority: 0,
                recoil: [33,100],
                secondary: false,
                target: "normal",
                type: "Dragon"
        }
};
<commit_msg>Update moves.js<commit_after>exports.BattleMovedex = {
        "triattack": {
                num: 161,
                accuracy: 100,
                basePower: 80,
                category: "Special",
                desc: "Deals damage to one adjacent target with a 20% chance to either burn, freeze, or paralyze it.",
                shortDesc: "20% chance to paralyze or burn or freeze target.",
                id: "triattack",
                isViable: true,
                name: "Tri Attack",
                pp: 10,
                priority: 0,
                multihit: [3,3],
                secondary: {
                        chance: 20,
                        onHit: function(target, source) {
                                var result = this.random(3);
                                if (result===0) {
                                        target.trySetStatus('brn', source);
                                } else if (result===1) {
                                        target.trySetStatus('par', source);
                                } else {
                                        target.trySetStatus('frz', source);
                                }
                        }
                },
                target: "normal",
                type: "Normal"
        },
        "crosschop": {
                num: 238,
                accuracy: 95,
                basePower: 100,
                category: "Physical",
                desc: "Deals damage to one adjacent target with a higher chance for a critical hit. Makes contact.",
                shortDesc: "High critical hit ratio.",
                id: "crosschop",
                isViable: true,
                name: "Cross Chop",
                pp: 10,
                priority: 0,
                isContact: true,
                secondary: {
                        chance: 15,
                        volatileStatus: 'flinch'
                },
                target: "normal",
                type: "Fighting"
        },
        "naturepower": {
                num: 267,
                accuracy: true,
                basePower: 0,
                category: "Status",
                desc: "This move calls another move for use depending on the battle terrain: Thunderbolt in Electric Terrain, Energy Ball in Grassy Terrain, Moonblast in Misty Terrain, and Tri Attack in plain terrain.",
                shortDesc: "Attack depends on terrain (default Tri Attack).",
                id: "naturepower",
                isViable: true,
                name: "Nature Power",
                pp: 20,
                priority: 0,
                onHit: function(target) {
                        var moveToUse = 'earthquake';
                        if (this.isTerrain('electricterrain')) moveToUse = 'thunderbolt';
                        else if (this.isTerrain('grassyterrain')) moveToUse = 'energyball';
                        else if (this.isTerrain('mistyterrain')) moveToUse = 'moonblast';

                        this.useMove(moveToUse, target);
                },
                secondary: false,
                target: "self",
                type: "Normal"
        },
        "stoneedge": {
                num: 444,
                accuracy: 95,
                basePower: 100,
                category: "Physical",
                desc: "Deals damage to one adjacent target with a higher chance for a critical hit. Makes contact.",
                shortDesc: "High critical hit ratio.",
                id: "stoneedge",
                isViable: true,
                name: "Stone Edge",
                pp: 10,
                priority: 0,
                isContact: true,
                secondary: {
                        chance: 15,
                        volatileStatus: 'flinch'
                },
                target: "normal",
                type: "Rock"
        },
        "moonblast": {
                num: -6,
                gen: 6,
                accuracy: 100,
                basePower: 100,
                category: "Special",
                desc: "Deals damage to one adjacent target with a 30% chance to lower its Special Attack by 1 stage.",
                shortDesc: "30% chance to lower the target's Sp. Atk by 1.",
                id: "moonblast",
                isViable: true,
                name: "Moonblast",
                pp: 15,
                priority: 0,
                secondary: {
                        chance: 30,
                        boosts: {
                                spa: -1
                        }
                },
                target: "normal",
                type: "Fairy"
        },
        "dazzlinggleam": {
                num: -6,
                gen: 6,
                accuracy: 100,
                basePower: 90,
                category: "Special",
                desc: "Deals damage to all adjacent foes.",
                shortDesc: "No additional effect. Hits adjacent foes.",
                id: "dazzlinggleam",
                isViable: true,
                name: "Dazzling Gleam",
                pp: 10,
                priority: 0,
                secondary: false,
                target: "allAdjacentFoes",
                type: "Fairy"
        },
        "hurricane": {
                num: 542,
                accuracy: 85,
                basePower: 110,
                category: "Special",
                desc: "Deals damage to one adjacent or non-adjacent target with a 30% chance to confuse it. This move can hit a target using Bounce, Fly, or Sky Drop. If the weather is Rain Dance, this move cannot miss. If the weather is Sunny Day, this move's accuracy is 50%.",
                shortDesc: "30% chance to confuse target. Can't miss in rain.",
                id: "hurricane",
                isViable: true,
                name: "Hurricane",
                pp: 10,
                priority: 0,
                onModifyMove: function(move) {
                        if (this.isWeather('raindance')) move.accuracy = true;
                        else if (this.isWeather('sunnyday')) move.accuracy = 50;
                },
                secondary: {
                        chance: 20,
                        volatileStatus: 'confusion'
                },
                target: "any",
                type: "Flying"
        },
        "focusblast": {
                num: 411,
                accuracy: 85,
                basePower: 110,
                category: "Special",
                desc: "Deals damage to one adjacent target with a 10% chance to lower its Special Defense by 1 stage.",
                shortDesc: "20% chance to lower the target's Sp. Def by 1.",
                id: "focusblast",
                isViable: true,
                name: "Focus Blast",
                pp: 5,
                priority: 0,
                isBullet: true,
                secondary: {
                        chance: 20,
                        boosts: {
                                spd: -1
                        }
                },
                target: "normal",
                type: "Fighting"
        },
        "gigadrain": {
                num: 202,
                accuracy: 100,
                basePower: 80,
                category: "Special",
                desc: "Deals damage to one adjacent target. The user recovers half of the HP lost by the target, rounded up. If Big Root is held by the user, the HP recovered is 1.3x normal, rounded half down.",
                shortDesc: "User recovers 50% of the damage dealt.",
                id: "gigadrain",
                isViable: true,
                name: "Giga Drain",
                pp: 10,
                priority: 0,
                drain: [1,2],
                secondary: false,
                target: "normal",
                type: "Grass"
        },
        "paraboliccharge": {
                num: -6,
                gen: 6,
                accuracy: 100,
                basePower: 80,
                category: "Special",
                desc: "Deals damage to all adjacent targets. The user recovers half of the HP lost by the target, rounded up.",
                shortDesc: "User recovers 50% of the damage dealt.",
                id: "paraboliccharge",
                name: "Parabolic Charge",
                pp: 20,
                priority: 0,
                isViable: true,
                drain: [1,2],
                secondary: false,
                target: "allAdjacent",
                type: "Electric"
        },
        "lightbringer": {
                num: -534,
                gen: 6,
                accuracy: 100,
                basePower: 150,
                category: "Special",
                desc: "Deals damage to one adjacent target with a 30% chance to lower its Special Attack by 1 stage.",
                shortDesc: "30% chance to lower the target's Sp. Atk by 1.",
                id: "lgihtbringer",
                isViable: true,
                name: "Light Bringer",
                pp: 5,
                priority: 0,
                recoil: [33,100],
                secondary: false,
                target: "normal",
                type: "Fairy"
        },
        "phantomforce": {
		num: -6,
		gen: 6,
		accuracy: 100,
		basePower: 100,
		category: "Physical",
		desc: "Deals damage to one adjacent target and breaks through Protect and Detect for this turn, allowing other Pokemon to attack the target normally. This attack charges on the first turn and strikes on the second. On the first turn, the user avoids all attacks. The user cannot make a move between turns. If the user is holding a Power Herb, the move completes in one turn. Makes contact.",
		shortDesc: "Disappears turn 1. Hits turn 2. Breaks protection.",
		id: "phantomforce",
		name: "Phantom Force",
		pp: 10,
		priority: 0,
		isContact: true,
		secondary: false,
		target: "normal",
		type: "Ghost"
	},
        "roaroftime": {
                num: 459,
                accuracy: 100,
                basePower: 150,
                category: "Special",
                desc: "Deals damage to one adjacent target. If this move is successful, the user must recharge on the following turn and cannot make a move.",
                shortDesc: "User cannot move next turn.",
                id: "roaroftime",
                name: "Roar of Time",
                pp: 5,
                priority: 0,
                recoil: [33,100],
                secondary: false,
                target: "normal",
                type: "Dragon"
        }
};
<|endoftext|>


<commit_before>'use strict';
var path = require('path');
var chalk = require('chalk');
var eslint = require('eslint').cli;

module.exports = function (grunt) {
	grunt.registerMultiTask('eslint', 'Validate files with ESLint', function () {
		var options = this.options();

		if (this.filesSrc.length === 0) {
			grunt.log.writeln(chalk.magenta('Couldn\'t find any files to validate.'));
			return;
		}

		options._ = this.filesSrc; // set positional arguments
		options.config = options.config ? path.resolve(options.config) : '';

		return eslint.execute(options) === 0;
	});
};
<commit_msg>catch errors and grunt.warn them<commit_after>'use strict';
var path = require('path');
var chalk = require('chalk');
var eslint = require('eslint').cli;

module.exports = function (grunt) {
	grunt.registerMultiTask('eslint', 'Validate files with ESLint', function () {
		var options = this.options();

		if (this.filesSrc.length === 0) {
			grunt.log.writeln(chalk.magenta('Couldn\'t find any files to validate.'));
			return;
		}

		options._ = this.filesSrc; // set positional arguments
		options.config = options.config ? path.resolve(options.config) : '';

		try {
			return eslint.execute(options) === 0;
		} catch (err) {
			grunt.warn(err);
		}
	});
};
<|endoftext|>


<commit_before>/*
 * grunt-sapui5
 * https://github.com/pplenkov/grunt-sapui5
 *
 * Copyright (c) 2017 theplenkov
 * Licensed under the MIT license.
 */

'use strict';

module.exports = function (grunt) {
  'use strict';

  //load SAP task
  grunt.loadNpmTasks('@sap/grunt-sapui5-bestpractice-build');

  // merging function
  var mergeWith = require('lodash.mergewith');
  var customizer = function (objValue, srcValue) {
    if (Array.isArray(objValue)) {
      return [srcValue].concat(objValue);
    }
  };

  // read config
  var oConfig = grunt.config();

  try {
    // read manifest.json
    var oManifest = grunt.file.readJSON(oConfig.dir.webapp + "/manifest.json");

    // take sap.app version
    var oApp = oManifest["sap.app"];
    if (oApp) {
      switch (oApp.type) {
        // for libraries we should create library.json
        case "library":

          // a.b.c -> a/b/c
          var sRoot = oConfig.dir.root.split(".").join("/");

          mergeWith(oConfig,
            {

              openui5_preload: {
                preloadTmp: {
                  options: {
                    compatVersion: "1.38",
                    resources: {
                      prefix: sRoot
                    },
                  },
                  libraries: true
                }
              },
              copy: {
                copyTmpToDist: {
                  files: [
                    {
                      expand: true,
                      src: '**/library.js',
                      dest: oConfig.dir.dist,
                      cwd: oConfig.dir.tmpDir

                    }
                  ]
                }
              }
            }, customizer
          );

          break;

        default:
          break;
      }
    }

  } catch (error) {

  }

  // ToDo: replace with find function
  var bHasComponents = true;
  if (bHasComponents) {
    mergeWith(oConfig,
      {
        copy: {
          copyTmpToDist: {
            files: [
              {
                expand: true,
                src: '**/Component.js',
                dest: oConfig.dir.dist,
                cwd: oConfig.dir.tmpDir

              }
            ]
          }
        }
      }, customizer
    );
  }

  grunt.config("openui5_preload", oConfig.openui5_preload);
  grunt.config("copy", oConfig.copy);

  grunt.registerTask('default', [
    'lint',
    'clean',
    'build'
  ]);
};
<commit_msg>ui5 version<commit_after>/*
 * grunt-sapui5
 * https://github.com/pplenkov/grunt-sapui5
 *
 * Copyright (c) 2017 theplenkov
 * Licensed under the MIT license.
 */

'use strict';

module.exports = function (grunt) {
  'use strict';

  //load SAP task
  grunt.loadNpmTasks('@sap/grunt-sapui5-bestpractice-build');

  // merging function
  var mergeWith = require('lodash.mergewith');
  var customizer = function (objValue, srcValue) {
    if (Array.isArray(objValue)) {
      return [srcValue].concat(objValue);
    }
  };

  // read config
  var oConfig = grunt.config();

  try {
    // read manifest.json
    var oManifest = grunt.file.readJSON(oConfig.dir.webapp + "/manifest.json");

    // take sap.app version
    var oApp = oManifest["sap.app"];
    var oUI5 = oManifest["sap.ui5"];

    var sVersion = (oUI5 && oUI5.dependencies && oUI5.dependencies.minUI5Version) ? oUI5.dependencies.minUI5Version.substring(0, 4) : "1.38";

    if (oApp) {
      switch (oApp.type) {
        // for libraries we should create library.json
        case "library":

          // a.b.c -> a/b/c
          var sRoot = oConfig.dir.root.split(".").join("/");

          mergeWith(oConfig,
            {

              openui5_preload: {
                preloadTmp: {
                  options: {
                    compatVersion: sVersion,
                    resources: {
                      prefix: sRoot
                    },
                  },
                  libraries: true
                }
              },
              copy: {
                copyTmpToDist: {
                  files: [
                    {
                      expand: true,
                      src: '**/library.js',
                      dest: oConfig.dir.dist,
                      cwd: oConfig.dir.tmpDir

                    }
                  ]
                }
              }
            }, customizer
          );

          break;

        default:
          break;
      }
    }

  } catch (error) {

  }

  // ToDo: replace with find function
  var bHasComponents = true;
  if (bHasComponents) {
    mergeWith(oConfig,
      {
        copy: {
          copyTmpToDist: {
            files: [
              {
                expand: true,
                src: '**/Component.js',
                dest: oConfig.dir.dist,
                cwd: oConfig.dir.tmpDir

              }
            ]
          }
        }
      }, customizer
    );
  }

  grunt.config("openui5_preload", oConfig.openui5_preload);
  grunt.config("copy", oConfig.copy);

  grunt.registerTask('default', [
    'lint',
    'clean',
    'build'
  ]);
};
<|endoftext|>


<commit_before>/*
 * grunt-bbb-styles
 * http://gruntjs.com/
 *
 * Copyright (c) 2013 Tim Branyen
 * Licensed under the MIT license.
 */

module.exports = function(grunt) {
  "use strict";

  var path = require("path");
  var cssom = require("cssom");

  // Grunt.
  var _ = grunt.util._;
  var log = grunt.log;
  var file = grunt.file;

  grunt.registerMultiTask("styles", "Compile project styles.", function() {
    var done = this.async();
    // Output file.
    var output = "";
    // Options.
    var options = this.data;
    // Read in the contents.
    var contents = file.read(options.src);
    // Parse the stylesheet.
    var stylesheet = cssom.parse(contents);
    // Include the Stylus library.
    var stylus = require("grunt-lib-stylus").init(grunt);
    var less = require("grunt-lib-less").init(grunt);
    // Ensure that any template's used in the file name are accounted for.
    var processedTarget = grunt.config.process(this.target);

    // If no CSS rules are defined, why are we even here?
    if (!Array.isArray(stylesheet.cssRules)) {
      return log.write("No css imports defined.");
    }

    if (!options.paths) {
      options.paths = [];
    }

    if (!options.prefix) {
      options.prefix = "./app/styles/";
    }

    // Iterate over the CSS rules, reducing to only @imports, then apply the
    // correct prefixed path to each file.
    var paths = stylesheet.cssRules.reduce(function(paths, rule) {
      // If it has a path it's relevant, so add to the paths array.
      if (rule.href) {
        paths.push(rule.href);
      }

      return paths;
    }, []).map(function(path) {
      return options.prefix + path;
    }).concat(options.additional || []);

    function additionalProcessing(css, filepath) {
      var stylesheet = cssom.parse(css);
      var url = /url\("(.*)"\)/;
      var dir = path.dirname(filepath);
      var rel = options.forceRelative;

      // Augment paths if a forceRelative path is specificed.
      if (options.hasOwnProperty("forceRelative")) {
        stylesheet.cssRules.forEach(function(rule) {
          // Iterate over all styles and find all `url` values.
          [].slice.apply(rule.style || []).forEach(function(key) {
            var value = rule.style[key];
            var match;

            // Replace the image paths.
            if (match = value.match(url)) {
              value = value.replace(match[1], rel + path.join(dir, match[1]));
              rule.style[key] = value;
            }
          });
        });

        // Return the normalized data.
        return stylesheet.toString();
      }

      return css;
    }

    function process(paths, cb) {
      if (!paths.length) { return cb(); }

      var opts = {
        paths: [].concat(options.paths)
      };

      // Get the first path off the array.
      var filepath = paths.shift();
      // Find the contents.
      var contents = file.read(filepath);

      // Add the current dirname to the paths.
      opts.paths.push(path.dirname(filepath));

      // Parse Stylus files.
      if (path.extname(filepath).slice(1) === "styl") {
        // Compile the source.
        return stylus.compile(String(contents), opts, function(css) {
          output += additionalProcessing(css, filepath);

          // Continue processing.
          process(paths, cb);
        });

      // Parse LESS files.
      } else if (path.extname(filepath).slice(1) === "less") {
        // Compile the source.
        return less.compile(String(contents), opts, function(css) {
          output += additionalProcessing(css, filepath);

          // Continue processing.
          process(paths, cb);
        });
      }

      // Add vanilla CSS files.
      output += additionalProcessing(contents, filepath);

      // Continue processing.
      return process(paths, cb);
    }

    // Once finished processing...
    process(paths, function() {
      // Write out the debug file.
      file.write(processedTarget, output);

      // Success message.
      log.writeln("File " + processedTarget + " created.");

      done();
    });
  });
};
<commit_msg>Removed use of CSSOM for parsed stylesheet output<commit_after>/*
 * grunt-bbb-styles
 * http://gruntjs.com/
 *
 * Copyright (c) 2013 Tim Branyen
 * Licensed under the MIT license.
 */

module.exports = function(grunt) {
  "use strict";

  var path = require("path");
  var cssom = require("cssom");

  // Grunt.
  var _ = grunt.util._;
  var log = grunt.log;
  var file = grunt.file;

  grunt.registerMultiTask("styles", "Compile project styles.", function() {
    var done = this.async();
    // Output file.
    var output = "";
    // Options.
    var options = this.data;
    // Read in the contents.
    var contents = file.read(options.src);
    // Parse the stylesheet.
    var stylesheet = cssom.parse(contents);
    // Include the Stylus library.
    var stylus = require("grunt-lib-stylus").init(grunt);
    var less = require("grunt-lib-less").init(grunt);
    // Ensure that any template's used in the file name are accounted for.
    var processedTarget = grunt.config.process(this.target);

    // If no CSS rules are defined, why are we even here?
    if (!Array.isArray(stylesheet.cssRules)) {
      return log.write("No css imports defined.");
    }

    if (!options.paths) {
      options.paths = [];
    }

    if (!options.prefix) {
      options.prefix = "./app/styles/";
    }

    // Iterate over the CSS rules, reducing to only @imports, then apply the
    // correct prefixed path to each file.
    var paths = stylesheet.cssRules.reduce(function(paths, rule) {
      // If it has a path it's relevant, so add to the paths array.
      if (rule.href) {
        paths.push(rule.href);
      }

      return paths;
    }, []).map(function(path) {
      return options.prefix + path;
    }).concat(options.additional || []);

    function additionalProcessing(css, filepath) {
      var url =/(url\([\'"]?)((?:[^\);](?!base64))+)([\'"]?\))/g;
      var dir = path.dirname(filepath);
      var rel = options.forceRelative;

      // Augment paths if a forceRelative path is specificed.
      if (options.hasOwnProperty("forceRelative")) {

        // Search the content for the url pattern
        // and call our function to dynamically create
        // a replacement
        return css.replace(url, function(match, p1, p2, p3){
          return p1 + rel + path.join(dir, p2) + p3;
        });
      }

      return css;
    }

    function process(paths, cb) {
      if (!paths.length) { return cb(); }

      var opts = {
        paths: [].concat(options.paths)
      };

      // Get the first path off the array.
      var filepath = paths.shift();
      // Find the contents.
      var contents = file.read(filepath);

      // Add the current dirname to the paths.
      opts.paths.push(path.dirname(filepath));

      // Parse Stylus files.
      if (path.extname(filepath).slice(1) === "styl") {
        // Compile the source.
        return stylus.compile(String(contents), opts, function(css) {
          output += additionalProcessing(css, filepath);

          // Continue processing.
          process(paths, cb);
        });

      // Parse LESS files.
      } else if (path.extname(filepath).slice(1) === "less") {
        // Compile the source.
        return less.compile(String(contents), opts, function(css) {
          output += additionalProcessing(css, filepath);

          // Continue processing.
          process(paths, cb);
        });
      }

      // Add vanilla CSS files.
      output += additionalProcessing(contents, filepath);

      // Continue processing.
      return process(paths, cb);
    }

    // Once finished processing...
    process(paths, function() {
      // Write out the debug file.
      file.write(processedTarget, output);

      // Success message.
      log.writeln("File " + processedTarget + " created.");

      done();
    });
  });
};
<|endoftext|>


<commit_before>// Copyright (c) 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// @ts-nocheck
// TODO(crbug.com/1011811): Enable TypeScript compiler checks

import * as ARIAProperties from '../generated/ARIAProperties.js';

/**
 * @unrestricted
 */
export class ARIAMetadata {
  /**
   * @param {?Object} config
   */
  constructor(config) {
    /** @type {!Map<string, !Attribute>} */
    this._attributes = new Map();

    if (config) {
      this._initialize(config);
    }
  }

  /**
   * @param {!Object} config
   */
  _initialize(config) {
    const attributes = config['attributes'];

    const booleanEnum = ['true', 'false'];
    for (const attributeConfig of attributes) {
      if (attributeConfig.type === 'boolean') {
        attributeConfig.enum = booleanEnum;
      }
      this._attributes.set(attributeConfig.name, new Attribute(attributeConfig));
    }

    /** @type {!Array<string>} */
    this._roleNames = config['roles'].map(roleConfig => roleConfig.name);
  }

  /**
   * @param {string} property
   * @return {!Array<string>}
   */
  valuesForProperty(property) {
    if (this._attributes.has(property)) {
      return this._attributes.get(property).getEnum();
    }

    if (property === 'role') {
      return this._roleNames;
    }

    return [];
  }
}

/**
 * @return {!ARIAMetadata}
 */
export function ariaMetadata() {
  if (!ARIAMetadata._instance) {
    ARIAMetadata._instance = new ARIAMetadata(ARIAProperties.config || null);
  }
  return ARIAMetadata._instance;
}

/**
 * @unrestricted
 */
export class Attribute {
  /**
   * @param {!Object} config
   */
  constructor(config) {
    /** @type {!Array<string>} */
    this._enum = [];

    if ('enum' in config) {
      this._enum = config.enum;
    }
  }

  /**
   * @return {!Array<string>}
   */
  getEnum() {
    return this._enum;
  }
}
<commit_msg>Migrate ARIAMetadata.js to TypeScript<commit_after>// Copyright (c) 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import * as ARIAProperties from '../generated/ARIAProperties.js';

/**
 * @typedef {{
 *   name: string,
 *   type: string,
 *   enum: (!Array<string>|undefined),
 * }}
 */
// @ts-ignore typedef
export let AttributeConfig;

/**
 * @typedef {{
 *   name: string,
 * }}
 */
// @ts-ignore typedef
export let RoleConfig;

/**
 * @typedef {{
 *   attributes: !Array<!AttributeConfig>,
 *   roles: !Array<!RoleConfig>
 * }}
 */
// @ts-ignore typedef
export let Config;

/**
 * @unrestricted
 */
export class ARIAMetadata {
  /**
   * @param {?Config} config
   */
  constructor(config) {
    /** @type {!Map<string, !Attribute>} */
    this._attributes = new Map();
    /** @type {!Array<string>} */
    this._roleNames = [];

    if (config) {
      this._initialize(config);
    }
  }

  /**
   * @param {!Config} config
   */
  _initialize(config) {
    const attributes = config['attributes'];

    const booleanEnum = ['true', 'false'];
    for (const attributeConfig of attributes) {
      if (attributeConfig.type === 'boolean') {
        attributeConfig.enum = booleanEnum;
      }
      this._attributes.set(attributeConfig.name, new Attribute(attributeConfig));
    }

    /** @type {!Array<string>} */
    this._roleNames = config['roles'].map(roleConfig => roleConfig.name);
  }

  /**
   * @param {string} property
   * @return {!Array<string>}
   */
  valuesForProperty(property) {
    const attribute = this._attributes.get(property);
    if (attribute) {
      return attribute.getEnum();
    }

    if (property === 'role') {
      return this._roleNames;
    }

    return [];
  }
}

/**
 * @type {!ARIAMetadata | undefined}
 */
let _instance;

/**
 * @return {!ARIAMetadata}
 */
export function ariaMetadata() {
  if (!_instance) {
    _instance = new ARIAMetadata(/** @type {!Config} */ (ARIAProperties.config) || null);
  }
  return _instance;
}

/**
 * @unrestricted
 */
export class Attribute {
  /**
   * @param {!AttributeConfig} config
   */
  constructor(config) {
    /** @type {!Array<string>} */
    this._enum = [];

    if (config.enum) {
      this._enum = config.enum;
    }
  }

  /**
   * @return {!Array<string>}
   */
  getEnum() {
    return this._enum;
  }
}
<|endoftext|>


<commit_before>import { PropTypes } from 'react'

export const matchContext = PropTypes.shape({
  addMatch: PropTypes.func.isRequired,
  removeMatch: PropTypes.func.isRequired
})

export const history = PropTypes.shape({
  listen: PropTypes.func.isRequired,
  listenBefore: PropTypes.func.isRequired,
  push: PropTypes.func.isRequired,
  replace: PropTypes.func.isRequired,
  go: PropTypes.func.isRequired
})

export const location = PropTypes.shape({
  pathname: PropTypes.string.isRequired,
  search: PropTypes.string.isRequired,
  hash: PropTypes.string.isRequired,
  state: PropTypes.any,
  key: PropTypes.string
})

export const routerContext = PropTypes.shape({
  transitionTo: PropTypes.func.isRequired,
  replaceWith: PropTypes.func.isRequired,
  blockTransitions: PropTypes.func.isRequired,
  createHref: PropTypes.func.isRequired
})

export const action = PropTypes.oneOf([
  'PUSH',
  'REPLACE',
  'POP'
])
<commit_msg>Move stuff around<commit_after>import { PropTypes } from 'react'

export const action = PropTypes.oneOf([
  'PUSH',
  'REPLACE',
  'POP'
])

export const matchContext = PropTypes.shape({
  addMatch: PropTypes.func.isRequired,
  removeMatch: PropTypes.func.isRequired
})

export const history = PropTypes.shape({
  listen: PropTypes.func.isRequired,
  listenBefore: PropTypes.func.isRequired,
  push: PropTypes.func.isRequired,
  replace: PropTypes.func.isRequired,
  go: PropTypes.func.isRequired
})

export const location = PropTypes.shape({
  pathname: PropTypes.string.isRequired,
  search: PropTypes.string.isRequired,
  hash: PropTypes.string.isRequired,
  state: PropTypes.any,
  key: PropTypes.string
})

export const routerContext = PropTypes.shape({
  transitionTo: PropTypes.func.isRequired,
  replaceWith: PropTypes.func.isRequired,
  blockTransitions: PropTypes.func.isRequired,
  createHref: PropTypes.func.isRequired
})
<|endoftext|>


<commit_before><commit_msg>Removing some extra parentheses<commit_after><|endoftext|>


<commit_before>var PythonShell = require('python-shell');

module.exports = function(RED) {
    function AdafruitMax31855Node(config) {
        RED.nodes.createNode(this,config);
        var node = this;

        var scriptPath = './spi_read.py'
        var pyshell = new PythonShell(scriptPath, { scriptPath: __dirname });

        pyshell.on('message', function (message) {
            // received a message sent from the Python script (a simple "print" statement)
            node.send({
                payload: message
            });
        });

        // end the input stream and allow the process to exit
        pyshell.end(function (err) {
            if (err) throw err;
            node.send('finished');
        });
    }
    RED.nodes.registerType("adafruit-max31855", AdafruitMax31855Node);
}<commit_msg>End pyshell when node is closed.<commit_after>var PythonShell = require('python-shell');

module.exports = function(RED) {
    function AdafruitMax31855Node(config) {
        RED.nodes.createNode(this,config);
        var node = this;

        var scriptPath = './spi_read.py'
        var pyshell = new PythonShell(scriptPath, { scriptPath: __dirname });

        pyshell.on('message', function (message) {
            node.send({
                payload: message
            });
        });

        this.on("close", function() {
            if (pyshell) { pyshell.end(); }
        });
    }
    RED.nodes.registerType("adafruit-max31855", AdafruitMax31855Node);
}<|endoftext|>


<commit_before>// Copyright © 2014 Intel Corporation. All rights reserved.
// Use  of this  source  code is  governed by  an Apache v2
// license that can be found in the LICENSE-APACHE-V2 file.

var FS = require("fs");
var Mustache = require("mustache");

/**
 * Class to handle reading and writing template files.
 * @function
 * @param {String} path Path to template file.
 * @throws {Error} When file could not be read.
 * @constructor
 */
function TemplateFile(path) {

    this._buffer = FS.readFileSync(path);
    if (!this._buffer || this._buffer.length === 0) {
        throw new Error("Could not read " + path);
    }
}

/**
 * Render template file to output file.
 * @function
 * @param {Object} data Data according to Mustache docs.
 * @param {String} path Path to output file.
 * @returns {Error} when failed, null on success.
 */
TemplateFile.prototype.renderTo = function(data, path) {

    var output = Mustache.render(this._buffer, data);
    return FS.writeFileSync(path, output);
};

module.exports = TemplateFile;
<commit_msg>TemplateFile: Rename renderTo() to render()<commit_after>// Copyright © 2014 Intel Corporation. All rights reserved.
// Use  of this  source  code is  governed by  an Apache v2
// license that can be found in the LICENSE-APACHE-V2 file.

var FS = require("fs");
var Mustache = require("mustache");

/**
 * Class to handle reading and writing template files.
 * @param {String} path Path to template file.
 * @throws {Error} When file could not be read.
 * @constructor
 */
function TemplateFile(path) {

    this._buffer = FS.readFileSync(path);
    if (!this._buffer || this._buffer.length === 0) {
        throw new Error("Could not read " + path);
    }
}

/**
 * Render template file to output file.
 * @function render
 * @param {Object} data Data according to Mustache docs.
 * @param {String} path Path to output file.
 * @returns {Error} when failed, null on success.
 * @memberOf TemplateFile
 */
TemplateFile.prototype.render = function(data, path) {

    var output = Mustache.render(this._buffer, data);
    return FS.writeFileSync(path, output);
};

module.exports = TemplateFile;
<|endoftext|>


<commit_before>import React from 'react';
import {withStyles} from 'material-ui/styles';
import TextField from 'material-ui/TextField';
import PropTypes from 'prop-types'

const styles = theme => ({
    textField: {
    }
});

const InputBox = ({content, classes, onChange}) => {
    return <TextField
        id="input"
        label="Original"
        value={content}
        onChange={() => onChange(content)}
        multiline={true}
        fullWidth={true}
        className={classes.textField}
    />
}

InputBox.propTypes = {
    content: PropTypes.string.isRequired,
    onChange: PropTypes.func.isRequired
}

export default withStyles(styles)(InputBox);<commit_msg>Reduxify, add state<commit_after>import React from 'react';
import {withStyles} from 'material-ui/styles';
import TextField from 'material-ui/TextField';
import PropTypes from 'prop-types'

const styles = theme => ({
    textField: {
    }
});

// TODO: This SHOULD be a stateless component, but I didn't want to deal with redux-form just for a text area. Easier (but dirtier) to let this field have its own state
class InputBox extends React.Component {
    constructor(props) {
        super(props);
        this.state = { value: this.props.content };

        this.handleChange = this.handleChange.bind(this);
    }

    async handleChange(event) {
        await this.setState({ value: event.target.value });
        this.props.onChange(this.state.value);
    }

    render() {
        return <TextField
            id="input"
            label="Original"
            value={this.state.value}
            onChange={this.handleChange}
            multiline={true}
            fullWidth={true}
            className={this.props.classes.textField}
        />
    }
}

InputBox.propTypes = {
    content: PropTypes.string.isRequired,
    onChange: PropTypes.func.isRequired
}

export default withStyles(styles)(InputBox);<|endoftext|>


<commit_before>var pollingRequests;
var showConsoleDebug = false;

$(document).ready(function () {

    pollingRequests = 0;

    if (!showConsoleDebug)
    {
        console.warn('Console Debug Messages Disabled')
    } else {
        console.log('Console Debug Messages Enabled');
    }

    $('#backlog-per-page').change(function() {
        this.form.submit();
    });

    $('#completed-per-page').change(function() {
        this.form.submit();
    });

    initializeColumnCollapse();

    checkForKanbanUpdate();
});

function checkForKanbanUpdate()
{
    boardTimestamp = parseInt($('#boardTimestamp').val(), 10);

    if (boardTimestamp > 0) {
        pollingRequests++;
        ajaxCookie = getColumnCookies();

        if (showConsoleDebug) {
            console.log('%c Long Polling: Start (send ajax request)', 'background: #a0a0a0;');
            console.log('- boardTimestamp: ' + boardTimestamp);
            console.log('- polling requests: ' + pollingRequests);
            console.dir(ajaxCookie);
        }

        $.ajax({
            url: "/board/polling",
            type: "post",
            timeout: longPollingTimeout,
            data: {
                'boardTimestamp': boardTimestamp,
                'ajaxCookie': JSON.stringify(ajaxCookie),
            },
        }).done(function (returnData) {
            pollingRequests--;
            newTimestamp = parseInt(returnData.newTimestamp);
            returnBoardTimestamp = parseInt(returnData.boardTimestamp, 10);

            // NewTimestamp checks if the server has returned an actual update
            // boardTimestamp comparison checks if this is a return from this client (???)
            if ((newTimestamp > 0) && (boardTimestamp == returnBoardTimestamp)) {

                $('.board-column' ).sortable('destroy');
                $('#kanban-row').html(returnData.html);
                $('#boardTimestamp').val(returnData.newTimestamp);
                initializeBoard();
                initializeColumnCollapse();
                synchronizeCollapseStatusToCookie();

                if (showConsoleDebug) {
                    console.info("Long Polling: Change");
                    console.log('- newTimestamp: ' + newTimestamp);
                    console.log('- boardTimestamp: ' + boardTimestamp);
                    console.log('- returnBoardTimestamp: ' + returnBoardTimestamp);
                    console.log('- polling requests: ' + pollingRequests);
                    console.log('- counterLimit    : ' + returnData.counterLimit);
                    console.log('- counter         : ' + returnData.counter);
                }

            } else {

                if (showConsoleDebug) {
                    console.warn("Long Polling: Bad Data");
                    console.log('- newTimestamp: ' + newTimestamp);
                    console.log('- boardTimestamp: ' + boardTimestamp);
                    console.log('- returnBoardTimestamp: ' + returnBoardTimestamp);
                    console.log('- polling requests: ' + pollingRequests);
                }

            }

            checkForKanbanUpdate();

        }).fail(function (jqXHR, textStatus, errorThrown) {
            pollingRequests--;

            if (showConsoleDebug) {
                var time = new Date();
                formattedTime =
                    ("0" + time.getHours()).slice(-2) + ":" +
                    ("0" + time.getMinutes()).slice(-2) + ":" +
                    ("0" + time.getSeconds()).slice(-2);

                console.warn('Long Polling: Fail');
                console.log('- time: ' + formattedTime);
                console.log('- status: ' + textStatus);
                console.log('- error: ' + errorThrown);
                console.log('- polling requests: ' + pollingRequests);
            }

            checkForKanbanUpdate();
        });
    }
}

function getColumnCookies()
{
    var columnCookies = {};

    $('.panel-collapse').each( function(index, element){
        columnId = $(this).attr('id');
        cookieValue = getCookie(columnId);
        if (cookieValue) {
            columnCookies[columnId] = cookieValue;
        }
    });

    return columnCookies;
}

function synchronizeCollapseStatusToCookie()
{
    columnCookies = getColumnCookies();
    for(var k in columnCookies) {
        console.log(k, columnCookies[k]);
    }
}

function initializeColumnCollapse()
{
    $('.apc-col-btn').siblings('.panel-collapse').on('shown.bs.collapse', function() {
        columnNumber = this.id;
        setCookie(columnNumber, 1, 365);

        if (showConsoleDebug) {
            console.log('Column shown ' + columnNumber);
        }
    });

    $('.apc-col-btn').siblings('.panel-collapse').on('hidden.bs.collapse', function() {
        columnNumber = this.id;
        setCookie(columnNumber, 0, 365);

        if (showConsoleDebug) {
            console.log('Column hidden ' + columnNumber);
        }
    });
}<commit_msg>Javascript Column collapse status  on AJAX Polling Update looks good<commit_after>var pollingRequests;
var showConsoleDebug = false;

$(document).ready(function () {

    pollingRequests = 0;

    if (!showConsoleDebug)
    {
        console.warn('Console Debug Messages Disabled');
    } else {
        console.log('Console Debug Messages Enabled');
    }

    $('#backlog-per-page').change(function() {
        this.form.submit();
    });

    $('#completed-per-page').change(function() {
        this.form.submit();
    });

    initializeColumnCollapse();

    checkForKanbanUpdate();
});

function checkForKanbanUpdate()
{
    boardTimestamp = parseInt($('#boardTimestamp').val(), 10);

    if (boardTimestamp > 0) {
        pollingRequests++;
        ajaxCookie = getColumnCookies();

        if (showConsoleDebug) {
            console.log('%c Long Polling: Start (send ajax request)', 'background: #a0a0a0;');
            console.log('- boardTimestamp: ' + boardTimestamp);
            console.log('- polling requests: ' + pollingRequests);
            console.dir(ajaxCookie);
        }

        $.ajax({
            url: "/board/polling",
            type: "post",
            timeout: longPollingTimeout,
            data: {
                'boardTimestamp': boardTimestamp,
                'ajaxCookie': JSON.stringify(ajaxCookie),
            },
        }).done(function (returnData) {
            pollingRequests--;
            newTimestamp = parseInt(returnData.newTimestamp);
            returnBoardTimestamp = parseInt(returnData.boardTimestamp, 10);

            // NewTimestamp checks if the server has returned an actual update
            // boardTimestamp comparison checks if this is a return from this client (???)
            if ((newTimestamp > 0) && (boardTimestamp == returnBoardTimestamp)) {

                $('.board-column' ).sortable('destroy');
                $('#kanban-row').html(returnData.html);
                $('#boardTimestamp').val(returnData.newTimestamp);
                initializeBoard();
                initializeColumnCollapse();
                synchronizeCollapseStatusToCookie();

                if (showConsoleDebug) {
                    console.info("Long Polling: Change");
                    console.log('- newTimestamp: ' + newTimestamp);
                    console.log('- boardTimestamp: ' + boardTimestamp);
                    console.log('- returnBoardTimestamp: ' + returnBoardTimestamp);
                    console.log('- polling requests: ' + pollingRequests);
                    console.log('- counterLimit    : ' + returnData.counterLimit);
                    console.log('- counter         : ' + returnData.counter);
                }

            } else {

                if (showConsoleDebug) {
                    console.warn("Long Polling: Bad Data");
                    console.log('- newTimestamp: ' + newTimestamp);
                    console.log('- boardTimestamp: ' + boardTimestamp);
                    console.log('- returnBoardTimestamp: ' + returnBoardTimestamp);
                    console.log('- polling requests: ' + pollingRequests);
                }

            }

            checkForKanbanUpdate();

        }).fail(function (jqXHR, textStatus, errorThrown) {
            pollingRequests--;

            if (showConsoleDebug) {
                var time = new Date();
                formattedTime =
                    ("0" + time.getHours()).slice(-2) + ":" +
                    ("0" + time.getMinutes()).slice(-2) + ":" +
                    ("0" + time.getSeconds()).slice(-2);

                console.warn('Long Polling: Fail');
                console.log('- time: ' + formattedTime);
                console.log('- status: ' + textStatus);
                console.log('- error: ' + errorThrown);
                console.log('- polling requests: ' + pollingRequests);
            }

            checkForKanbanUpdate();
        });
    }
}

function getColumnCookies()
{
    var columnCookies = {};

    $('.panel-collapse').each( function(index, element){
        columnId = $(this).attr('id');
        cookieValue = getCookie(columnId);
        if (cookieValue) {
            columnCookies[columnId] = cookieValue;
        }
    });

    return columnCookies;
}

function synchronizeCollapseStatusToCookie()
{
    columnCookies = getColumnCookies();
    for(var k in columnCookies) {
        if (columnCookies[k] == 1) {
            $('#' + k).collapse('show');
            if (showConsoleDebug) {
                console.log('Show: ' + k);
            }
        } else {
            $('#' + k).collapse('hide');
            if (showConsoleDebug) {
                console.log('Close: ' + k);
            }
        }
    }
}

function initializeColumnCollapse()
{
    $('.apc-col-btn').siblings('.panel-collapse').on('shown.bs.collapse', function() {
        columnNumber = this.id;
        setCookie(columnNumber, 1, 365);

        if (showConsoleDebug) {
            console.log('Column shown ' + columnNumber);
        }
    });

    $('.apc-col-btn').siblings('.panel-collapse').on('hidden.bs.collapse', function() {
        columnNumber = this.id;
        setCookie(columnNumber, 0, 365);

        if (showConsoleDebug) {
            console.log('Column hidden ' + columnNumber);
        }
    });
}<|endoftext|>


<commit_before>set_global('$', global.make_zjquery());
zrequire('input_pill');

zrequire('Handlebars', 'handlebars');
zrequire('templates');
global.compile_template('input_pill');

set_global('blueslip', {
});

var noop = function () {};

set_global('ui_util', {
    place_caret_at_end: noop,
});

var id_seq = 0;

(function set_up_ids() {
    // just get coverage on a simple one-liner:
    input_pill.random_id();

    input_pill.random_id = function () {
        id_seq += 1;
        return 'some_id' + id_seq;
    };
}());

function pill_html(value, data_id) {
    var opts = {
        id: data_id,
        display_value: value,
    };

    return templates.render('input_pill', opts);
}

(function test_basics() {
    var error;

    var config = {};

    blueslip.error = function (err) {
        error = err;
    };

    input_pill.create(config);
    assert.equal(error, 'Pill needs container.');

    var pill_input = $.create('pill_input');
    var container = $.create('container');
    container.set_find_results('.input', pill_input);

    config.container = container;
    input_pill.create(config);
    assert.equal(error, 'Pill needs create_item_from_text');

    config.create_item_from_text = noop;
    input_pill.create(config);
    assert.equal(error, 'Pill needs get_text_from_item');

    blueslip.error = function () {
        throw "unexpected error";
    };

    config.get_text_from_item = noop;
    var widget = input_pill.create(config);

    var item = {
        display_value: 'JavaScript',
        language: 'js',
    };

    var inserted_before;
    var expected_html = pill_html('JavaScript', 'some_id1');

    pill_input.before = function (elem) {
        inserted_before = true;
        assert.equal(elem.html(), expected_html);
    };

    widget.appendValidatedData(item);
    assert(inserted_before);

    assert.deepEqual(widget.items(), [item]);
}());

(function test_insert_remove() {
    set_global('$', global.make_zjquery());
    var items = {
        blue: {
            display_value: 'BLUE',
            description: 'color of the sky',
        },

        red: {
            display_value: 'RED',
            description: 'color of stop signs',
        },

        yellow: {
            display_value: 'YELLOW',
            description: 'color of bananas',
        },
    };

    var pill_input = $.create('pill_input');

    var inserted_html = [];
    pill_input.before = function (elem) {
        inserted_html.push(elem.html());
    };

    var create_item_from_text = function (text) {
        return items[text];
    };

    var container = $.create('container');
    container.set_find_results('.input', pill_input);

    var config = {
        container: container,
        create_item_from_text: create_item_from_text,
        get_text_from_item: noop,
    };

    id_seq = 0;

    // FINALLY CREATE THE WIDGET!!
    var widget = input_pill.create(config);

    var created;
    var removed;

    widget.onPillCreate(function () {
        created = true;
    });

    widget.onPillRemove(function () {
        removed = true;
    });

    widget.appendValue('blue,chartreuse,red,yellow,mauve');

    assert(created);
    assert(!removed);

    assert.deepEqual(inserted_html, [
        pill_html('BLUE', 'some_id1'),
        pill_html('RED', 'some_id2'),
        pill_html('YELLOW', 'some_id3'),
    ]);

    assert.deepEqual(widget.items(), [
        items.blue,
        items.red,
        items.yellow,
    ]);

    assert.equal(pill_input.text(), 'chartreuse, mauve');

    widget.clear_text();
    assert.equal(pill_input.text(), '');

    var BACKSPACE = 8;
    var key_handler = container.get_on_handler('keydown', '.input');

    key_handler({
        keyCode: BACKSPACE,
        target: {
            innerText: '',
        },
        preventDefault: noop,
    });

    assert(removed);

    assert.deepEqual(widget.items(), [
        items.blue,
        items.red,
    ]);
}());
<commit_msg>zblueslip: Convert node_tests/input_pill.js to zblueslip.<commit_after>set_global('$', global.make_zjquery());
zrequire('input_pill');

zrequire('Handlebars', 'handlebars');
zrequire('templates');
global.compile_template('input_pill');

set_global('blueslip', global.make_zblueslip());

var noop = function () {};

set_global('ui_util', {
    place_caret_at_end: noop,
});

var id_seq = 0;

(function set_up_ids() {
    // just get coverage on a simple one-liner:
    input_pill.random_id();

    input_pill.random_id = function () {
        id_seq += 1;
        return 'some_id' + id_seq;
    };
}());

function pill_html(value, data_id) {
    var opts = {
        id: data_id,
        display_value: value,
    };

    return templates.render('input_pill', opts);
}

(function test_basics() {
    var config = {};

    blueslip.set_test_data('error', 'Pill needs container.');
    input_pill.create(config);
    assert.equal(blueslip.get_test_logs('error').length, 1);
    blueslip.clear_test_data();

    var pill_input = $.create('pill_input');
    var container = $.create('container');
    container.set_find_results('.input', pill_input);

    blueslip.set_test_data('error', 'Pill needs create_item_from_text');
    config.container = container;
    input_pill.create(config);
    assert.equal(blueslip.get_test_logs('error').length, 1);
    blueslip.clear_test_data();

    blueslip.set_test_data('error', 'Pill needs get_text_from_item');
    config.create_item_from_text = noop;
    input_pill.create(config);
    assert.equal(blueslip.get_test_logs('error').length, 1);
    blueslip.clear_test_data();

    config.get_text_from_item = noop;
    var widget = input_pill.create(config);

    var item = {
        display_value: 'JavaScript',
        language: 'js',
    };

    var inserted_before;
    var expected_html = pill_html('JavaScript', 'some_id1');

    pill_input.before = function (elem) {
        inserted_before = true;
        assert.equal(elem.html(), expected_html);
    };

    widget.appendValidatedData(item);
    assert(inserted_before);

    assert.deepEqual(widget.items(), [item]);
}());

(function test_insert_remove() {
    set_global('$', global.make_zjquery());
    var items = {
        blue: {
            display_value: 'BLUE',
            description: 'color of the sky',
        },

        red: {
            display_value: 'RED',
            description: 'color of stop signs',
        },

        yellow: {
            display_value: 'YELLOW',
            description: 'color of bananas',
        },
    };

    var pill_input = $.create('pill_input');

    var inserted_html = [];
    pill_input.before = function (elem) {
        inserted_html.push(elem.html());
    };

    var create_item_from_text = function (text) {
        return items[text];
    };

    var container = $.create('container');
    container.set_find_results('.input', pill_input);

    var config = {
        container: container,
        create_item_from_text: create_item_from_text,
        get_text_from_item: noop,
    };

    id_seq = 0;

    // FINALLY CREATE THE WIDGET!!
    var widget = input_pill.create(config);

    var created;
    var removed;

    widget.onPillCreate(function () {
        created = true;
    });

    widget.onPillRemove(function () {
        removed = true;
    });

    widget.appendValue('blue,chartreuse,red,yellow,mauve');

    assert(created);
    assert(!removed);

    assert.deepEqual(inserted_html, [
        pill_html('BLUE', 'some_id1'),
        pill_html('RED', 'some_id2'),
        pill_html('YELLOW', 'some_id3'),
    ]);

    assert.deepEqual(widget.items(), [
        items.blue,
        items.red,
        items.yellow,
    ]);

    assert.equal(pill_input.text(), 'chartreuse, mauve');

    widget.clear_text();
    assert.equal(pill_input.text(), '');

    var BACKSPACE = 8;
    var key_handler = container.get_on_handler('keydown', '.input');

    key_handler({
        keyCode: BACKSPACE,
        target: {
            innerText: '',
        },
        preventDefault: noop,
    });

    assert(removed);

    assert.deepEqual(widget.items(), [
        items.blue,
        items.red,
    ]);
}());
<|endoftext|>


<commit_before>(function(ns) {
  var prevState = ns.prevState || [];
  var currentState = [];
  var domGUID = ns.domGUID = ns.domGUID || 0;
  var nodeTypes = [];

  $('body').contents().each(function processNodes() {
    var selfNode = this;
    var jqThis = $(this);
    var val = "";
    var childs = [];
    var childIDs = [];
    var thisUID = -1;

    if(this.domDeltaID) { thisUID = this.domDeltaID; }
    else {
      thisUID = this.domDeltaID = ns.domGUID++;
      val += "ADDED NODE: " + this.domDeltaID + "; ";
    }

    if(nodeTypes.indexOf(this.nodeType) == -1) nodeTypes.push(this.nodeType);

    var tempstyle = window.getComputedStyle(this);
    var style = null;

    // Deep copy the computed style in case the function returns the same object
    if(tempstyle) {
      style = {};
      $.each(tempstyle, function(key, value) {
        style[key] = value;
      });
    }

    var attrNames = null;
    var attrVals = null;

    // Gather attributes
    if(this.attributes) {
    	attrNames = [];
    	attrVals = [];

    	for (var i = 0; i < this.attributes.length; i++) {
		  var attrib = this.attributes[i];
		  if (attrib.specified) {
		  	attrNames.push(attrib.name);
		  	attrVals.push(attrib.value);
		  }
		}
    }

    var styleNames = null;
    var styleVals = null;

    // Gather attributes
    if(this.style) {
    	styleNames = [];
    	styleVals = [];

    	for (var sName in this.style) {
		  	styleNames.push(sName);
		  	styleVals.push(this.style[sName]);
		}
    }

    if(jqThis.contents().length > 0) {
      // Make sure children are processed first so we can get a UID for each of them
      jqThis.contents().each(processNodes);

      jqThis.contents().each(function() {
        childs.push(this);
        childIDs.push(this.domDeltaID);
      });
    }

    // Record the state of affairs for the node
    currentState[thisUID] = {style: style, children:childs, childrenIDs:childIDs, dom:this, styleNames:styleNames, styleVals:styleVals, attrNames:attrNames, attrVals:attrVals, classList: this.className ? this.className.split(' ') : null };
  });

  // console.log("NodeTypes", nodeTypes);
  // console.log("Previous State", ns.prevState);
  // console.log("Current State", currentState);

  if(prevState.length > 0) {
    var testsRan = 0;
    console.log("Calculating Diff...");
    for(var i=0,end=currentState.length; i!=end; ++i) {
      // See if the UID exists in the prev state
      if(!(i in prevState)) {
        console.log("Added element: ", currentState[i]);
        continue;
      }

      if(currentState[i]) {}
      else { console.log("POSSIBLY REMOVED: Undefined current state element"); continue; }

      var dom = currentState[i].dom;
      var style = currentState[i].style;
      var prevStyle = prevState[i].style;
      var classList = currentState[i].classList;
      var prevClassList = prevState[i].classList;
      var attrNames = currentState[i].attrNames;
      var prevAttrNames = prevState[i].attrNames;
      var attrVals = currentState[i].attrVals;
      var prevAttrVals = prevState[i].attrVals;
      var styleNames = currentState[i].styleNames;
      var prevStyleNames = prevState[i].styleNames;
      var styleVals = currentState[i].styleVals;
      var prevStyleVals = prevState[i].styleVals;

      // Find class add/removals
      if(classList) {
      	if(prevClassList) {
      		// Adds
      		$.each(classList, function(index, className) {
      			if(className.trim().length > 0) {
	      			if(prevClassList.indexOf(className) == -1) {
	      				console.log("Added class to: ", dom, "Class: ", className);
	      			}
      			}
      		});
      		// Removes
      		$.each(prevClassList, function(index, className) {
      			if(className.trim().length > 0) {
	      			if(classList.indexOf(className) == -1) {
	      				console.log("Removed class from: ", dom, "Class: ", className);
	      			}
      			}
      		});
      	}

      	else {
      		console.log("Added classes to: ", dom, "Classes: ", classList);
      	}
      }

      else {
      	if(prevClassList) {
      		console.log("Removed classes from: ", dom, "Classes: ", classList);
      	}
      }

      // Find attribute add/remove/change
      if(attrNames) {
      	if(prevAttrNames) {
      		// Adds/changes
      		$.each(attrNames, function(index, attrObj) {
      			// Adds
      			if(prevAttrNames.indexOf(attrObj) == -1) {
      				console.log("Added attribute to: ", dom, "Attribute: ", attrObj);
      			}

      			// Changes
      			else {
      				if(attrVals[index] != prevAttrVals[index]) {
      					console.log("Changed attribute on: ", dom, "Prev: ", prevAttrVals[index], "New: ", attrVals[index]);
      				}
      			}
      		});
      		// Removes
      		$.each(prevAttrNames, function(index, attrObj) {
      			if(attrNames.indexOf(attrObj) == -1) {
      				console.log("Removed attribute from: ", dom, "Attribute: ", attrObj);
      			}
      		});
      	}

      	else {
      		console.log("Added attributes to: ", dom, "Attributes: ", attrNames, attrVals);
      	}
      }

      else {
      	if(prevAttrNames) {
      		console.log("Removed attributes from: ", dom, "Attributes: ", prevAttrNames);
      	}
      }

      // Find style add/remove/change
      if(styleNames) {
      	if(prevStyleNames) {
      		// Adds/changes
      		$.each(styleNames, function(index, styleObj) {
      			// Adds
      			if(prevStyleNames.indexOf(styleObj) == -1) {
      				console.log("Added style to: ", dom, "Style: ", styleObj);
      			}

      			// Changes
      			else {
      				if(styleVals[index] != prevStyleVals[index]) {
      					console.log("Changed style:", styleObj, "on:", dom, "Prev:", prevStyleVals[index], "New:", styleVals[index]);
      				}
      			}

      			testsRan++;
      		});
      		// Removes
      		$.each(prevStyleNames, function(index, styleObj) {
      			if(styleNames.indexOf(styleObj) == -1) {
      				console.log("Removed style from: ", dom, "Style: ", styleObj);
      			}
      		});
      	}

      	else {
      		console.log("Added styles to: ", dom, "Styles: ", styleNames, styleVals);
      	}
      }

      else {
      	if(prevStyleNames) {
      		console.log("Removed styles from: ", dom, "Styles: ", prevStyleNames);
      	}
      }

      // Make sure a style was generated for our item in question
      if(style && prevStyle) {
        // Find changed and added properties
        $.each(style, function(key, value) {
          if(key in prevStyle) {
            if((prevStyle[key] != style[key])) {
              console.log("DOM Node:", dom, "Property", key, "PREV: ", prevStyle[key], "NEW: ", style[key]);
            }
          }

          else {
            console.log("DOM Node:", dom, "New Property", key, "NEW: ", style[key]);
          }

          testsRan++;
        });

        // Find removed properties
        $.each(prevStyle, function(key, value) {
          if(!(key in style)) {
            console.log("DOM Node:", dom, "Removed Property", key, "NEW: ", style[key]);
          }
        });
      }

      // Now diff children additions/removals
      $.each(currentState[i].childrenIDs, function(index, value) {
        if(prevState[i].childrenIDs.indexOf(value) == -1) {
          console.log("Added child to: ", dom, "Child: ", currentState[i].children[index]);
        }
      });
      $.each(prevState[i].childrenIDs, function(index, value) {
        if(currentState[i].childrenIDs.indexOf(value) == -1) {
          console.log("Removed child from: ", dom, "Child: ", prevState[i].children[index]);
        }
      });
    }

    console.log("Tested " + testsRan + " properties for differences.");

    // CLean out UIDs and reset the diff capture
    ns.prevState = null;
    ns.domGUID = null;

    $('body').contents().each(function cleanNodes() {
    	var jqNode = $(this);
    	this.domDeltaID = null;
    	if(jqNode.contents().length > 0) jqNode.contents().each(cleanNodes);
    });
  }

  else {
    console.log("First frame captured, run again after making some changes to see diff");
    ns.prevState = currentState;
  	ns.domGUID = domGUID;
  }

})(window.top);
<commit_msg>Group changes by DOM element to reduce noise<commit_after>(function(ns) {
  var prevState = ns.prevState || [];
  var currentState = [];
  var domGUID = ns.domGUID = ns.domGUID || 0;
  var nodeTypes = [];

  $('body').contents().each(function processNodes() {
    var selfNode = this;
    var jqThis = $(this);
    var val = "";
    var childs = [];
    var childIDs = [];
    var thisUID = -1;

    if(this.domDeltaID) { thisUID = this.domDeltaID; }
    else {
      thisUID = this.domDeltaID = ns.domGUID++;
      val += "ADDED NODE: " + this.domDeltaID + "; ";
    }

    if(nodeTypes.indexOf(this.nodeType) == -1) nodeTypes.push(this.nodeType);

    var tempstyle = window.getComputedStyle(this);
    var style = null;

    // Deep copy the computed style in case the function returns the same object
    if(tempstyle) {
      style = {};
      $.each(tempstyle, function(key, value) {
        style[key] = value;
      });
    }

    var attrNames = null;
    var attrVals = null;

    // Gather attributes
    if(this.attributes) {
    	attrNames = [];
    	attrVals = [];

    	for (var i = 0; i < this.attributes.length; i++) {
		  var attrib = this.attributes[i];
		  if (attrib.specified) {
		  	attrNames.push(attrib.name);
		  	attrVals.push(attrib.value);
		  }
		}
    }

    var styleNames = null;
    var styleVals = null;

    // Gather attributes
    if(this.style) {
    	styleNames = [];
    	styleVals = [];

    	for (var sName in this.style) {
		  	styleNames.push(sName);
		  	styleVals.push(this.style[sName]);
		}
    }

    if(jqThis.contents().length > 0) {
      // Make sure children are processed first so we can get a UID for each of them
      jqThis.contents().each(processNodes);

      jqThis.contents().each(function() {
        childs.push(this);
        childIDs.push(this.domDeltaID);
      });
    }

    // Record the state of affairs for the node
    currentState[thisUID] = {style: style, children:childs, childrenIDs:childIDs, dom:this, styleNames:styleNames, styleVals:styleVals, attrNames:attrNames, attrVals:attrVals, classList: this.className ? this.className.split(' ') : null };
  });

  // console.log("NodeTypes", nodeTypes);
  // console.log("Previous State", ns.prevState);
  // console.log("Current State", currentState);

  if(prevState.length > 0) {
    var testsRan = 0;
    console.log("Calculating Diff...");
    for(var i=0,end=currentState.length; i!=end; ++i) {
      // See if the UID exists in the prev state
      if(!(i in prevState)) {
        console.log("Added element: ", currentState[i]);
        continue;
      }

      if(currentState[i]) {}
      else { console.log("POSSIBLY REMOVED: Undefined current state element"); continue; }

      var dom = currentState[i].dom;
      var style = currentState[i].style;
      var prevStyle = prevState[i].style;
      var classList = currentState[i].classList;
      var prevClassList = prevState[i].classList;
      var attrNames = currentState[i].attrNames;
      var prevAttrNames = prevState[i].attrNames;
      var attrVals = currentState[i].attrVals;
      var prevAttrVals = prevState[i].attrVals;
      var styleNames = currentState[i].styleNames;
      var prevStyleNames = prevState[i].styleNames;
      var styleVals = currentState[i].styleVals;
      var prevStyleVals = prevState[i].styleVals;
      var changelist = [];

      // Find class add/removals
      if(classList) {
      	if(prevClassList) {
      		// Adds
      		$.each(classList, function(index, className) {
      			if(className.trim().length > 0) {
	      			if(prevClassList.indexOf(className) == -1) {
	      				changelist.push["Added class to: ", dom, "Class: ", className];
	      			}
      			}
      		});
      		// Removes
      		$.each(prevClassList, function(index, className) {
      			if(className.trim().length > 0) {
	      			if(classList.indexOf(className) == -1) {
	      				changelist.push["Removed class from: ", dom, "Class: ", className];
	      			}
      			}
      		});
      	}

      	else {
      		changelist.push["Added classes to: ", dom, "Classes: ", classList];
      	}
      }

      else {
      	if(prevClassList) {
      		changelist.push["Removed classes from: ", dom, "Classes: ", classList];
      	}
      }

      // Find attribute add/remove/change
      if(attrNames) {
      	if(prevAttrNames) {
      		// Adds/changes
      		$.each(attrNames, function(index, attrObj) {
      			// Adds
      			if(prevAttrNames.indexOf(attrObj) == -1) {
      				changelist.push["Added attribute to: ", dom, "Attribute: ", attrObj];
      			}

      			// Changes
      			else {
      				if(attrVals[index] != prevAttrVals[index]) {
      					changelist.push["Changed attribute on: ", dom, "Prev: ", prevAttrVals[index], "New: ", attrVals[index]];
      				}
      			}
      		});
      		// Removes
      		$.each(prevAttrNames, function(index, attrObj) {
      			if(attrNames.indexOf(attrObj) == -1) {
      				changelist.push["Removed attribute from: ", dom, "Attribute: ", attrObj];
      			}
      		});
      	}

      	else {
      		changelist.push["Added attributes to: ", dom, "Attributes: ", attrNames, attrVals];
      	}
      }

      else {
      	if(prevAttrNames) {
      		changelist.push["Removed attributes from: ", dom, "Attributes: ", prevAttrNames];
      	}
      }

      // Find style add/remove/change
      if(styleNames) {
      	if(prevStyleNames) {
      		// Adds/changes
      		$.each(styleNames, function(index, styleObj) {
      			// Adds
      			if(prevStyleNames.indexOf(styleObj) == -1) {
      				changelist.push["Added style to: ", dom, "Style: ", styleObj];
      			}

      			// Changes
      			else {
      				if(styleVals[index] != prevStyleVals[index]) {
      					changelist.push["Changed style:", styleObj, "on:", dom, "Prev:", prevStyleVals[index], "New:", styleVals[index]];
      				}
      			}

      			testsRan++;
      		});
      		// Removes
      		$.each(prevStyleNames, function(index, styleObj) {
      			if(styleNames.indexOf(styleObj) == -1) {
      				changelist.push["Removed style from: ", dom, "Style: ", styleObj];
      			}
      		});
      	}

      	else {
      		changelist.push["Added styles to: ", dom, "Styles: ", styleNames, styleVals];
      	}
      }

      else {
      	if(prevStyleNames) {
      		changelist.push["Removed styles from: ", dom, "Styles: ", prevStyleNames];
      	}
      }

      // Make sure a style was generated for our item in question
      if(style && prevStyle) {
        // Find changed and added properties
        $.each(style, function(key, value) {
          if(key in prevStyle) {
            if((prevStyle[key] != style[key])) {
              changelist.push["DOM Node:", dom, "Property", key, "PREV: ", prevStyle[key], "NEW: ", style[key]];
            }
          }

          else {
            changelist.push["DOM Node:", dom, "New Property", key, "NEW: ", style[key]];
          }

          testsRan++;
        });

        // Find removed properties
        $.each(prevStyle, function(key, value) {
          if(!(key in style)) {
            changelist.push["DOM Node:", dom, "Removed Property", key, "NEW: ", style[key]];
          }
        });
      }

      // Now diff children additions/removals
      $.each(currentState[i].childrenIDs, function(index, value) {
        if(prevState[i].childrenIDs.indexOf(value) == -1) {
          changelist.push["Added child to: ", dom, "Child: ", currentState[i].children[index]];
        }
      });
      $.each(prevState[i].childrenIDs, function(index, value) {
        if(currentState[i].childrenIDs.indexOf(value) == -1) {
          changelist.push["Removed child from: ", dom, "Child: ", prevState[i].children[index]];
        }
      });

      console.log("ELEMENT:", dom, "CHANGES", changelist);
    }

    console.log("Tested " + testsRan + " properties for differences.");

    // CLean out UIDs and reset the diff capture
    ns.prevState = null;
    ns.domGUID = null;

    $('body').contents().each(function cleanNodes() {
    	var jqNode = $(this);
    	this.domDeltaID = null;
    	if(jqNode.contents().length > 0) jqNode.contents().each(cleanNodes);
    });
  }

  else {
    console.log("First frame captured, run again after making some changes to see diff");
    ns.prevState = currentState;
  	ns.domGUID = domGUID;
  }

})(window.top);
<|endoftext|>


<commit_before>/**
 * Multiselect search
 *
 * Copyright (c) 2011 Raul Raat
 * Dual licensed under the MIT and GPL licenses:
 * http://www.opensource.org/licenses/mit-license.php
 * http://www.gnu.org/licenses/gpl.html
 */
(function(){
	var ctrl_key_down = false,
		initialized = false;

	/**
	* @see http://www.webmasterworld.com/javascript/3304115.htm
	*/
	function insertafter(newChild, refChild) {
		refChild.parentNode.insertBefore(newChild, refChild.nextSibling);
	}

	/**
	* @see http://www.quirksmode.org/js/eventSimple.html
	*/
	function addEventSimple(obj, evt, fn) {
		if (obj.addEventListener) {
			obj.addEventListener(evt, fn, false);
		} else if (obj.attachEvent) {
			obj.attachEvent('on' + evt, fn);
		}
	}

	function init() {
		// mark ctrl key as either up or down
		// TODO: this is broken in IE atm (but workarounded in select-onchange event)
		addEventSimple(window, 'keydown', function (e) {
			var k = e.keyCode || e.which;
			if (k === 17) {
				ctrl_key_down = true;
			}
		});
		addEventSimple(window, 'keyup', function (e) {
			var k = e.keyCode || e.which;
			if (k === 17) {
				ctrl_key_down = false;
			}
		});
	}

	window.multiselect_search = function (ob, settings) {
		if (!ob || !ob.nodeName || ob.nodeName.toString().toLowerCase() !== 'select' || !ob.multiple) {
			// do nothing if given element isn't multiple select
			return;
		}

		if (!initialized) {
			init();
			initialized = true;
		}

		settings = settings || {};
		settings.match = settings.match || function (searchterm, item) {return !!item.match(new RegExp(searchterm, "ig"));};

		function get_list(ob) {
			var i,
				cnodes = ob.childNodes,
				list = [];
			function new_list_element(node) {
				var text = cnodes[i].innerHTML,
					new_node = document.createElement('option');

				new_node.innerHTML = text;
				new_node.selected = node.selected;

				return {
					text: text,
					o_node: node,
					n_node: new_node,
					visible: true
				};
			}
			for (i in cnodes) {
				// NOTE: For IE there is no hasOwnProperty method for childNodes
				if (!cnodes.hasOwnProperty || cnodes.hasOwnProperty(i)) {
					if (cnodes[i].nodeName && cnodes[i].nodeName.toString().toLowerCase() === 'option') {
						list[list.length] = new_list_element(cnodes[i]);
					}
				}
			}
			return list;
		}

		var list = get_list(ob),
			// container div for multiselect_search
			div = document.createElement('div'),
			// the input area to search select options
			searchbox = document.createElement('input'),
			// new select where we add/remove options form
			select = document.createElement('select'),
			last_search = '',
			i;

		function clearSelect() {
			while (select.hasChildNodes()) {
				select.removeChild(select.firstChild);
			}
		}

		function search() {
			// NOTE: don't use "this" as for IE this is window for others input element
			var term = searchbox.value,
				i;
			if (term === last_search) {
				return;
			}
			last_search = term;
			clearSelect();
			for (i in list) {
				if (list.hasOwnProperty(i)) {
					if (settings.match(term, list[i].text)) {
						select.appendChild(list[i].n_node);
						list[i].visible = true;
					} else {
						list[i].visible = false;
					}
				}
			}
		}

		searchbox.type = 'text';
		if (settings.searchbox_class) {
			searchbox.className = settings.searchbox_class;
		}
		addEventSimple(searchbox, 'keyup', search);

		select.multiple = true;
		if (ob.className) {
			select.className = ob.className;
		}
		for (i in list) {
			if (list.hasOwnProperty(i)) {
				select.appendChild(list[i].n_node);
			}
		}

		addEventSimple(select, 'change', function (e) {
			// only IE has propery ctrlKey for change event
			var i;
			if (e.ctrlKey === true || e.ctrlKey === false) {
				ctrl_key_down = e.ctrlKey;
			}
			for (i in list) {
				if (list.hasOwnProperty(i)) {
					if (!ctrl_key_down && list[i].visible == false) {
						list[i].o_node.selected = list[i].n_node.selected = false;
					} else {
						list[i].o_node.selected = list[i].n_node.selected;
					}
				}
			}
		});

		if (settings.container_id) {
			div.id = settings.container_id;
		}
		if (settings.container_class) {
			div.className = settings.container_class;
		}
		div.appendChild(searchbox);
		div.appendChild(document.createElement('br'));
		div.appendChild(select);

		ob.style.display = 'none';
		insertafter(div, ob);
	}
})();<commit_msg>ony remove childs that don't match searchterm<commit_after>/**
 * Multiselect search
 *
 * Copyright (c) 2011 Raul Raat
 * Dual licensed under the MIT and GPL licenses:
 * http://www.opensource.org/licenses/mit-license.php
 * http://www.gnu.org/licenses/gpl.html
 */
(function(){
	var ctrl_key_down = false,
		initialized = false;

	/**
	* @see http://www.webmasterworld.com/javascript/3304115.htm
	*/
	function insertafter(newChild, refChild) {
		refChild.parentNode.insertBefore(newChild, refChild.nextSibling);
	}

	/**
	* @see http://www.quirksmode.org/js/eventSimple.html
	*/
	function addEventSimple(obj, evt, fn) {
		if (obj.addEventListener) {
			obj.addEventListener(evt, fn, false);
		} else if (obj.attachEvent) {
			obj.attachEvent('on' + evt, fn);
		}
	}

	function init() {
		// mark ctrl key as either up or down
		// TODO: this is broken in IE atm (but workarounded in select-onchange event)
		addEventSimple(window, 'keydown', function (e) {
			var k = e.keyCode || e.which;
			if (k === 17) {
				ctrl_key_down = true;
			}
		});
		addEventSimple(window, 'keyup', function (e) {
			var k = e.keyCode || e.which;
			if (k === 17) {
				ctrl_key_down = false;
			}
		});
	}

	window.multiselect_search = function (ob, settings) {
		if (!ob || !ob.nodeName || ob.nodeName.toString().toLowerCase() !== 'select' || !ob.multiple) {
			// do nothing if given element isn't multiple select
			return;
		}

		if (!initialized) {
			init();
			initialized = true;
		}

		settings = settings || {};
		settings.match = settings.match || function (searchterm, item) {return !!item.match(new RegExp(searchterm, "ig"));};

		function get_list(ob) {
			var i,
				cnodes = ob.childNodes,
				list = [];
			function new_list_element(node) {
				var text = cnodes[i].innerHTML,
					new_node = document.createElement('option');

				new_node.innerHTML = text;
				new_node.selected = node.selected;

				return {
					text: text,
					o_node: node,
					n_node: new_node,
					visible: true
				};
			}
			for (i in cnodes) {
				// NOTE: For IE there is no hasOwnProperty method for childNodes
				if (!cnodes.hasOwnProperty || cnodes.hasOwnProperty(i)) {
					if (cnodes[i].nodeName && cnodes[i].nodeName.toString().toLowerCase() === 'option') {
						list[list.length] = new_list_element(cnodes[i]);
					}
				}
			}
			return list;
		}

		var list = get_list(ob),
			// container div for multiselect_search
			div = document.createElement('div'),
			// the input area to search select options
			searchbox = document.createElement('input'),
			// new select where we add/remove options form
			select = document.createElement('select'),
			last_search = '',
			i;

		function search() {
			// NOTE: don't use "this" as for IE this is window for others input element
			var term = searchbox.value,
				i;
			if (term === last_search) {
				return;
			}
			last_search = term;

			for (i in list) {
				if (list.hasOwnProperty(i)) {
					if (settings.match(term, list[i].text)) {
						// always attach all matching options
						// this keeps them in the original order
						select.appendChild(list[i].n_node);
						list[i].visible = true;
					} else if (list[i].visible) {
						select.removeChild(list[i].n_node);
						list[i].visible = false;
					}
				}
			}
		}

		searchbox.type = 'text';
		if (settings.searchbox_class) {
			searchbox.className = settings.searchbox_class;
		}
		addEventSimple(searchbox, 'keyup', search);

		select.multiple = true;
		if (ob.className) {
			select.className = ob.className;
		}
		for (i in list) {
			if (list.hasOwnProperty(i)) {
				select.appendChild(list[i].n_node);
			}
		}

		addEventSimple(select, 'change', function (e) {
			// only IE has propery ctrlKey for change event
			var i;
			if (e.ctrlKey === true || e.ctrlKey === false) {
				ctrl_key_down = e.ctrlKey;
			}
			for (i in list) {
				if (list.hasOwnProperty(i)) {
					if (!ctrl_key_down && list[i].visible == false) {
						list[i].o_node.selected = list[i].n_node.selected = false;
					} else {
						list[i].o_node.selected = list[i].n_node.selected;
					}
				}
			}
		});

		if (settings.container_id) {
			div.id = settings.container_id;
		}
		if (settings.container_class) {
			div.className = settings.container_class;
		}
		div.appendChild(searchbox);
		div.appendChild(document.createElement('br'));
		div.appendChild(select);

		ob.style.display = 'none';
		insertafter(div, ob);
	}
})();<|endoftext|>


<commit_before>var h = require('hyperscript')
var u = require('patchbay/util')
var pull = require('pull-stream')
var Scroller = require('pull-scroll')

var plugs = require('patchbay/plugs')
var sbot_log = plugs.first(exports.sbot_log = [])
var data_render = plugs.first(exports.data_render = [])

exports.screen_view = function (path, sbot) {
  if(path === '/data-feed') {
    var content = h('div.column.scroller__content')
    var div = h('div.column.scroller',
      {style: {'overflow':'auto'}},
      h('div.scroller__wrapper',
        content
      )
    )

    pull(
      u.next(sbot_log, {old: false, limit: 100}),
      Scroller(div, content, data_render, true, false)
    )

    pull(
      u.next(sbot_log, {reverse: true, limit: 100, live: false}),
      Scroller(div, content, data_render, false, false)
    )

    return div
  }
}
<commit_msg>also allow `/data` to access raw data feed<commit_after>var h = require('hyperscript')
var u = require('patchbay/util')
var pull = require('pull-stream')
var Scroller = require('pull-scroll')

var plugs = require('patchbay/plugs')
var sbot_log = plugs.first(exports.sbot_log = [])
var data_render = plugs.first(exports.data_render = [])

exports.screen_view = function (path, sbot) {
  if(path === '/data-feed' || path === '/data') {
    var content = h('div.column.scroller__content')
    var div = h('div.column.scroller',
      {style: {'overflow':'auto'}},
      h('div.scroller__wrapper',
        content
      )
    )

    pull(
      u.next(sbot_log, {old: false, limit: 100}),
      Scroller(div, content, data_render, true, false)
    )

    pull(
      u.next(sbot_log, {reverse: true, limit: 100, live: false}),
      Scroller(div, content, data_render, false, false)
    )

    return div
  }
}
<|endoftext|>


<commit_before>const
    Complex = require('../index.js').Complex,
    should = require('should');

describe('Complex', function() {
  var c;

  beforeEach(function() {
    c = new Complex(3, -4);
  });

  it('#toString() should convert object to string', function() {
    c.toString().should.equal("(3,-4)");
  });

  it('has a property `real`', function() {
    c.should.have.property('real');
    c.real.should.equal(3);
    c.real = 7;
    c.real.should.equal(7);
    c.toString().should.equal("(7,-4)");
  });

  it('has a property `imag`', function() {
    c.should.have.property('imag');
    c.imag.should.equal(-4);
    c.imag = 2;
    c.imag.should.equal(2);
    c.toString().should.equal("(3,2)");
  });

  it('#abs() should return the absolute value of the complex number', function() {
    c.abs.should.be.a.Function;
    c.abs().should.equal(5);
  });

  it('#arg() should return the phase angle (or angular component) of the complex number, expressed in radians', function() {
    c.arg.should.be.a.Function;
    c.arg().should.equal(-0.9272952180016122);
    (c.abs() * Math.cos(c.arg())).should.approximately(3, 0.0000001);
    (c.abs() * Math.sin(c.arg())).should.approximately(-4, 0.0000001);
  });

  it('#norm() should return the norm value of the complex number', function() {
    c.norm.should.be.a.Function;
    c.norm().should.equal(25);
  });

  it('#conj() should return the conjugate of the complex number', function() {
    c.conj.should.be.a.Function;
    c.conj().toString().should.equal("(3,4)");
  });

  it('#polar() should returns a complex object (in cartesian format) corresponding to the complex number defined by its polar components rho and theta, where rho is the magnitude (modulus) and theta is the phase angle', function() {
    Complex.polar.should.be.a.Function;
    var rho = 5;
    var theta = -0.9272952180016122;
    c = Complex.polar(rho, theta);
    c.toString().should.equal("(5,-0.927295)");
    (c.real * Math.cos(c.imag)).should.approximately(3, 0.0000001);
    (c.real * Math.sin(c.imag)).should.approximately(-4, 0.0000001);
  });

  it('#cos() should return the cosine of the complex number', function() {
    Complex.cos.should.be.a.Function;
    Complex.cos(c).toString().should.equal("(-27.0349,3.85115)");
  });

  it('#cosh() should return the hyperbolic cosine of the complex number', function() {
    Complex.cosh.should.be.a.Function;
    Complex.cosh(c).toString().should.equal("(-6.58066,7.58155)");
    c = Complex(0, 0);
    Complex.cosh(c).toString().should.equal("(1,0)");
    c = Complex(1, 0);
    Complex.cosh(c).toString().should.equal("(1.54308,0)");
    c = Complex(-1, 0);
    Complex.cosh(c).toString().should.equal("(1.54308,-0)");
  });

  it('#exp() should return the base-e exponential of the complex number', function() {
    Complex.exp.should.be.a.Function;
    Complex.exp(c).toString().should.equal("(-13.1288,15.2008)");
    c = Complex(-1, 0);
    Complex.cosh(c).toString().should.equal("(1.54308,-0)");
    c = Complex(0, 0);
    Complex.cosh(c).toString().should.equal("(1,0)");
    c = Complex(1, 0);
    Complex.cosh(c).toString().should.equal("(1.54308,0)");
  });
});
<commit_msg>test: fixed some mistakes<commit_after>const
    Complex = require('../index.js').Complex,
    should = require('should');

describe('Complex', function() {
  var c;

  beforeEach(function() {
    c = new Complex(3, -4);
  });

  it('#toString() should convert object to string', function() {
    c.toString().should.equal("(3,-4)");
  });

  it('has a property `real`', function() {
    c.should.have.property('real');
    c.real.should.equal(3);
    c.real = 7;
    c.real.should.equal(7);
    c.toString().should.equal("(7,-4)");
  });

  it('has a property `imag`', function() {
    c.should.have.property('imag');
    c.imag.should.equal(-4);
    c.imag = 2;
    c.imag.should.equal(2);
    c.toString().should.equal("(3,2)");
  });

  it('#abs() should return the absolute value of the complex number', function() {
    c.abs.should.be.a.Function;
    c.abs().should.equal(5);
  });

  it('#arg() should return the phase angle (or angular component) of the complex number, expressed in radians', function() {
    c.arg.should.be.a.Function;
    c.arg().should.equal(-0.9272952180016122);
    (c.abs() * Math.cos(c.arg())).should.approximately(3, 0.0000001);
    (c.abs() * Math.sin(c.arg())).should.approximately(-4, 0.0000001);
  });

  it('#norm() should return the norm value of the complex number', function() {
    c.norm.should.be.a.Function;
    c.norm().should.equal(25);
  });

  it('#conj() should return the conjugate of the complex number', function() {
    c.conj.should.be.a.Function;
    c.conj().toString().should.equal("(3,4)");
  });

  it('#polar() should returns a complex object (in cartesian format) corresponding to the complex number defined by its polar components rho and theta, where rho is the magnitude (modulus) and theta is the phase angle', function() {
    Complex.polar.should.be.a.Function;
    var rho = 5;
    var theta = -0.9272952180016122;
    c = Complex.polar(rho, theta);
    c.toString().should.equal("(5,-0.927295)");
    (c.real * Math.cos(c.imag)).should.approximately(3, 0.0000001);
    (c.real * Math.sin(c.imag)).should.approximately(-4, 0.0000001);
  });

  it('#cos() should return the cosine of the complex number', function() {
    Complex.cos.should.be.a.Function;
    Complex.cos(c).toString().should.equal("(-27.0349,3.85115)");
  });

  it('#cosh() should return the hyperbolic cosine of the complex number', function() {
    Complex.cosh.should.be.a.Function;
    Complex.cosh(c).toString().should.equal("(-6.58066,7.58155)");
    c = Complex(0, 0);
    Complex.cosh(c).toString().should.equal("(1,0)");
    c = Complex(1, 0);
    Complex.cosh(c).toString().should.equal("(1.54308,0)");
    c = Complex(-1, 0);
    Complex.cosh(c).toString().should.equal("(1.54308,-0)");
  });

  it('#exp() should return the base-e exponential of the complex number', function() {
    Complex.exp.should.be.a.Function;
    Complex.exp(c).toString().should.equal("(-13.1288,15.2008)");
    c = Complex(-1, 0);
    Complex.exp(c).toString().should.equal("(0.367879,0)");
    c = Complex(0, 0);
    Complex.exp(c).toString().should.equal("(1,0)");
    c = Complex(1, 0);
    Complex.exp(c).toString().should.equal("(2.71828,0)");
  });
});
<|endoftext|>