<commit_before>// Copyright (c) Martin Costello, 2017. All rights reserved.
// Licensed under the Apache 2.0 license. See the LICENSE file in the project root for full license information.

"use strict";

var constants = require("./constants");
var responses = require("./responses");
var cancelIntent = require("./intents/cancel");
var commuteIntent = require("./intents/commute");
var disruptionIntent = require("./intents/disruption");
var helpIntent = require("./intents/help");
var statusIntent = require("./intents/status");
var stopIntent = require("./intents/stop");
var telemetry = require("./telemetry");

var skill = {
  dictionary: {
    "LINE_NAMES": [
      "Bakerloo",
      "Central",
      "Circle",
      "District",
      "DLR",
      "Hammersmith and City",
      "Jubilee",
      "London Overground",
      "Metropolitan",
      "Northern",
      "Piccadilly",
      "Victoria",
      "Waterloo and City"
    ]
  },
  name: constants.appName,
  onError: function (exception, request, response) {

    console.error("Unhandled exception: ", exception);

    telemetry.trackException(exception, {
      sessionId: request.sessionId,
      userId: request.userId
    });

    response.say(responses.onError);
  },
  onLaunch: function (request, response) {

    telemetry.trackEvent("LaunchRequest", {
      sessionId: request.sessionId,
      userId: request.userId
    });

    response
      .say(responses.onLaunch)
      .shouldEndSession(false);
  },
  onSessionEnded: function (request, response) {

    telemetry.trackEvent("SessionEndedRequest", {
      sessionId: request.sessionId,
      userId: request.userId
    });

    response.say(responses.onSessionEnded);
  },
  preReqest: function (request, response, type) {

    console.info("Handling request.", JSON.stringify({
      request: request.data.request,
      sessionId: request.sessionId,
      userId: request.userId
    }));

    if (process.env.VERIFY_SKILL_ID && request.applicationId !== (process.env.SKILL_ID || null)) {
      console.error("Request application Id and configured skill Id mismatch.", request.applicationId, process.env.SKILL_ID);
      response.fail("Invalid application Id.");
    }
  },
  postResponse: function (request, response, type, exception) {
    console.info("Handled request.", JSON.stringify({
      request: request.data.request,
      sessionId: request.sessionId,
      userId: request.userId,
      exception: exception
    }));
  },
  setMessages: function (app) {
    app.messages.GENERIC_ERROR = responses.onError;
    app.messages.INVALID_REQUEST_TYPE = responses.onInvalidRequest;
    app.messages.NO_AUDIO_PLAYER_EVENT_HANDLER_FOUND = responses.noAudioPlayer;
    app.messages.NO_INTENT_FOUND = responses.noIntent;
    app.messages.NO_LAUNCH_FUNCTION = responses.noIntent;
    app.messages.NO_SESSION = responses.noSession;
  },
  intents: [
    cancelIntent,
    commuteIntent,
    disruptionIntent,
    helpIntent,
    statusIntent,
    stopIntent
  ]
};

module.exports = skill;
<commit_msg>Add TfL Rail to LINE_NAMES<commit_after>// Copyright (c) Martin Costello, 2017. All rights reserved.
// Licensed under the Apache 2.0 license. See the LICENSE file in the project root for full license information.

"use strict";

var constants = require("./constants");
var responses = require("./responses");
var cancelIntent = require("./intents/cancel");
var commuteIntent = require("./intents/commute");
var disruptionIntent = require("./intents/disruption");
var helpIntent = require("./intents/help");
var statusIntent = require("./intents/status");
var stopIntent = require("./intents/stop");
var telemetry = require("./telemetry");

var skill = {
  dictionary: {
    "LINE_NAMES": [
      "Bakerloo",
      "Central",
      "Circle",
      "District",
      "DLR",
      "Hammersmith and City",
      "Jubilee",
      "London Overground",
      "Metropolitan",
      "Northern",
      "Piccadilly",
      "TfL Rail",
      "Victoria",
      "Waterloo and City"
    ]
  },
  name: constants.appName,
  onError: function (exception, request, response) {

    console.error("Unhandled exception: ", exception);

    telemetry.trackException(exception, {
      sessionId: request.sessionId,
      userId: request.userId
    });

    response.say(responses.onError);
  },
  onLaunch: function (request, response) {

    telemetry.trackEvent("LaunchRequest", {
      sessionId: request.sessionId,
      userId: request.userId
    });

    response
      .say(responses.onLaunch)
      .shouldEndSession(false);
  },
  onSessionEnded: function (request, response) {

    telemetry.trackEvent("SessionEndedRequest", {
      sessionId: request.sessionId,
      userId: request.userId
    });

    response.say(responses.onSessionEnded);
  },
  preReqest: function (request, response, type) {

    console.info("Handling request.", JSON.stringify({
      request: request.data.request,
      sessionId: request.sessionId,
      userId: request.userId
    }));

    if (process.env.VERIFY_SKILL_ID && request.applicationId !== (process.env.SKILL_ID || null)) {
      console.error("Request application Id and configured skill Id mismatch.", request.applicationId, process.env.SKILL_ID);
      response.fail("Invalid application Id.");
    }
  },
  postResponse: function (request, response, type, exception) {
    console.info("Handled request.", JSON.stringify({
      request: request.data.request,
      sessionId: request.sessionId,
      userId: request.userId,
      exception: exception
    }));
  },
  setMessages: function (app) {
    app.messages.GENERIC_ERROR = responses.onError;
    app.messages.INVALID_REQUEST_TYPE = responses.onInvalidRequest;
    app.messages.NO_AUDIO_PLAYER_EVENT_HANDLER_FOUND = responses.noAudioPlayer;
    app.messages.NO_INTENT_FOUND = responses.noIntent;
    app.messages.NO_LAUNCH_FUNCTION = responses.noIntent;
    app.messages.NO_SESSION = responses.noSession;
  },
  intents: [
    cancelIntent,
    commuteIntent,
    disruptionIntent,
    helpIntent,
    statusIntent,
    stopIntent
  ]
};

module.exports = skill;
<|endoftext|>


<commit_before>var async = require('async'),
    assert = require('assert'),
    engines = {};

function sum(a, b) {
  return a + b;
}
function getImageStats(images) {
  // Pluck the width and heights of the images
  var imgHeights = images.map(function (img) {
        return img.height;
      }),
      imgWidths = images.map(function (img) {
        return img.width;
      });

  // Determine the maximums and totals
  var retVal = {
    'heights': imgHeights,
    'widths': imgWidths,
    'maxHeight': Math.max.apply(Math, imgHeights),
    'maxWidth': Math.max.apply(Math, imgWidths),
    'totalHeight': imgHeights.reduce(sum, 0),
    'totalWidth': imgWidths.reduce(sum, 0)
  };

  // Return all the info
  return retVal;
}

function Smithy(engine) {
  this.engine = engine;
}
Smithy.prototype = {
  // Create an image from a file via the engine
  'createImage': function (file, cb) {
    var engine = this.engine;
    async.waterfall([
      function createImage (cb) {
        engine.createImage(file, cb);
      },
      function savePath (img, cb) {
        // Save the buffer path to the image
        img._filepath = file;

        // Callback with the image
        cb(null, img);
      }
    ], cb);
  },
  // Sugar function for creating multiple images
  'createImages': function (files, cb) {
    // Map the files into their image counterparts
    async.map(files, this.createImage.bind(this), cb);
  },
  // Collector for image stats
  'getImageStats': getImageStats,
  // Helper to create canvas via engine
  'createCanvas': function (width, height, cb) {
    var engine = this.engine;
    return engine.createCanvas(width, height, cb);
  },
  'packCanvas': function (canvas, algorithm, cb) {

  }
};

/**
 * Spritesmith generation function
 * @param {Object} params Parameters for spritesmith
 * @param {String[]} [params.src] Images to generate into sprite sheet
 * @param {String} [params.engine="auto"] Engine to use (canvas, gm, or user-defined via Spritesmith.addEngine)
 * TODO: engineOpts is not yet available
 * @param {String} [params.algorithm] Algorithm to pack images with (vertical or user-defined via Spritesmith.addAlgorithm)
 * @param {Mixed} [params.engineOpts] Options to pass through to engine
 * @param {Function} callback Function that receives compiled spritesheet and map
 */
function Spritesmith(params, callback) {
  var retObj = {},
      files = params.src,
      enginePref = params.engine || 'auto',
      engine = engines[enginePref];

  // If the engine is not defined
  if (engine === undefined) {
    // If the engine was not auto, inform the user
    assert.strictEqual(enginePref, 'auto', 'Sorry, the spritesmith engine \'' + enginePref + '\' could not be loaded. Please be sure you have installed it properly on your machine.');

    // Begin attempting to load the engines
    engine = engines.canvas || engines.gm;

    // Assert there is an engine
    assert(engine, 'Sorry, no spritesmith engine could be loaded for your machine. Please be sure you have installed canvas or gm.');
  }

  var smith = new Smithy(engine);

  // In a waterfall fashion
  async.waterfall([
    function grabImages (cb) {
      // Map the files into their image counterparts
      smith.createImages(files, cb);
    },
    // Then, create a canvas and the files to it
    function smithAddFiles (images, cb) {
      // TODO: Predict the optimum size canvas
      var imgStats = smith.getImageStats(images),
          maxWidth = imgStats.maxWidth,
          totalHeight = imgStats.totalHeight;

      // Create a canvas
      async.waterfall([
        function createCanvasFn (cb) {
          smith.createCanvas(maxWidth, totalHeight, cb);
        },
        function addImagesFn (canvas, cb) {
          var currentHeight = 0,
              coords = {};

          // Add the images to the canvas
          // TODO: Use a better algorithm
          // TODO: Should this be async.each
          images.forEach(function (img) {
            // Save the image properties
            var x = 0,
                y = currentHeight,
                imgWidth = img.width,
                imgHeight = img.height;

            // Draw the image at the current height
            canvas.addImage(img, x, y);

            // Add the img.height to the current height
            currentHeight += imgHeight;

            // Save the coordinates for this image
            coords[img._filepath] = {
              'x': x,
              'y': y,
              'height': imgHeight,
              'width': imgWidth
            };
          });

          // Save the coordinates to retObj
          retObj.coordinates = coords;

          // Callback with the canvas
          cb(null, canvas);
        }
      ], cb);
    },
    // Then, callback with the output canvas
    function smithOutputCanvas (canvas, cb) {
      async.waterfall([
        // Export the canvas as a png
        function exportCanvas (cb) {
          canvas['export']('png', cb);
        },
        function saveImageToRetObj(imgStr, cb) {
          // Save the image to the retObj
          retObj.image = imgStr;

          // Callback
          cb(null);
        }
      ], cb);
    },
    function smithCallbackData (cb) {
      // Callback with the return object
      cb(null, retObj);
    }
  ], callback);
}

/**
 * Method to add new engines via
 * @param {String} name Name of engine
 * @param {Function} engine Engine to bind under name
 */
function addEngine(name, engine) {
  engines[name] = engine;
}
Spritesmith.addEngine = addEngine;

// Attempt to load canvas and imagemagick
var canvasEngine,
    gmEngine;
try {
  canvasEngine = require('./engines/canvas');
} catch (e) {}

try {
  gmEngine = require('./engines/gm');
} catch (e) {}

if (canvasEngine) { addEngine('canvas', canvasEngine); }
if (gmEngine) { addEngine('gm', gmEngine); }

// Export Spritesmith
module.exports = Spritesmith;<commit_msg>Broke it a bit but I am liking the refactor<commit_after>var async = require('async'),
    assert = require('assert'),
    engines = {};

function sum(a, b) {
  return a + b;
}
function getImageStats(images) {
  // Pluck the width and heights of the images
  var imgHeights = images.map(function (img) {
        return img.height;
      }),
      imgWidths = images.map(function (img) {
        return img.width;
      });

  // Determine the maximums and totals
  var retVal = {
    'heights': imgHeights,
    'widths': imgWidths,
    'maxHeight': Math.max.apply(Math, imgHeights),
    'maxWidth': Math.max.apply(Math, imgWidths),
    'totalHeight': imgHeights.reduce(sum, 0),
    'totalWidth': imgWidths.reduce(sum, 0)
  };

  // Return all the info
  return retVal;
}

function EngineSmithy(engine) {
  this.engine = engine;
}
EngineSmithy.prototype = {
  // Create an image from a file via the engine
  'createImage': function (file, cb) {
    var engine = this.engine;
    async.waterfall([
      function createImage (cb) {
        engine.createImage(file, cb);
      },
      function savePath (img, cb) {
        // Save the buffer path to the image
        img._filepath = file;

        // Callback with the image
        cb(null, img);
      }
    ], cb);
  },
  // Sugar function for creating multiple images
  'createImages': function (files, cb) {
    // Map the files into their image counterparts
    async.map(files, this.createImage.bind(this), cb);
  },
  // Collector for image stats
  'getImageStats': getImageStats,
  // Helper to create canvas via engine
  'createCanvas': function (width, height, cb) {
    var engine = this.engine;
    return engine.createCanvas(width, height, cb);
  }
};

function CanvasSmithy(algorithm) {
  this.images = {};

  // TODO: Load in via .addAlgorithm
  this.algorithm = function (name, img) {
    var y = this.y || 0,
        imgHeight = imgHeight;

    // The image will be saved at the current height
    var saveImg = {
          'name': name,
          'x': 0,
          'y': y,
          'height': img.height,
          'width': img.width,
          '_img': img
        };

    // Increment the y
    this.y = y + imgHeight;

    // Save the image
    this.images[name] = saveImg;
  };
}
CanvasSmith.prototype = {
  'addImage': function (img) {
    // Add the image
    return this.algorithm.call(this, img);
  },
  'exportCoordinates': function () {

  },
  'exportToCanvas': function () {

  },
  'export': function () {
  }
};

/**
 * Spritesmith generation function
 * @param {Object} params Parameters for spritesmith
 * @param {String[]} [params.src] Images to generate into sprite sheet
 * @param {String} [params.engine="auto"] Engine to use (canvas, gm, or user-defined via Spritesmith.addEngine)
 * TODO: engineOpts is not yet available
 * @param {String} [params.algorithm] Algorithm to pack images with (vertical or user-defined via Spritesmith.addAlgorithm)
 * @param {Mixed} [params.engineOpts] Options to pass through to engine
 * @param {Function} callback Function that receives compiled spritesheet and map
 */
function Spritesmith(params, callback) {
  var retObj = {},
      files = params.src,
      enginePref = params.engine || 'auto',
      engine = engines[enginePref];

  // If the engine is not defined
  if (engine === undefined) {
    // If the engine was not auto, inform the user
    assert.strictEqual(enginePref, 'auto', 'Sorry, the spritesmith engine \'' + enginePref + '\' could not be loaded. Please be sure you have installed it properly on your machine.');

    // Begin attempting to load the engines
    engine = engines.canvas || engines.gm;

    // Assert there is an engine
    assert(engine, 'Sorry, no spritesmith engine could be loaded for your machine. Please be sure you have installed canvas or gm.');
  }

  // Get our smithies
  var engineSmith = new EngineSmithy(engine),
      canvasSmith = new CanvasSmithy('auto');

  // In a waterfall fashion
  async.waterfall([
    function grabImages (cb) {
      // Map the files into their image counterparts
      engineSmith.createImages(files, cb);
    },
    // Then, add the images to our canvas (dry run)
    function smithAddFiles (images, cb) {
      var addImageToCanvas = canvasSmith.addImage.bind(canvasSmith);
      images.forEach(addImageToCanvas);

      // Callback with nothing
      cb(null);
    },
    // Then, output the coordinates
    function smithOutputCoordinates (cb) {

    },
    // Then, callback with the output canvas
    function smithOutputCanvas (canvas, cb) {
      async.waterfall([
        // Export the canvas as a png
        function exportCanvas (cb) {
          canvas['export']('png', cb);
        },
        function saveImageToRetObj(imgStr, cb) {
          // Save the image to the retObj
          retObj.image = imgStr;

          // Callback
          cb(null);
        }
      ], cb);
    },
    function smithCallbackData (cb) {
      // Callback with the return object
      cb(null, retObj);
    }
  ], callback);
}

/**
 * Method to add new engines via
 * @param {String} name Name of engine
 * @param {Function} engine Engine to bind under name
 */
function addEngine(name, engine) {
  engines[name] = engine;
}
Spritesmith.addEngine = addEngine;

// Attempt to load canvas and imagemagick
var canvasEngine,
    gmEngine;
try {
  canvasEngine = require('./engines/canvas');
} catch (e) {}

try {
  gmEngine = require('./engines/gm');
} catch (e) {}

if (canvasEngine) { addEngine('canvas', canvasEngine); }
if (gmEngine) { addEngine('gm', gmEngine); }

// Export Spritesmith
module.exports = Spritesmith;<|endoftext|>


<commit_before>var async = require('async'),
    assert = require('assert'),
    EngineSmith = require('./smiths/engine.smith.js'),
    Layout = require('layout'),
    CanvasSmith = require('./smiths/canvas.smith.js'),
    engines = {};

/**
 * Spritesmith generation function
 * @param {Object} params Parameters for spritesmith
 * @param {String[]} [params.src] Images to generate into sprite sheet
 * @param {String} [params.engine="auto"] Engine to use (phantomjs, canvas, gm, pngsmith, or user-defined via Spritesmith.addEngine)
 * @param {String} [params.algorithm="top-down"] Algorithm to pack images with (top-down or user-defined via Spritesmith.addAlgorithm)
 * @param {Number} [params.padding] Padding to use between images
 * @param {Mixed} [params.exportOpts] Options to pass through to engine for export
 * @param {Function} callback Function that receives compiled spritesheet and map
 * @returns {Mixed} callback[0] err If an error was encountered, this will be returned to callback
 * @returns {Object} callback[1] result Result object of spritesmith
 * @returns {String} callback[1].image Binary string representation of image
 * @returns {Object} callback[1].coordinates Map from file name to an object containing x, y, height, and width information about the source image
 */
function Spritesmith(params, callback) {
  var retObj = {},
      files = params.src,
      enginePref = params.engine || 'auto',
      engine = engines[enginePref],
      algorithmPref = params.algorithm || 'top-down';

  // If the engine is not defined
  if (engine === undefined) {
    // If the engine was not auto, inform the user
    assert.strictEqual(enginePref, 'auto', 'Sorry, the spritesmith engine \'' + enginePref + '\' could not be loaded. Please be sure you have installed it properly on your machine.');

    // Begin attempting to load the engines (in order of hardest to easiest)
    engine = engines.canvas || engines.gm || engines.phantomjs || engine['png-engine'];

    // Assert there is an engine
    assert(engine, 'Sorry, no spritesmith engine could be loaded for your machine. Please be sure you have installed canvas or gm.');
  }

  // If there is a set parameter for the engine, use it
  if (engine.set) {
    var engineOpts = params.engineOpts || {};
    engine.set(engineOpts);
  }

  // Create our smiths
  var engineSmith = new EngineSmith(engine),
      layer = new Layout(algorithmPref),
      padding = params.padding || 0,
      exportOpts = params.exportOpts || {},
      packedObj;

  // In a waterfall fashion
  async.waterfall([
    function grabImages (cb) {
      // Map the files into their image counterparts
      engineSmith.createImages(files, cb);
    },
    // Then, add the images to our canvas (dry run)
    function smithAddFiles (images, cb) {
      images.forEach(function (img) {
        // Save the non-padded properties as meta data
        var width = img.width,
            height = img.height,
            meta = {'img': img, 'actualWidth': width, 'actualHeight': height};

        // Add the item with padding to our layer
        layer.addItem({'width': width + padding, 'height': height + padding, 'meta': meta});
      });

      // Callback with nothing
      cb(null);
    },
    // Then, output the coordinates
    function smithOutputCoordinates (cb) {
      // Export and saved packedObj for later
      packedObj = layer['export']();

      // Extract the coordinates
      var coordinates = {},
          packedItems = packedObj.items;
      packedItems.forEach(function (item) {
        var meta = item.meta,
            img = meta.img,
            name = img._filepath;
        coordinates[name] = {
          'x': item.x,
          'y': item.y,
          'width': meta.actualWidth,
          'height': meta.actualHeight
        };
      });

      // Save the coordinates
      retObj.coordinates = coordinates;

      // Continue
      cb(null);
    },
    // Then, generate a canvas
    function generateCanvas (cb) {
      // Grab and fallback the width/height
      var width = Math.max(packedObj.width || 0, 0),
          height = Math.max(packedObj.height || 0, 0);

      // If there are items
      var itemsExist = packedObj.items.length;
      if (itemsExist) {
        // Remove the last item's padding
        width -= padding;
        height -= padding;
      }

      // Export the total width and height of the generated canvas
      retObj.properties = {
        width: width,
        height: height
      };

      // If there are items, generate the canvas
      if (itemsExist) {
        engine.createCanvas(width, height, cb);
      } else {
      // Otherwise, skip over potential errors/CPU
        cb(null, '');
      }
    },
    // Then, export the canvas
    function exportCanvas (canvas, cb) {
      // If there is no canvas, callback with an empty string
      var items = packedObj.items;
      if (!canvas) {
        return cb(null, '');
      }

      // Create a CanvasSmithy
      var canvasSmith = new CanvasSmith(canvas);

      // Add the images onto canvasSmith
      canvasSmith.addImages(items);

      // Export our canvas
      canvasSmith['export'](exportOpts, cb);
    },
    function saveImageToRetObj(imgStr, cb) {
      // Save the image to the retObj
      retObj.image = imgStr;

      // Callback
      cb(null);
    },
    function smithCallbackData (cb) {
      // Callback with the return object
      cb(null, retObj);
    }
  ], callback);
}

// Add the smiths to Spritesmith
Spritesmith.EngineSmith = EngineSmith;
Spritesmith.Layout = Layout;
Spritesmith.CanvasSmith = CanvasSmith;

/**
 * Method to add new engines via
 * @param {String} name Name of engine
 * @param {Function} engine Engine to bind under name
 */
function addEngine(name, engine) {
  engines[name] = engine;
}
Spritesmith.addEngine = addEngine;
Spritesmith.engines = engines;

// Attempt to load canvas and imagemagick
var canvasEngine,
    gmEngine,
    phantomjsEngine,
    pngEngine;
try {
  canvasEngine = require('canvassmith');
} catch (e) {}

try {
  gmEngine = require('gmsmith');
} catch (e) {}

try {
  phantomjsEngine = require('phantomjssmith');
} catch (e) {}

try {
  pngEngine = require('pngsmith');
} catch (e) {}

if (canvasEngine) { addEngine('canvas', canvasEngine); }
if (gmEngine) { addEngine('gm', gmEngine); }
if (phantomjsEngine) { addEngine('phantomjs', phantomjsEngine); }
if (pngEngine) { addEngine('pngsmith', pngEngine); }

// Export Spritesmith
module.exports = Spritesmith;
<commit_msg>Fixed up bad fallback chain<commit_after>var async = require('async'),
    assert = require('assert'),
    EngineSmith = require('./smiths/engine.smith.js'),
    Layout = require('layout'),
    CanvasSmith = require('./smiths/canvas.smith.js'),
    engines = {};

/**
 * Spritesmith generation function
 * @param {Object} params Parameters for spritesmith
 * @param {String[]} [params.src] Images to generate into sprite sheet
 * @param {String} [params.engine="auto"] Engine to use (phantomjs, canvas, gm, pngsmith, or user-defined via Spritesmith.addEngine)
 * @param {String} [params.algorithm="top-down"] Algorithm to pack images with (top-down or user-defined via Spritesmith.addAlgorithm)
 * @param {Number} [params.padding] Padding to use between images
 * @param {Mixed} [params.exportOpts] Options to pass through to engine for export
 * @param {Function} callback Function that receives compiled spritesheet and map
 * @returns {Mixed} callback[0] err If an error was encountered, this will be returned to callback
 * @returns {Object} callback[1] result Result object of spritesmith
 * @returns {String} callback[1].image Binary string representation of image
 * @returns {Object} callback[1].coordinates Map from file name to an object containing x, y, height, and width information about the source image
 */
function Spritesmith(params, callback) {
  var retObj = {},
      files = params.src,
      enginePref = params.engine || 'auto',
      engine = engines[enginePref],
      algorithmPref = params.algorithm || 'top-down';

  // If the engine is not defined
  if (engine === undefined) {
    // If the engine was not auto, inform the user
    assert.strictEqual(enginePref, 'auto', 'Sorry, the spritesmith engine \'' + enginePref + '\' could not be loaded. Please be sure you have installed it properly on your machine.');

    // Begin attempting to load the engines (in order of hardest to easiest)
    engine = engines.canvas || engines.gm || engines.phantomjs || engines['png-engine'];

    // Assert there is an engine
    assert(engine, 'Sorry, no spritesmith engine could be loaded for your machine. Please be sure you have installed canvas or gm.');
  }

  // If there is a set parameter for the engine, use it
  if (engine.set) {
    var engineOpts = params.engineOpts || {};
    engine.set(engineOpts);
  }

  // Create our smiths
  var engineSmith = new EngineSmith(engine),
      layer = new Layout(algorithmPref),
      padding = params.padding || 0,
      exportOpts = params.exportOpts || {},
      packedObj;

  // In a waterfall fashion
  async.waterfall([
    function grabImages (cb) {
      // Map the files into their image counterparts
      engineSmith.createImages(files, cb);
    },
    // Then, add the images to our canvas (dry run)
    function smithAddFiles (images, cb) {
      images.forEach(function (img) {
        // Save the non-padded properties as meta data
        var width = img.width,
            height = img.height,
            meta = {'img': img, 'actualWidth': width, 'actualHeight': height};

        // Add the item with padding to our layer
        layer.addItem({'width': width + padding, 'height': height + padding, 'meta': meta});
      });

      // Callback with nothing
      cb(null);
    },
    // Then, output the coordinates
    function smithOutputCoordinates (cb) {
      // Export and saved packedObj for later
      packedObj = layer['export']();

      // Extract the coordinates
      var coordinates = {},
          packedItems = packedObj.items;
      packedItems.forEach(function (item) {
        var meta = item.meta,
            img = meta.img,
            name = img._filepath;
        coordinates[name] = {
          'x': item.x,
          'y': item.y,
          'width': meta.actualWidth,
          'height': meta.actualHeight
        };
      });

      // Save the coordinates
      retObj.coordinates = coordinates;

      // Continue
      cb(null);
    },
    // Then, generate a canvas
    function generateCanvas (cb) {
      // Grab and fallback the width/height
      var width = Math.max(packedObj.width || 0, 0),
          height = Math.max(packedObj.height || 0, 0);

      // If there are items
      var itemsExist = packedObj.items.length;
      if (itemsExist) {
        // Remove the last item's padding
        width -= padding;
        height -= padding;
      }

      // Export the total width and height of the generated canvas
      retObj.properties = {
        width: width,
        height: height
      };

      // If there are items, generate the canvas
      if (itemsExist) {
        engine.createCanvas(width, height, cb);
      } else {
      // Otherwise, skip over potential errors/CPU
        cb(null, '');
      }
    },
    // Then, export the canvas
    function exportCanvas (canvas, cb) {
      // If there is no canvas, callback with an empty string
      var items = packedObj.items;
      if (!canvas) {
        return cb(null, '');
      }

      // Create a CanvasSmithy
      var canvasSmith = new CanvasSmith(canvas);

      // Add the images onto canvasSmith
      canvasSmith.addImages(items);

      // Export our canvas
      canvasSmith['export'](exportOpts, cb);
    },
    function saveImageToRetObj(imgStr, cb) {
      // Save the image to the retObj
      retObj.image = imgStr;

      // Callback
      cb(null);
    },
    function smithCallbackData (cb) {
      // Callback with the return object
      cb(null, retObj);
    }
  ], callback);
}

// Add the smiths to Spritesmith
Spritesmith.EngineSmith = EngineSmith;
Spritesmith.Layout = Layout;
Spritesmith.CanvasSmith = CanvasSmith;

/**
 * Method to add new engines via
 * @param {String} name Name of engine
 * @param {Function} engine Engine to bind under name
 */
function addEngine(name, engine) {
  engines[name] = engine;
}
Spritesmith.addEngine = addEngine;
Spritesmith.engines = engines;

// Attempt to load canvas and imagemagick
var canvasEngine,
    gmEngine,
    phantomjsEngine,
    pngEngine;
try {
  canvasEngine = require('canvassmith');
} catch (e) {}

try {
  gmEngine = require('gmsmith');
} catch (e) {}

try {
  phantomjsEngine = require('phantomjssmith');
} catch (e) {}

try {
  pngEngine = require('pngsmith');
} catch (e) {}

if (canvasEngine) { addEngine('canvas', canvasEngine); }
if (gmEngine) { addEngine('gm', gmEngine); }
if (phantomjsEngine) { addEngine('phantomjs', phantomjsEngine); }
if (pngEngine) { addEngine('pngsmith', pngEngine); }

// Export Spritesmith
module.exports = Spritesmith;
<|endoftext|>


<commit_before>class Space {
  constructor(iterable) {
    if (!iterable) {
      throw new Error();
    }
    this.table = new Map(iterable);
  }

  get(key) {
    return this.table.get(key);
  }

  set(key, value) {
    return this.table.set(key, value);
  }

  getOrSet(key, value = null) {
    if (value == null) {
      return this.get(key);
    }
    this.set(key, value);
    return this;
  }

  values() {
    return this.table.values();
  }
}

export class Rgb extends Space {
  static KEY_R = "r";
  static KEY_G = "g";
  static KEY_B = "b";

  constructor(r, g, b) {
    super([[Rgb.KEY_R, r], [Rgb.KEY_G, g], [Rgb.KEY_B, b]]);
  }

  toString() {
    return `rgb(${this.r()}, ${this.g()}, ${this.b()})`;
  }

  r(value = null) {
    return this.getOrSet(Rgb.KEY_R, value);
  }

  g(value = null) {
    return this.getOrSet(Rgb.KEY_G, value);
  }

  b(value = null) {
    return this.getOrSet(Rgb.KEY_B, value);
  }
}
<commit_msg>Added a cloning method<commit_after>class Space {
  constructor(iterable) {
    if (!iterable) {
      throw new Error();
    }
    this.table = new Map(iterable);
  }

  clone() {
    throw new Error("clone() is not implemented");
  }

  get(key) {
    return this.table.get(key);
  }

  set(key, value) {
    return this.table.set(key, value);
  }

  getOrSet(key, value = null) {
    if (value == null) {
      return this.get(key);
    }
    this.set(key, value);
    return this;
  }

  values() {
    return this.table.values();
  }
}

export class Rgb extends Space {
  static KEY_R = "r";
  static KEY_G = "g";
  static KEY_B = "b";

  constructor(r, g, b) {
    super([[Rgb.KEY_R, r], [Rgb.KEY_G, g], [Rgb.KEY_B, b]]);
  }

  toString() {
    return `rgb(${this.r()}, ${this.g()}, ${this.b()})`;
  }

  clone() {
    return new Rgb(this.r(), this.g(), this.b());
  }

  r(value = null) {
    return this.getOrSet(Rgb.KEY_R, value);
  }

  g(value = null) {
    return this.getOrSet(Rgb.KEY_G, value);
  }

  b(value = null) {
    return this.getOrSet(Rgb.KEY_B, value);
  }
}
<|endoftext|>


<commit_before>var fs = require('fs')
var IPFSApi = require('ipfs-api')
var libp2p = require('libp2p-ipfs')
var PeerId = require('peer-id')
var PeerInfo = require('peer-info')
var multiaddr = require('multiaddr')
var pify = require('pify')
var debug = require('debug')
var log = debug('pando:start')
log.error = debug('pando:start:error')
var protocols = require('./protocols')
var utils = require('./utils')
var path = require('path')

var createPeerInfo = pify(function createPeerInfo (config, cb) {
  if (config) {
    log('retrieving peerid')
    PeerId.createFromPrivKey(config.Identity.PrivKey, (err, peerId) => {
      if (err) {
        log.err(err)
        return cb(err)
      }

      log('retrieved id: ' + peerId.toB58String())
      var peerInfo = new PeerInfo(peerId)
      cb(null, peerInfo)
    })
  } else {
    log('creating a new peerid')
    PeerId.create(cb)
  }
})

var startNetwork = pify(function startNetwork (node, cb) {
  log('Starting communication node')
  node._libp2p.start((err) => {
    if (err) {
      log.error(err)
      return cb(err)
    }

    log('Node started successfully')

    log('Installing protocols')
    protocols.install(node, '/jobs/1.0.0')

    node._started = true

    log('Node listening')
    node._events.emit('listening')

    cb(null, node)
  })
})

module.exports = function (node, cb) {
  if (typeof cb !== 'function') {
    throw new Error('Invalid callback function')
  }

  // When using IPFS, retrieve the PeerId in the config file so the node shares
  // the same id on both the IPFS and Pando (libp2p) networks. If no IPFS repository
  // has been initialized already create a new PeerId.
  var config
  try {
    log('Reading config')
    config = JSON.parse(fs.readFileSync(path.join(node._options.repoPath, 'config')))
  } catch (err) {
    log(err)
    log('creating a new peer id')
    config = null
  }

  // Connecting to ipfs daemon
  utils.isIpfsRunning((running) => {
    if (!running) {
      // TODO: Reactivate when the file sharing protocol
      //       becomes necessary
      // var err = new Error('ipfs not running, aborting')
      // log.error(err)
      // return cb(err)
      log('WARNING: ipfs not running')
    }

    try {
      log('Starting ipfs api')
      node._ipfs = new IPFSApi()
    } catch (err) {
      log.error(err)
      cb(err)
    }
  })

  // We need to create a complete peer info (using the peer id) for using the
  // lower-level apis of libp2p
  createPeerInfo(config)
    .then((peerInfo) => {
      log('Creating communication node')
      node._libp2p = new libp2p.Node(peerInfo)

      log('Adding multiaddresses')
      node._libp2p.peerInfo.multiaddr.add(multiaddr.fromNodeAddress({
        family: 'IPv4',
        address: '0.0.0.0',
        port: node._options.port
      }, 'tcp'))

      startNetwork(node, cb)
    })
    .catch((err) => {
      log.error(err)
      cb(err)
    })
}
<commit_msg>Fixed bug<commit_after>var fs = require('fs')
var IPFSApi = require('ipfs-api')
var libp2p = require('libp2p-ipfs')
var PeerId = require('peer-id')
var PeerInfo = require('peer-info')
var multiaddr = require('multiaddr')
var pify = require('pify')
var debug = require('debug')
var log = debug('pando:start')
log.error = debug('pando:start:error')
var protocols = require('./protocols')
var utils = require('./utils')
var path = require('path')

var createPeerInfo = pify(function createPeerInfo (config, cb) {
  if (config) {
    log('retrieving peerid')
    PeerId.createFromPrivKey(config.Identity.PrivKey, (err, peerId) => {
      if (err) {
        log.err(err)
        return cb(err)
      }

      log('retrieved id: ' + peerId.toB58String())
      var peerInfo = new PeerInfo(peerId)
      cb(null, peerInfo)
    })
  } else {
    log('creating a new peer id')
    PeerId.create((err, peerId) => {
        if (err) throw err
        cb(null, new PeerInfo(peerId))
    })
  }
})

var startNetwork = pify(function startNetwork (node, cb) {
  log('Starting communication node')
  node._libp2p.start((err) => {
    if (err) {
      log.error(err)
      return cb(err)
    }

    log('Node started successfully')

    log('Installing protocols')
    protocols.install(node, '/jobs/1.0.0')

    node._started = true

    log('Node listening')
    node._events.emit('listening')

    cb(null, node)
  })
})

module.exports = function (node, cb) {
  if (typeof cb !== 'function') {
    throw new Error('Invalid callback function')
  }

  // When using IPFS, retrieve the PeerId in the config file so the node shares
  // the same id on both the IPFS and Pando (libp2p) networks. If no IPFS repository
  // has been initialized already create a new PeerId.
  var config
  try {
    log('Reading config')
    config = JSON.parse(fs.readFileSync(path.join(node._options.repoPath, 'config')))
  } catch (err) {
    log(err)
    log('creating a new peer id')
    config = null
  }

  // Connecting to ipfs daemon
  utils.isIpfsRunning((running) => {
    if (!running) {
      // TODO: Reactivate when the file sharing protocol
      //       becomes necessary
      // var err = new Error('ipfs not running, aborting')
      // log.error(err)
      // return cb(err)
      log('WARNING: ipfs not running')
    }

    try {
      log('Starting ipfs api')
      node._ipfs = new IPFSApi()
    } catch (err) {
      log.error(err)
      cb(err)
    }
  })

  // We need to create a complete peer info (using the peer id) for using the
  // lower-level apis of libp2p
  createPeerInfo(config)
    .then((peerInfo) => {
      log('Creating communication node')
      node._libp2p = new libp2p.Node(peerInfo)

      log('Adding multiaddresses')
      node._libp2p.peerInfo.multiaddr.add(multiaddr.fromNodeAddress({
        family: 'IPv4',
        address: '0.0.0.0',
        port: node._options.port
      }, 'tcp'))

      startNetwork(node, cb)
    })
    .catch((err) => {
      log.error(err)
      cb(err)
    })
}
<|endoftext|>


<commit_before>import { createStore, applyMiddleware, compose } from 'redux'
import { routerMiddleware } from 'react-router-redux'
import promiseMiddleware from 'redux-promise-middleware'
import createHistory from 'history/createBrowserHistory'
import { createScrollMiddleware } from 'react-redux-scroll'

import rootReducer from './reducers/index'
const history = createHistory()

let prevLocation = {};
history.listen(location => {
  const pathChanged = prevLocation.pathname !== location.pathname;
  const hashChanged = prevLocation.hash !== location.hash;
  if (pathChanged || hashChanged) window.scrollTo(0, 0);
  prevLocation = location;
});

const routerStuff = routerMiddleware(history)

export { history }

const defaultState = {
	auth: {
    charity: null
  },
  navigation: {
    dropdownVisible: false
  },
  howItWorks: {
    howItWorksVisible: false
  },
  noAuthSubNavigation: {
    currentLandingPageComponent: "Whats Happening"
  },
  charityDashboardSidebar: {
    currentCharityDashboardSidebarTab: "Members"
  },
	helpSomeone: {
		members: [],
    current_member: {
      donations: [],
      comments: [],
      info: '',
      name: 'Charlie',
      goal: 0
    }
	},
  careButton: {
    tooltipVisible: false
  },
  newMemberProcess: {
    tab: 'basics',
    file: '',
    imagePreviewUrl: ''
  },
  charityPage: {
    aboutUsVisible: false,
    story: {}
  }
}

const middleware = applyMiddleware(routerStuff, promiseMiddleware(), createScrollMiddleware())

const enhancers = compose(middleware, window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__())

const store = createStore(rootReducer, defaultState, enhancers)

export default store
<commit_msg>Added story object to newMemberProcess state<commit_after>import { createStore, applyMiddleware, compose } from 'redux'
import { routerMiddleware } from 'react-router-redux'
import promiseMiddleware from 'redux-promise-middleware'
import createHistory from 'history/createBrowserHistory'
import { createScrollMiddleware } from 'react-redux-scroll'

import rootReducer from './reducers/index'
const history = createHistory()

let prevLocation = {};
history.listen(location => {
  const pathChanged = prevLocation.pathname !== location.pathname;
  const hashChanged = prevLocation.hash !== location.hash;
  if (pathChanged || hashChanged) window.scrollTo(0, 0);
  prevLocation = location;
});

const routerStuff = routerMiddleware(history)

export { history }

const defaultState = {
	auth: {
    charity: null
  },
  navigation: {
    dropdownVisible: false
  },
  howItWorks: {
    howItWorksVisible: false
  },
  noAuthSubNavigation: {
    currentLandingPageComponent: "Whats Happening"
  },
  charityDashboardSidebar: {
    currentCharityDashboardSidebarTab: "Members"
  },
	helpSomeone: {
		members: [],
    current_member: {
      donations: [],
      comments: [],
      info: '',
      name: 'Charlie',
      goal: 0
    }
	},
  careButton: {
    tooltipVisible: false
  },
  newMemberProcess: {
    tab: 'basics',
    file: '',
    imagePreviewUrl: '',
    story: {
      reason_for_use: '',
      story: '',
      goal: ''
    }
  },
  charityPage: {
    aboutUsVisible: false,
    story: {}
  }
}

const middleware = applyMiddleware(routerStuff, promiseMiddleware(), createScrollMiddleware())

const enhancers = compose(middleware, window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__())

const store = createStore(rootReducer, defaultState, enhancers)

export default store
<|endoftext|>


<commit_before>module.exports = (client, twitter) => {

  // Import de las regex
  var regex = require("./regexp");

  var comandosDeAudio = require("./comandos");

  var estoySilenciado = false;

  client.on('message', message => {
    if(message.channel.id == 346796946393923584){
      var adjuntos = message.attachments.array()
      if(adjuntos.length > 0){
        var adjunto = adjuntos[0] //TODO ponerse a hacer esto en multiples archivos algun día
        console.log("URL: " + adjunto.url);
        /*
        twitter.postMedia({'media' : adjunto.attachment}, error, function(response){
            console.log("LLEGUE HASTA AQUI");
            twitter.postTweet({'status': message.content, 'media_ids': [response.media_id_string] }, error, success);
          })
          */
        }else {
          twitter.postTweet({'status': message.content}, () => {}, () => {});
        }
    }else{
      // Si el mensaje no lo escribe el bot ni está silenciado, y si el mensaje viene de un canal válido
      if( message.author.username != 'EstrellaZorro'
          && !estoySilenciado
          && (message.channel.id == 730686599049773086 // EstrellaZorro -> BOTS/beep-beep-bop
          || message.channel.id == 268398719802540032 // EstrellaZorro -> boop
          || message.channel.id == 382239046790807562) // TESTOTESTOTEST -> GENERAL/texto
          ){
        // Respuesta a un saludo al servidor
        if (regex.regexSaludos.test(message.content)) {
          message.reply('HOLA MAMÁ').catch(console.log)
        }
        if (/hola bot/i.test(message.content)){
          message.reply('Holas, pero soy un bot. deberías hablar con seres humanos').catch(console.log)
        }
        if (/gracias bot/i.test(message.content)){
          message.reply('De nada, pero soy un bot. deberías hablar con seres humanos').catch(console.log)
        }
        if (regex.regexQuejaBot.test(message.content)){
          message.reply('LO SIENTO LO HAGO SIN QUERER').catch(console.log)
          estoySilenciado = true;
          setTimeout(
            () => {
              estoySilenciado = false
            }, 300000
          )
        }
        // Respuesta a peplo y las orisas
        if (regex.regexPeplo.test(message.content) && message.author.username == 'Peplo'){
          message.reply('PE... PE... PERO ORISA, PEPLO!').catch(console.log)
        }
        // Respuesta a halpmepls
        if (message.content === '!halpmepls'){
          message.channel.send('ESTE TÍO DICE QUE NECESITA AYUDA PUTO PRINGAO\'.HASTA YO ME DOY CUENTA Y ESO QUE NO TENGO AMIGOS.\nEH TÍOS, QUE NECESITA AYUDA!!!!1!uno!. PERO MIRA QUÉ PRINGAO\'...').catch(console.log)
        }
        // Respuesta al asco
        if (regex.regexAsco.test(message.content)){
          message.channel.send('',{ file: 'https://cdn.discordapp.com/attachments/268398719802540032/321729711950528513/unknown.png'}).catch(console.log)
        }
        if (regex.regexRate.test(message.content)){
          message.channel.send('',{ file: 'http://i.imgur.com/TGGnTq1.jpg'}).catch(console.log)
        }
        if (message.content == ':sad:' || message.content == '!sad'){
          message.channel.send('',{ file: 'https://cdn.discordapp.com/attachments/268398719802540032/382006568553676812/Sin_titulo.png'}).catch(console.log)
        }
        if (regex.regexCallMe.test(message.content)) {
          message.channel.send('https://68.media.tumblr.com/f67ea264b93b8df0e558b61f019a2240/tumblr_o4rc1yh5ql1uulaizo1_500.gif').catch(console.log)
        }
        if (regex.regexHum.test(message.content)) {
          message.channel.send('https://media.giphy.com/media/CaiVJuZGvR8HK/giphy.gif').catch(console.log)
        }
        if (regex.regexBorja.test(message.content)) {
          message.channel.send('',{ file: 'https://cdn.discordapp.com/attachments/268398719802540032/330319777694220288/kek.jpg'}).catch(console.log)
        }
        if (regex.regexTTSMal.test(message.content)) {
          message.reply('QUE NO SE ESCRIBE ASÍ SUBNORMAL. ESCRIBE "!halpmepls" PARA MÁS AYUDA SALU3').catch(console.log)
        }
        if (message.content === '!pien'){
          message.channel.send('',{ file: 'https://cdn.discordapp.com/attachments/347123923001016320/732145091031990312/unknown.png'}).catch(console.log)
        }
        if (message.content === '!halluda') {
          message.channel.send(`Sé decir esto: ${comandosDeAudio.join(", ")}`).catch(console.log)
        }
      }
    }
  });
}
<commit_msg>fix al envío de archivos<commit_after>module.exports = (client, twitter) => {

  // Import de las regex
  var regex = require("./regexp");

  var comandosDeAudio = require("./comandos");

  var estoySilenciado = false;

  client.on('message', message => {
    if(message.channel.id == 346796946393923584){
      var adjuntos = message.attachments.array()
      if(adjuntos.length > 0){
        var adjunto = adjuntos[0] //TODO ponerse a hacer esto en multiples archivos algun día
        console.log("URL: " + adjunto.url);
        /*
        twitter.postMedia({'media' : adjunto.attachment}, error, function(response){
            console.log("LLEGUE HASTA AQUI");
            twitter.postTweet({'status': message.content, 'media_ids': [response.media_id_string] }, error, success);
          })
          */
        }else {
          twitter.postTweet({'status': message.content}, () => {}, () => {});
        }
    }else{
      // Si el mensaje no lo escribe el bot ni está silenciado, y si el mensaje viene de un canal válido
      if( message.author.username != 'EstrellaZorro'
          && !estoySilenciado
          && (message.channel.id == 730686599049773086 // EstrellaZorro -> BOTS/beep-beep-bop
          || message.channel.id == 268398719802540032 // EstrellaZorro -> boop
          || message.channel.id == 382239046790807562) // TESTOTESTOTEST -> GENERAL/texto
          ){
        // Respuesta a un saludo al servidor
        if (regex.regexSaludos.test(message.content)) {
          message.reply('HOLA MAMÁ').catch(console.log)
        }
        if (/hola bot/i.test(message.content)){
          message.reply('Holas, pero soy un bot. deberías hablar con seres humanos').catch(console.log)
        }
        if (/gracias bot/i.test(message.content)){
          message.reply('De nada, pero soy un bot. deberías hablar con seres humanos').catch(console.log)
        }
        if (regex.regexQuejaBot.test(message.content)){
          message.reply('LO SIENTO LO HAGO SIN QUERER').catch(console.log)
          estoySilenciado = true;
          setTimeout(
            () => {
              estoySilenciado = false
            }, 300000
          )
        }
        // Respuesta a peplo y las orisas
        if (regex.regexPeplo.test(message.content) && message.author.username == 'Peplo'){
          message.reply('PE... PE... PERO ORISA, PEPLO!').catch(console.log)
        }
        // Respuesta a halpmepls
        if (message.content === '!halpmepls'){
          message.channel.send('ESTE TÍO DICE QUE NECESITA AYUDA PUTO PRINGAO\'.HASTA YO ME DOY CUENTA Y ESO QUE NO TENGO AMIGOS.\nEH TÍOS, QUE NECESITA AYUDA!!!!1!uno!. PERO MIRA QUÉ PRINGAO\'...').catch(console.log)
        }
        // Respuesta al asco
        if (regex.regexAsco.test(message.content)){
          message.channel.send({ files: ['https://cdn.discordapp.com/attachments/268398719802540032/321729711950528513/unknown.png']}).catch(console.log)
        }
        if (regex.regexRate.test(message.content)){
          message.channel.send({ files: ['http://i.imgur.com/TGGnTq1.jpg']}).catch(console.log)
        }
        if (message.content == ':sad:' || message.content == '!sad'){
          message.channel.send({ files: ['https://cdn.discordapp.com/attachments/268398719802540032/382006568553676812/Sin_titulo.png']}).catch(console.log)
        }
        if (regex.regexCallMe.test(message.content)) {
          message.channel.send({ files: ['https://68.media.tumblr.com/f67ea264b93b8df0e558b61f019a2240/tumblr_o4rc1yh5ql1uulaizo1_500.gif']}).catch(console.log)
        }
        if (regex.regexHum.test(message.content)) {
          message.channel.send('https://media.giphy.com/media/CaiVJuZGvR8HK/giphy.gif').catch(console.log)
        }
        if (regex.regexBorja.test(message.content)) {
          message.channel.send({ files: ['https://cdn.discordapp.com/attachments/268398719802540032/330319777694220288/kek.jpg']}).catch(console.log)
        }
        if (regex.regexTTSMal.test(message.content)) {
          message.reply('QUE NO SE ESCRIBE ASÍ SUBNORMAL. ESCRIBE "!halpmepls" PARA MÁS AYUDA SALU3').catch(console.log)
        }
        if (message.content === '!pien'){
          message.channel.send({ files: ['https://cdn.discordapp.com/attachments/347123923001016320/732145091031990312/unknown.png']}).catch(console.log)
        }
        if (message.content === '!halluda') {
          message.channel.send(`Sé decir esto: ${comandosDeAudio.join(", ")}`).catch(console.log)
        }
      }
    }
  });
}
<|endoftext|>


<commit_before>/* global _, setInterval, clearInterval, test */

/* jshint ignore:start */
import util.underscore as _;
import .test as test;
/* jshint ignore:end */

exports = (function () {
  'use strict';

  var mock = null,
    listeners = {},
    obj = {};

  obj.clear = function () {
    obj.unregister(_.keys(listeners));
  };

  obj.unregister = function (tags) {
    tags = _.isArray(tags) ? tags : [tags];
    _.each(tags, function (tag) {
      if (listeners[tag]) {
        clearInterval(listeners[tag].timer);
        delete listeners[tag];
      }
    });
  };

  obj.register = function (tag, callback, interval) {
    interval = mock ? mock : interval;

    if (!listeners[tag]) {
      listeners[tag] = {
        callback: callback,
        interval: interval,
        timer: setInterval(callback, interval),
        is_running: true
      };
    }
  };

  obj.pause = function (tags) {
    tags = _.isArray(tags) ? tags : [tags];
    _.each(tags, function (tag) {
      var listener = listeners[tag];

      // no need to clear interval if timer is not running
      if (listener && listener.is_running) {
        clearInterval(listener.timer);
        listener.is_running = false;
      }
    });
  };

  obj.resume = function (tags) {
    var listener;

    tags = _.isArray(tags) ? tags : [tags];
    _.each(tags, function (tag) {
      listener = listeners[tag];
      if (listener && !listener.is_running) {
        listener.timer = setInterval(listener.callback, listener.interval);
        listener.is_running = true;
      }
    });
  };

  obj.has = function (tag) {
    return !!listeners[tag];
  };

  obj.mock = function (interval) {
    mock = interval;
  };

  test.prepare(obj, {
    listeners: listeners
  });

  return obj;
})();
<commit_msg>added timeout function for timer module<commit_after>/* global _, setInterval, clearInterval, setTimeout, test */

/* jshint ignore:start */
import util.underscore as _;
import .test as test;
/* jshint ignore:end */

exports = (function () {
  'use strict';

  var mock = null,
    listeners = {},
    obj = {};

  obj.clear = function () {
    obj.unregister(_.keys(listeners));
  };

  obj.unregister = function (tags) {
    tags = _.isArray(tags) ? tags : [tags];
    _.each(tags, function (tag) {
      if (listeners[tag]) {
        clearInterval(listeners[tag].timer);
        delete listeners[tag];
      }
    });
  };

  obj.register = function (tag, callback, interval) {
    interval = mock ? mock : interval;

    if (!listeners[tag]) {
      listeners[tag] = {
        callback: callback,
        interval: interval,
        timer: setInterval(callback, interval),
        is_running: true
      };
    }
  };

  obj.pause = function (tags) {
    tags = _.isArray(tags) ? tags : [tags];
    _.each(tags, function (tag) {
      var listener = listeners[tag];

      // no need to clear interval if timer is not running
      if (listener && listener.is_running) {
        clearInterval(listener.timer);
        listener.is_running = false;
      }
    });
  };

  obj.resume = function (tags) {
    var listener;

    tags = _.isArray(tags) ? tags : [tags];
    _.each(tags, function (tag) {
      listener = listeners[tag];
      if (listener && !listener.is_running) {
        listener.timer = setInterval(listener.callback, listener.interval);
        listener.is_running = true;
      }
    });
  };

  obj.has = function (tag) {
    return !!listeners[tag];
  };

  obj.timeout = function (callback, interval) {
    setTimeout(callback, mock ? mock : interval);
  };

  obj.mock = function (interval) {
    mock = interval;
  };

  test.prepare(obj, {
    listeners: listeners
  });

  return obj;
})();
<|endoftext|>


<commit_before>'use strict'
var Tools = (function(global, undefined) {

    // 获得对象的实际类型
    function _typeof(obj) {
        if (typeof obj === 'undefined') {
            return 'undefined';
        }
        if (obj === null) {
            return 'null';
        }
        var _obj = obj,
            type = _obj.constructor.name;
        if (type === 'Number') {
            if (isNaN(_obj)) {
                return 'NaN';
            }
        }
        return type;
    }

    // 找出关键词在字符串中所有的匹配位置
    function _mark_str(substr, str) {
        var index = [],
            sublen = substr.length,
            regexp = new RegExp(substr, 'g');
        while (regexp.exec(str)) {
            index.push(regexp.lastIndex - sublen);
        }
        return index;
    }

    // 找出关键词数组中的每个关键词在字符串中所有匹配的位置
    function _mark_str_arr(substr_arr, str) {
        var index = [];
        for (var i = 0; i < substr_arr.length; i++) {
            var _index = {key: substr_arr[i], index: []},
                sublen = substr_arr[i].length,
                regexp = new RegExp(substr_arr[i], 'g');
            while (regexp.exec(str)) {
                _index.index.push(regexp.lastIndex - sublen);
            }
            index.push(_index);
        }
        return index;
    }

    return {
        mark: function(substr, str) {
            if (_typeof(substr) === 'Array') {
                return _mark_str_arr(substr, str);
            } else if (_typeof(substr) === 'String') {
                return _mark_str(substr, str);
            }
        },
        _typeof: _typeof
    };
})(window);
<commit_msg>added documentation comment<commit_after>/**
 * An utility functions collection of javascript.
 * @author victor.li
 * @date 2015/01/22
 * @version 1.0.0
 * Released under terms of MIT lincense.
 */
'use strict'
var Tools = (function(global, undefined) {

    // 获得对象的实际类型
    function _typeof(obj) {
        if (typeof obj === 'undefined') {
            return 'undefined';
        }
        if (obj === null) {
            return 'null';
        }
        var _obj = obj,
            type = _obj.constructor.name;
        if (type === 'Number') {
            if (isNaN(_obj)) {
                return 'NaN';
            }
        }
        return type;
    }

    // 找出关键词在字符串中所有的匹配位置
    function _mark_str(substr, str) {
        var index = [],
            sublen = substr.length,
            regexp = new RegExp(substr, 'g');
        while (regexp.exec(str)) {
            index.push(regexp.lastIndex - sublen);
        }
        return index;
    }

    // 找出关键词数组中的每个关键词在字符串中所有匹配的位置
    function _mark_str_arr(substr_arr, str) {
        var index = [];
        for (var i = 0; i < substr_arr.length; i++) {
            var _index = {key: substr_arr[i], index: []},
                sublen = substr_arr[i].length,
                regexp = new RegExp(substr_arr[i], 'g');
            while (regexp.exec(str)) {
                _index.index.push(regexp.lastIndex - sublen);
            }
            index.push(_index);
        }
        return index;
    }

    return {
        mark: function(substr, str) {
            if (_typeof(substr) === 'Array') {
                return _mark_str_arr(substr, str);
            } else if (_typeof(substr) === 'String') {
                return _mark_str(substr, str);
            }
        },
        _typeof: _typeof
    };
})(window);
<|endoftext|>


<commit_before>angular.module('com.likalo.ui')
    .factory('$uiTools', function() {

        var ngModelNoop = function() {
            this.$viewValue = undefined;
            this.$modelValue = undefined;
            this.$formatters = [];
            this.$parsers = [];
        };
        ngModelNoop.prototype = {
            $parse: function(value) {
                var $modelValue = value;
                angular.forEach(this.$parsers,
                    function parse(parser) {
                        $modelValue = parser(value);
                    });
                this.$modelValue = value;
            },
            $render: angular.noop,
            $setViewValue: function(value) {
                this.$viewValue = value;
                this.$parse(value);
            }
        };

        function elementUnwrap(el) {
            if (angular.isUndefined(el)) return;
            if (angular.isDefined(el['nodeName'])) return el;
            return el[0];
        }

        function findElementBySelector(selector, el) {
            var document = $document[0];
            if (selector[0] === "#") return angular.element(
                document.getElementById(selector.substr(1))
            );
            if (selector[0] === ".") return angular.element(
                document.getElementsByClassName(selector.substr(1))
            );
            if (selector === ":parent") return el.parent();
            if (selector === ":previous") return el.previous();
            if (selector === ":next") return el.next();
            return angular.element(
                document.getElementsByTagName(selector)
            );
        }

        return {
        	ngModelNoop: ngModelNoop,
        	elementUnwrap: elementUnwrap,
        	findElementBySelector: findElementBySelector
        };
    });<commit_msg>Fix the injection error<commit_after>angular.module('com.likalo.ui')
  .factory('$uiTools', [
    '$document',
    function ($document) {

      var ngModelNoop = function () {
        this.$viewValue = undefined;
        this.$modelValue = undefined;
        this.$formatters = [];
        this.$parsers = [];
      };
      ngModelNoop.prototype = {
        $parse: function (value) {
          var $modelValue = value;
          angular.forEach(this.$parsers,
            function parse(parser) {
              $modelValue = parser(value);
            });
          this.$modelValue = value;
        },
        $render: angular.noop,
        $setViewValue: function (value) {
          this.$viewValue = value;
          this.$parse(value);
        }
      };

      function elementUnwrap(el) {
        if (angular.isUndefined(el)) return;
        if (angular.isDefined(el['nodeName'])) return el;
        return el[0];
      }

      function findElementBySelector(selector, el) {
        var document = $document[0];
        if (selector[0] === "#") return angular.element(
          document.getElementById(selector.substr(1))
        );
        if (selector[0] === ".") return angular.element(
          document.getElementsByClassName(selector.substr(1))
        );
        if (selector === ":parent") return el.parent();
        if (selector === ":previous") return el.previous();
        if (selector === ":next") return el.next();
        return angular.element(
          document.getElementsByTagName(selector)
        );
      }

      return {
        ngModelNoop: ngModelNoop,
        elementUnwrap: elementUnwrap,
        findElementBySelector: findElementBySelector
      };
    }
  ]);<|endoftext|>


<commit_before>// This file is adapted from taterbase/gpx-parser
//
// https://github.com/taterbase/gpx-parser

import xml2js from 'xml2js';
import EasyFit from 'easy-fit';
import Pako from 'pako';

const parser = new xml2js.Parser();

function extractGPXTracks(gpx) {
    if (!gpx.trk) {
        console.log('GPX file has no tracks!', gpx);
        throw new Error('Unexpected gpx file format.');
    }

    const parsedTracks = [];

    gpx.trk.forEach(trk => {
        let name = trk.name && trk.name.length > 0 ? trk.name[0] : 'untitled';

        trk.trkseg.forEach(trkseg => {
            let points = trkseg.trkpt.map(trkpt => ({
                lat: parseFloat(trkpt.$.lat),
                lng: parseFloat(trkpt.$.lon),
                // These are available to us, but are currently unused
                // elev: parseFloat(trkpt.ele) || 0,
                // time: new Date(trkpt.time || '0')
            }));

            parsedTracks.push({points, name});
        });
    });

    return parsedTracks;
}

function extractTCXTracks(tcx, name) {
    if (!tcx.Activities) {
        console.log('TCX file has no activities!', tcx);
        throw new Error('Unexpected tcx file format.');
    }

    const parsedTracks = [];

    for (const act of tcx.Activities[0].Activity) {
        for (const lap of act.Lap) {
            let points = lap.Track[0].Trackpoint
                .filter(trkpt => trkpt.Position)
                .map(trkpt => ({
                    lat: parseFloat(trkpt.Position[0].LatitudeDegrees[0]),
                    lng: parseFloat(trkpt.Position[0].LongitudeDegrees[0]),
                    // These are available to us, but are currently unused
                    // elev: parseFloat(trkpt.ElevationMeters[0]) || 0,
                    // time: new Date(trkpt.Time[0] || '0')
                }));

            parsedTracks.push({points, name});
        }
    }

    return parsedTracks;
}

function extractFITTracks(fit, name) {
    if (!fit.records || fit.records.length === 0) {
        console.log('FIT file has no records!', fit);
        throw new Error('Unexpected FIT file format.');
    }

    const points = [];
    for (const record of fit.records) {
        if (record.position_lat && record.position_long) {
            points.push({
                lat: record.position_lat,
                lng: record.position_long,
                // Other available fields: timestamp, distance, altitude, speed, heart_rate
            });
        }
    }

    return [{points, name}];
}

function readFile(file, encoding, isGzipped) {
    return new Promise(resolve => {
        const reader = new FileReader();
        reader.onload = (e) => {
            const result = e.target.result;
            resolve(isGzipped ? Pako.inflate(result) : result);
        };

        if (encoding === 'binary') {
            reader.readAsArrayBuffer(file);
        } else {
            reader.readAsText(file);
        }
    });
}

export default function extractTracks(file) {
    const isGzipped = /\.gz$/i.test(file.name);
    const strippedName = file.name.replace(/\.gz$/i, '');
    const format = strippedName.split('.').pop().toLowerCase();

    switch (format) {
    case 'gpx':
    case 'tcx': /* Handle XML based file formats the same way */

        return readFile(file, 'text', isGzipped)
            .then(textContents => new Promise((resolve, reject) => {
                parser.parseString(textContents, (err, result) => {
                    if (err) {
                        reject(err);
                    } else if (result.gpx) {
                        resolve(extractGPXTracks(result.gpx));
                    } else if (result.TrainingCenterDatabase) {
                        resolve(extractTCXTracks(result.TrainingCenterDatabase, strippedName));
                    } else {
                        reject(new Error('Invalid file type.'));
                    }
                });
            }));

    case 'fit':
        return readFile(file, 'binary', isGzipped)
            .then(contents => new Promise((resolve, reject) => {
                const parser = new EasyFit({
                    force: true,
                    mode: 'list',
                });

                parser.parse(contents, (err, result) => {
                    if (err) {
                        reject(err);
                    } else {
                        resolve(extractFITTracks(result, strippedName));
                    }
                });
            }));

    default:
        throw `Unsupported file format: ${format}`;
    }
}
<commit_msg>Fix gzip inflate error handling<commit_after>// This file is adapted from taterbase/gpx-parser
//
// https://github.com/taterbase/gpx-parser

import xml2js from 'xml2js';
import EasyFit from 'easy-fit';
import Pako from 'pako';

const parser = new xml2js.Parser();

function extractGPXTracks(gpx) {
    if (!gpx.trk) {
        console.log('GPX file has no tracks!', gpx);
        throw new Error('Unexpected gpx file format.');
    }

    const parsedTracks = [];

    gpx.trk.forEach(trk => {
        let name = trk.name && trk.name.length > 0 ? trk.name[0] : 'untitled';

        trk.trkseg.forEach(trkseg => {
            let points = trkseg.trkpt.map(trkpt => ({
                lat: parseFloat(trkpt.$.lat),
                lng: parseFloat(trkpt.$.lon),
                // These are available to us, but are currently unused
                // elev: parseFloat(trkpt.ele) || 0,
                // time: new Date(trkpt.time || '0')
            }));

            parsedTracks.push({points, name});
        });
    });

    return parsedTracks;
}

function extractTCXTracks(tcx, name) {
    if (!tcx.Activities) {
        console.log('TCX file has no activities!', tcx);
        throw new Error('Unexpected tcx file format.');
    }

    const parsedTracks = [];

    for (const act of tcx.Activities[0].Activity) {
        for (const lap of act.Lap) {
            let points = lap.Track[0].Trackpoint
                .filter(trkpt => trkpt.Position)
                .map(trkpt => ({
                    lat: parseFloat(trkpt.Position[0].LatitudeDegrees[0]),
                    lng: parseFloat(trkpt.Position[0].LongitudeDegrees[0]),
                    // These are available to us, but are currently unused
                    // elev: parseFloat(trkpt.ElevationMeters[0]) || 0,
                    // time: new Date(trkpt.Time[0] || '0')
                }));

            parsedTracks.push({points, name});
        }
    }

    return parsedTracks;
}

function extractFITTracks(fit, name) {
    if (!fit.records || fit.records.length === 0) {
        console.log('FIT file has no records!', fit);
        throw new Error('Unexpected FIT file format.');
    }

    const points = [];
    for (const record of fit.records) {
        if (record.position_lat && record.position_long) {
            points.push({
                lat: record.position_lat,
                lng: record.position_long,
                // Other available fields: timestamp, distance, altitude, speed, heart_rate
            });
        }
    }

    return [{points, name}];
}

function readFile(file, encoding, isGzipped) {
    return new Promise((resolve, reject) => {
        const reader = new FileReader();
        reader.onload = (e) => {
            const result = e.target.result;
            try {
                return resolve(isGzipped ? Pako.inflate(result) : result);
            } catch (e) {
                return reject(e);
            }
        };

        if (encoding === 'binary') {
            reader.readAsArrayBuffer(file);
        } else {
            reader.readAsText(file);
        }
    });
}

export default function extractTracks(file) {
    const isGzipped = /\.gz$/i.test(file.name);
    const strippedName = file.name.replace(/\.gz$/i, '');
    const format = strippedName.split('.').pop().toLowerCase();

    switch (format) {
    case 'gpx':
    case 'tcx': /* Handle XML based file formats the same way */

        return readFile(file, 'text', isGzipped)
            .then(textContents => new Promise((resolve, reject) => {
                parser.parseString(textContents, (err, result) => {
                    if (err) {
                        reject(err);
                    } else if (result.gpx) {
                        resolve(extractGPXTracks(result.gpx));
                    } else if (result.TrainingCenterDatabase) {
                        resolve(extractTCXTracks(result.TrainingCenterDatabase, strippedName));
                    } else {
                        reject(new Error('Invalid file type.'));
                    }
                });
            }));

    case 'fit':
        return readFile(file, 'binary', isGzipped)
            .then(contents => new Promise((resolve, reject) => {
                const parser = new EasyFit({
                    force: true,
                    mode: 'list',
                });

                parser.parse(contents, (err, result) => {
                    if (err) {
                        reject(err);
                    } else {
                        resolve(extractFITTracks(result, strippedName));
                    }
                });
            }));

    default:
        throw `Unsupported file format: ${format}`;
    }
}
<|endoftext|>


<commit_before>Util.querySelector = u.qs = function(query, scope) {
	scope = scope ? scope : document;
	return scope.querySelector(query);
}
Util.querySelectorAll = u.qsa = function(query, scope) {
	scope = scope ? scope : document;
	return scope.querySelectorAll(query);
}

// Get element (id/class/tag)
// Returns elementById if possible
// else Returns first element with (partial) matching classname from target
// If no matches, return first element with tagname from target
Util.getElement = u.ge = function(identifier, scope) {
	var node, i, regexp;
	if(document.getElementById(identifier)) {
		return document.getElementById(identifier);
	}
	scope = scope ? scope : document;
	regexp = new RegExp("(^|\\s)" + identifier + "(\\s|$|\:)");
	for(i = 0; node = scope.getElementsByTagName("*")[i]; i++) {
		if(regexp.test(node.className)) {
			return node;
		}
	}
	return scope.getElementsByTagName(identifier).length ? scope.getElementsByTagName(identifier)[0] : false;
}
// Get elements (class/tag)
// Returns all elements with (partial) matching classname from target
// If no matches, return elements with tagname from target
Util.getElements = u.ges = function(identifier, scope) {
	var node, i, regexp;
	var nodes = new Array();
	scope = scope ? scope : document;
	regexp = new RegExp("(^|\\s)" + identifier + "(\\s|$|\:)");
	for(i = 0; node = scope.getElementsByTagName("*")[i]; i++) {
		if(regexp.test(node.className)) {
			nodes.push(node);
		}
	}
	return nodes.length ? nodes : scope.getElementsByTagName(identifier);
}

// get parent node of type
Util.parentNode = u.pn = function(node, node_type) {
	if(node_type) {
		if(node.parentNode) {
			var parent = node.parentNode;
		}
//		u.bug(e.parentNode.nodeName.toLowerCase());
		while(parent.nodeName.toLowerCase() != node_type.toLowerCase()) {
			if(parent.parentNode) {
				parent = parent.parentNode;
			}
			else {
				return false;
			}
		}
		return parent;
	}
	else {
		return node.parentNode;
	}
}

// Returns previous sibling, not counting text nodes as siblings and ignoring optional exclude=className/nodeName
// TODO: extend with include option and make exclude and include list
Util.previousSibling = u.ps = function(node, exclude) {
	node = node.previousSibling;
	while(node && (node.nodeType == 3 || node.nodeType == 8 || exclude && (u.hc(node, exclude) || node.nodeName.toLowerCase().match(exclude)))) {
		node = node.previousSibling;
	}
	return node;
}

// Returns next sibling, not counting text nodes as siblings and ignoring optional exclude=className/nodeName
// TODO: extend with include option and make exclude and include list
Util.nextSibling = u.ns = function(node, exclude) {
	node = node.nextSibling;
	while(node && (node.nodeType == 3 || node.nodeType == 8 || exclude && (u.hc(node, exclude) || node.nodeName.toLowerCase().match(exclude)))) {
		node = node.nextSibling;
	}
	return node;
}

// TODO: extend with include option and make exclude and include list
Util.childNodes = u.cn = function(node, exclude) {
	var i, child;
	var children = new Array();
	for(i = 0; child = node.childNodes[i]; i++) {
		if(child && child.nodeType != 3 && child.nodeType != 8 && (!exclude || (!u.hc(child, exclude) && !child.nodeName.toLowerCase().match(exclude) ))) {
			children.push(child);
		}
	}
	return children;
}

/**
* append child to element e
* add reference to e on node
* @param node e html element to append new child to
* @param String node_type new node to create and append - can be either node type of actual node
* @param Optional ClassName or attribute object
* return HTML node
*/
Util.appendElement = u.ae = function(parent, node_type, attributes) {
	try {
		// is node_type already DOM node
		var node = (typeof(node_type) == "object") ? node_type : document.createElement(node_type);
		node = parent.appendChild(node);

		// add attributes
		if(attributes) {
			var attribute;
			for(attribute in attributes) {
				if(attribute == "html") {
					node.innerHTML = attributes[attribute];
				}
				else {
					node.setAttribute(attribute, attributes[attribute]);
				}
			}
		}
		return node;
	}
	catch(exception) {
		u.bug("Exception ("+exception+") in u.ae, called from: "+arguments.callee.caller.name);
		u.bug("node:" + u.nodeId(parent, 1));
		u.xInObject(attributes);
	}
	return false;
}

/**
* Insert element
*/
Util.insertElement = u.ie = function(parent, node_type, attributes) {
	try {
		var node = (typeof(node_type) == "object") ? node_type : document.createElement(node_type);
		node = parent.insertBefore(node, parent.firstChild);
		// add attributes
		if(attributes) {
			var attribute;
			for(attribute in attributes) {
				if(attribute == "html") {
					node.innerHTML = attributes[attribute];
				}
				else {
					node.setAttribute(attribute, attributes[attribute]);
				}
			}
		}
		return node;
	}
	catch(exception) {
		u.bug("Exception ("+exception+") in u.ie, called from: "+arguments.callee.caller);
		u.bug("node:" + u.nodeId(parent, 1));
		u.xInObject(attributes);
	}
	return false;
}

// insert element in wrap-element and return wrapper
Util.wrapElement = u.we = function(node, node_type, attributes) {
	try {
		var wrapper_node = node.parentNode.insertBefore(document.createElement(node_type), node);
		if(attributes) {
			var attribute;
			for(attribute in attributes) {
				wrapper_node.setAttribute(attribute, attributes[attribute]);
			}
		}
		wrapper_node.appendChild(node);
		return wrapper_node;
	}
	catch(exception) {
		u.bug("Exception ("+exception+") in u.we, called from: "+arguments.callee.caller);
		u.bug("node:" + u.nodeId(node, 1));
		u.xInObject(attributes);
	}
	return false;
}

// wrap content of node in wrap-element and return wrapper
Util.wrapContent = u.wc = function(node, node_type, attributes) {
	try {
		var wrapper_node = document.createElement(node_type);
		if(attributes) {
			var attribute;
			for(attribute in attributes) {
				wrapper_node.setAttribute(attribute, attributes[attribute]);
			}
		}
		while(node.childNodes.length) {
			wrapper_node.appendChild(node.childNodes[0]);
		}

		node.appendChild(wrapper_node);
		return wrapper_node;
	}
	catch(exception) {
		u.bug("Exception ("+exception+") in u.wc, called from: "+arguments.callee.caller);
		u.bug("node:" + u.nodeId(node, 1));
		u.xInObject(attributes);
	}
	return false;
}

// get node textcontent shorthand (basically this is not needed for newer browsers, but required to align syntax for older browsers)
Util.textContent = u.text = function(node) {
	return node.textContent;
}

// make element clickable with options
Util.clickableElement = u.ce = function(node, options) {
	// look for link
	var a = (node.nodeName.toLowerCase() == "a" ? node : u.qs("a", node));
	if(a) {
		u.ac(node, "link");
		// only set url, if a has href attribute
		if(a.getAttribute("href") !== null) {
			node.url = a.href;
			a.removeAttribute("href");
		}
	}
	else {
		u.ac(node, "clickable");
	}

	if(typeof(u.e.click) == "function") {
		u.e.click(node);

		if(typeof(options) == "object") {
			var argument;
			for(argument in options) {

				switch(argument) {
					case "type"			: node._click_type		= options[argument]; break;
					case "method"		: node._click_method	= options[argument]; break;
				}

			}

			if(node._click_type == "link") {
				node.clicked = function(event) {
					if(event.metaKey || event.ctrlKey) {
						window.open(this.url);
					}
					else {
						// HASH navigation
						if(typeof(page.navigate) == "function") {
							page.navigate(this.url);
						}
						else {
							location.href = this.url;
						}
					}
				}
			}
		}
	}
	return node;
}

// Get JSS class value
Util.classVar = u.cv = function(node, var_name) {
//	u.bug(u.nodeId(node) + ":" + node.className);
	try {
		var regexp = new RegExp(var_name + ":[?=\\w/\\#~:.,?+=?&%@!\\-]*");
		if(node.className.match(regexp)) {
			return node.className.match(regexp)[0].replace(var_name + ":", "");
		}
	}
	catch(exception) {
		u.bug("Exception ("+exception+") in u.cv, called from: "+arguments.callee.caller);
	}
	return false;
}
// TODO: DEPRECATED
u.getIJ = u.cv;

// set classname on element, replacing all others
Util.setClass = u.sc = function(node, classname) {
	try {
		var old_class = node.className;
		node.className = classname;

		// force dom update
		node.offsetTop;
		return old_class;
	}
	catch(exception) {
		u.bug("Exception ("+exception+") in u.setClass, called from: "+arguments.callee.caller);
	}
	// return false on error
	return false;
}
// Element has classname
Util.hasClass = u.hc = function(node, classname) {
	try {
		if(classname) {
			var regexp = new RegExp("(^|\\s)(" + classname + ")(\\s|$)");
			if(regexp.test(node.className)) {
				return true;
			}
		}
	}
	catch(exception) {
		u.bug("Exception ("+exception+") in u.hasClass("+u.nodeId(node)+"), called from: "+arguments.callee.caller);
	}
	// return false on error
	return false;
}

// Add classname to element if it is not already there
Util.addClass = u.ac = function(node, classname, dom_update) {
	try {
		if(classname) {
			var regexp = new RegExp("(^|\\s)" + classname + "(\\s|$)");
			if(!regexp.test(node.className)) {
				node.className += node.className ? " " + classname : classname;

				// force dom update (performance killer, but will make rendering more detailed)
				dom_update === false ? false : node.offsetTop;
			}
			return node.className;
		}
	}
	catch(exception) {
		u.bug("Exception ("+exception+") in u.addClass, called from: "+arguments.callee.caller);
	}
	return false;
}
// Remove all instances of classname from element
Util.removeClass = u.rc = function(node, classname, dom_update) {
	try {
		if(classname) {
			var regexp = new RegExp("(\\b)" + classname + "(\\s|$)", "g");
			node.className = node.className.replace(regexp, " ").trim().replace(/[\s]{2}/g, " ");
			// force dom update (performance killer, but will make rendering more detailed)
			dom_update === false ? false : node.offsetTop;
			return node.className;
		}
	}
	catch(exception) {
		u.bug("Exception ("+exception+") in u.removeClass, called from: "+arguments.callee.caller);
	}
	return false;
}
// Toggle classname on element
// if class is applied, then remove
// if not applied, then apply
// if _classname is given as parameter, switch between to two classnames
Util.toggleClass = u.tc = function(node, classname, _classname, dom_update) {
	try {
		var regexp = new RegExp("(^|\\s)" + classname + "(\\s|$|\:)");
		if(regexp.test(node.className)) {
			u.rc(node, classname, false);
			if(_classname) {
				u.ac(node, _classname, false);
			}
		}
		else {
			u.ac(node, classname, false);
			if(_classname) {
				u.rc(node, _classname, false);
			}
		}

		dom_update === false ? false : node.offsetTop;
		return node.className;
	}
	catch(exception) {
		u.bug("Exception ("+exception+") in u.toggleClass, called from: "+arguments.callee.caller);
	}
	return false;
}

// apply style
// set style value and query DOM to force update
Util.applyStyle = u.as = function(node, property, value, dom_update) {
	node.style[property] = value;

	dom_update === false ? false : node.offsetTop;
}

// apply styles
// set style values and query DOM to force update
Util.applyStyles = u.ass = function(node, styles, dom_update) {

	if(styles) {
		var style;
		for(style in styles) {
			node.style[style] = styles[style];
		}
	}

	dom_update === false ? false : node.offsetTop;
}

// Get elements computed style value for css property
Util.getComputedStyle = u.gcs = function(node, property) {
	// query DOM to force update
	node.offsetHeight;
	// return computed style if method is supported
	if(document.defaultView && document.defaultView.getComputedStyle) {
		return document.defaultView.getComputedStyle(node, null).getPropertyValue(property);
	}
	return false;
}

// has fixed parent - lots of things needs to be calculated differently if parent is fixed
Util.hasFixedParent = u.hfp = function(node) {
	while(node.nodeName.toLowerCase() != "body") {
		if(u.gcs(node.parentNode, "position").match("fixed")) {
			return true;
		}
		node = node.parentNode;
	}
	return false;
}

// FOR CONSIDERATION

// is node in NodeList
Util.inNodeList = function(node, list) {

	var i, list_node;
	for(i = 0; list_node = list[i]; i++) {
		if(list_node = node) {
			return true;
		}
	}

	return false;
}

// is node within scope
Util.nodeWithin = u.nw = function(node, scope) {
	var node_key = u.randomString(8);
	var scope_key = u.randomString(8);
	u.ac(node, node_key);
	u.ac(scope, scope_key);

	if(u.qs("."+scope_key+" ."+node_key)) {

		u.rc(node, node_key);
		u.rc(scope, scope_key);

		return true;
	}

	u.rc(node, node_key);
	u.rc(scope, scope_key);
	return false;
}

<commit_msg>fix u.ce type link event<commit_after>Util.querySelector = u.qs = function(query, scope) {
	scope = scope ? scope : document;
	return scope.querySelector(query);
}
Util.querySelectorAll = u.qsa = function(query, scope) {
	scope = scope ? scope : document;
	return scope.querySelectorAll(query);
}

// Get element (id/class/tag)
// Returns elementById if possible
// else Returns first element with (partial) matching classname from target
// If no matches, return first element with tagname from target
Util.getElement = u.ge = function(identifier, scope) {
	var node, i, regexp;
	if(document.getElementById(identifier)) {
		return document.getElementById(identifier);
	}
	scope = scope ? scope : document;
	regexp = new RegExp("(^|\\s)" + identifier + "(\\s|$|\:)");
	for(i = 0; node = scope.getElementsByTagName("*")[i]; i++) {
		if(regexp.test(node.className)) {
			return node;
		}
	}
	return scope.getElementsByTagName(identifier).length ? scope.getElementsByTagName(identifier)[0] : false;
}
// Get elements (class/tag)
// Returns all elements with (partial) matching classname from target
// If no matches, return elements with tagname from target
Util.getElements = u.ges = function(identifier, scope) {
	var node, i, regexp;
	var nodes = new Array();
	scope = scope ? scope : document;
	regexp = new RegExp("(^|\\s)" + identifier + "(\\s|$|\:)");
	for(i = 0; node = scope.getElementsByTagName("*")[i]; i++) {
		if(regexp.test(node.className)) {
			nodes.push(node);
		}
	}
	return nodes.length ? nodes : scope.getElementsByTagName(identifier);
}

// get parent node of type
Util.parentNode = u.pn = function(node, node_type) {
	if(node_type) {
		if(node.parentNode) {
			var parent = node.parentNode;
		}
//		u.bug(e.parentNode.nodeName.toLowerCase());
		while(parent.nodeName.toLowerCase() != node_type.toLowerCase()) {
			if(parent.parentNode) {
				parent = parent.parentNode;
			}
			else {
				return false;
			}
		}
		return parent;
	}
	else {
		return node.parentNode;
	}
}

// Returns previous sibling, not counting text nodes as siblings and ignoring optional exclude=className/nodeName
// TODO: extend with include option and make exclude and include list
Util.previousSibling = u.ps = function(node, exclude) {
	node = node.previousSibling;
	while(node && (node.nodeType == 3 || node.nodeType == 8 || exclude && (u.hc(node, exclude) || node.nodeName.toLowerCase().match(exclude)))) {
		node = node.previousSibling;
	}
	return node;
}

// Returns next sibling, not counting text nodes as siblings and ignoring optional exclude=className/nodeName
// TODO: extend with include option and make exclude and include list
Util.nextSibling = u.ns = function(node, exclude) {
	node = node.nextSibling;
	while(node && (node.nodeType == 3 || node.nodeType == 8 || exclude && (u.hc(node, exclude) || node.nodeName.toLowerCase().match(exclude)))) {
		node = node.nextSibling;
	}
	return node;
}

// TODO: extend with include option and make exclude and include list
Util.childNodes = u.cn = function(node, exclude) {
	var i, child;
	var children = new Array();
	for(i = 0; child = node.childNodes[i]; i++) {
		if(child && child.nodeType != 3 && child.nodeType != 8 && (!exclude || (!u.hc(child, exclude) && !child.nodeName.toLowerCase().match(exclude) ))) {
			children.push(child);
		}
	}
	return children;
}

/**
* append child to element e
* add reference to e on node
* @param node e html element to append new child to
* @param String node_type new node to create and append - can be either node type of actual node
* @param Optional ClassName or attribute object
* return HTML node
*/
Util.appendElement = u.ae = function(parent, node_type, attributes) {
	try {
		// is node_type already DOM node
		var node = (typeof(node_type) == "object") ? node_type : document.createElement(node_type);
		node = parent.appendChild(node);

		// add attributes
		if(attributes) {
			var attribute;
			for(attribute in attributes) {
				if(attribute == "html") {
					node.innerHTML = attributes[attribute];
				}
				else {
					node.setAttribute(attribute, attributes[attribute]);
				}
			}
		}
		return node;
	}
	catch(exception) {
		u.bug("Exception ("+exception+") in u.ae, called from: "+arguments.callee.caller.name);
		u.bug("node:" + u.nodeId(parent, 1));
		u.xInObject(attributes);
	}
	return false;
}

/**
* Insert element
*/
Util.insertElement = u.ie = function(parent, node_type, attributes) {
	try {
		var node = (typeof(node_type) == "object") ? node_type : document.createElement(node_type);
		node = parent.insertBefore(node, parent.firstChild);
		// add attributes
		if(attributes) {
			var attribute;
			for(attribute in attributes) {
				if(attribute == "html") {
					node.innerHTML = attributes[attribute];
				}
				else {
					node.setAttribute(attribute, attributes[attribute]);
				}
			}
		}
		return node;
	}
	catch(exception) {
		u.bug("Exception ("+exception+") in u.ie, called from: "+arguments.callee.caller);
		u.bug("node:" + u.nodeId(parent, 1));
		u.xInObject(attributes);
	}
	return false;
}

// insert element in wrap-element and return wrapper
Util.wrapElement = u.we = function(node, node_type, attributes) {
	try {
		var wrapper_node = node.parentNode.insertBefore(document.createElement(node_type), node);
		if(attributes) {
			var attribute;
			for(attribute in attributes) {
				wrapper_node.setAttribute(attribute, attributes[attribute]);
			}
		}
		wrapper_node.appendChild(node);
		return wrapper_node;
	}
	catch(exception) {
		u.bug("Exception ("+exception+") in u.we, called from: "+arguments.callee.caller);
		u.bug("node:" + u.nodeId(node, 1));
		u.xInObject(attributes);
	}
	return false;
}

// wrap content of node in wrap-element and return wrapper
Util.wrapContent = u.wc = function(node, node_type, attributes) {
	try {
		var wrapper_node = document.createElement(node_type);
		if(attributes) {
			var attribute;
			for(attribute in attributes) {
				wrapper_node.setAttribute(attribute, attributes[attribute]);
			}
		}
		while(node.childNodes.length) {
			wrapper_node.appendChild(node.childNodes[0]);
		}

		node.appendChild(wrapper_node);
		return wrapper_node;
	}
	catch(exception) {
		u.bug("Exception ("+exception+") in u.wc, called from: "+arguments.callee.caller);
		u.bug("node:" + u.nodeId(node, 1));
		u.xInObject(attributes);
	}
	return false;
}

// get node textcontent shorthand (basically this is not needed for newer browsers, but required to align syntax for older browsers)
Util.textContent = u.text = function(node) {
	return node.textContent;
}

// make element clickable with options
Util.clickableElement = u.ce = function(node, options) {
	// look for link
	var a = (node.nodeName.toLowerCase() == "a" ? node : u.qs("a", node));
	if(a) {
		u.ac(node, "link");
		// only set url, if a has href attribute
		if(a.getAttribute("href") !== null) {
			node.url = a.href;
			a.removeAttribute("href");
		}
	}
	else {
		u.ac(node, "clickable");
	}

	if(typeof(u.e.click) == "function") {
		u.e.click(node);

		if(typeof(options) == "object") {
			var argument;
			for(argument in options) {

				switch(argument) {
					case "type"			: node._click_type		= options[argument]; break;
					case "method"		: node._click_method	= options[argument]; break;
				}

			}

			if(node._click_type == "link") {
				node.clicked = function(event) {
					if(event && (event.metaKey || event.ctrlKey)) {
						window.open(this.url);
					}
					else {
						// HASH navigation
						if(typeof(page.navigate) == "function") {
							page.navigate(this.url);
						}
						else {
							location.href = this.url;
						}
					}
				}
			}
		}
	}
	return node;
}

// Get JSS class value
Util.classVar = u.cv = function(node, var_name) {
//	u.bug(u.nodeId(node) + ":" + node.className);
	try {
		var regexp = new RegExp(var_name + ":[?=\\w/\\#~:.,?+=?&%@!\\-]*");
		if(node.className.match(regexp)) {
			return node.className.match(regexp)[0].replace(var_name + ":", "");
		}
	}
	catch(exception) {
		u.bug("Exception ("+exception+") in u.cv, called from: "+arguments.callee.caller);
	}
	return false;
}
// TODO: DEPRECATED
u.getIJ = u.cv;

// set classname on element, replacing all others
Util.setClass = u.sc = function(node, classname) {
	try {
		var old_class = node.className;
		node.className = classname;

		// force dom update
		node.offsetTop;
		return old_class;
	}
	catch(exception) {
		u.bug("Exception ("+exception+") in u.setClass, called from: "+arguments.callee.caller);
	}
	// return false on error
	return false;
}
// Element has classname
Util.hasClass = u.hc = function(node, classname) {
	try {
		if(classname) {
			var regexp = new RegExp("(^|\\s)(" + classname + ")(\\s|$)");
			if(regexp.test(node.className)) {
				return true;
			}
		}
	}
	catch(exception) {
		u.bug("Exception ("+exception+") in u.hasClass("+u.nodeId(node)+"), called from: "+arguments.callee.caller);
	}
	// return false on error
	return false;
}

// Add classname to element if it is not already there
Util.addClass = u.ac = function(node, classname, dom_update) {
	try {
		if(classname) {
			var regexp = new RegExp("(^|\\s)" + classname + "(\\s|$)");
			if(!regexp.test(node.className)) {
				node.className += node.className ? " " + classname : classname;

				// force dom update (performance killer, but will make rendering more detailed)
				dom_update === false ? false : node.offsetTop;
			}
			return node.className;
		}
	}
	catch(exception) {
		u.bug("Exception ("+exception+") in u.addClass, called from: "+arguments.callee.caller);
	}
	return false;
}
// Remove all instances of classname from element
Util.removeClass = u.rc = function(node, classname, dom_update) {
	try {
		if(classname) {
			var regexp = new RegExp("(\\b)" + classname + "(\\s|$)", "g");
			node.className = node.className.replace(regexp, " ").trim().replace(/[\s]{2}/g, " ");
			// force dom update (performance killer, but will make rendering more detailed)
			dom_update === false ? false : node.offsetTop;
			return node.className;
		}
	}
	catch(exception) {
		u.bug("Exception ("+exception+") in u.removeClass, called from: "+arguments.callee.caller);
	}
	return false;
}
// Toggle classname on element
// if class is applied, then remove
// if not applied, then apply
// if _classname is given as parameter, switch between to two classnames
Util.toggleClass = u.tc = function(node, classname, _classname, dom_update) {
	try {
		var regexp = new RegExp("(^|\\s)" + classname + "(\\s|$|\:)");
		if(regexp.test(node.className)) {
			u.rc(node, classname, false);
			if(_classname) {
				u.ac(node, _classname, false);
			}
		}
		else {
			u.ac(node, classname, false);
			if(_classname) {
				u.rc(node, _classname, false);
			}
		}

		dom_update === false ? false : node.offsetTop;
		return node.className;
	}
	catch(exception) {
		u.bug("Exception ("+exception+") in u.toggleClass, called from: "+arguments.callee.caller);
	}
	return false;
}

// apply style
// set style value and query DOM to force update
Util.applyStyle = u.as = function(node, property, value, dom_update) {
	node.style[property] = value;

	dom_update === false ? false : node.offsetTop;
}

// apply styles
// set style values and query DOM to force update
Util.applyStyles = u.ass = function(node, styles, dom_update) {

	if(styles) {
		var style;
		for(style in styles) {
			node.style[style] = styles[style];
		}
	}

	dom_update === false ? false : node.offsetTop;
}

// Get elements computed style value for css property
Util.getComputedStyle = u.gcs = function(node, property) {
	// query DOM to force update
	node.offsetHeight;
	// return computed style if method is supported
	if(document.defaultView && document.defaultView.getComputedStyle) {
		return document.defaultView.getComputedStyle(node, null).getPropertyValue(property);
	}
	return false;
}

// has fixed parent - lots of things needs to be calculated differently if parent is fixed
Util.hasFixedParent = u.hfp = function(node) {
	while(node.nodeName.toLowerCase() != "body") {
		if(u.gcs(node.parentNode, "position").match("fixed")) {
			return true;
		}
		node = node.parentNode;
	}
	return false;
}

// FOR CONSIDERATION

// is node in NodeList
Util.inNodeList = function(node, list) {

	var i, list_node;
	for(i = 0; list_node = list[i]; i++) {
		if(list_node = node) {
			return true;
		}
	}

	return false;
}

// is node within scope
Util.nodeWithin = u.nw = function(node, scope) {
	var node_key = u.randomString(8);
	var scope_key = u.randomString(8);
	u.ac(node, node_key);
	u.ac(scope, scope_key);

	if(u.qs("."+scope_key+" ."+node_key)) {

		u.rc(node, node_key);
		u.rc(scope, scope_key);

		return true;
	}

	u.rc(node, node_key);
	u.rc(scope, scope_key);
	return false;
}

<|endoftext|>