<commit_before>module.exports = handler

const fs = require('fs')
const glob = require('glob')
const _path = require('path')
const $rdf = require('rdflib')
const Negotiator = require('negotiator')
const url = require('url')
const mime = require('mime-types')

const debug = require('debug')('solid:get')
const debugGlob = require('debug')('solid:glob')
const allow = require('./allow')

const utils = require('../utils.js')
const translate = require('../utils.js').translate
const error = require('../http-error')

const RDFs = require('../ldp').RDF_MIME_TYPES

function handler (req, res, next) {
  const ldp = req.app.locals.ldp
  const includeBody = req.method === 'GET'
  const negotiator = new Negotiator(req)
  const baseUri = utils.getFullUri(req)
  const path = res.locals.path || req.path
  const requestedType = negotiator.mediaType()
  let possibleRDFType = negotiator.mediaType(RDFs)
  // Fallback to text/turtle if content type is unknown
  possibleRDFType = (!possibleRDFType) ? 'text/turtle' : possibleRDFType

  res.header('MS-Author-Via', 'SPARQL')

  // Set live updates
  if (ldp.live) {
    res.header('Updates-Via', utils.getBaseUri(req).replace(/^http/, 'ws'))
  }

  debug(req.originalUrl + ' on ' + req.hostname)

  const options = {
    'hostname': req.hostname,
    'path': path,
    'baseUri': baseUri,
    'includeBody': includeBody,
    'possibleRDFType': possibleRDFType,
    'range': req.headers.range
  }
  ldp.get(options, function (err, ret) {
    // use globHandler if magic is detected
    if (err && err.status === 404 && glob.hasMagic(path)) {
      debug('forwarding to glob request')
      return globHandler(req, res, next)
    }

    // Handle error
    if (err) {
      debug(req.method + ' -- Error: ' + err.status + ' ' + err.message)
      return next(err)
    }

    let stream
    let contentType
    let container
    let contentRange
    let chunksize

    if (ret) {
      stream = ret.stream
      contentType = ret.contentType
      container = ret.container
      contentRange = ret.contentRange
      chunksize = ret.chunksize
    }

    // Till here it must exist
    if (!includeBody) {
      debug('HEAD only')
      res.sendStatus(200)
      return next()
    }

    // Handle dataBrowser
    if (requestedType && requestedType.includes('text/html')) {
      let mimeTypeByExt = mime.lookup(_path.basename(path))
      let isHtmlResource = mimeTypeByExt && mimeTypeByExt.includes('html')
      let useDataBrowser = ldp.dataBrowserPath && (
          container ||
          RDFs.includes(contentType) && !isHtmlResource && !ldp.suppressDataBrowser)

      if (useDataBrowser) {
        res.set('Content-Type', 'text/html')
        const defaultDataBrowser = _path.join(__dirname, '../../static/databrowser.html')
        const dataBrowserPath = ldp.dataBrowserPath === 'default' ? defaultDataBrowser : ldp.dataBrowserPath
        debug('   sending data browser file: ' + dataBrowserPath)
        res.sendFile(dataBrowserPath)
        return
      } else if (stream) {
        res.setHeader('Content-Type', contentType)
        return stream.pipe(res)
      }
    }

    // If request accepts the content-type we found
    if (stream && negotiator.mediaType([contentType])) {
      res.setHeader('Content-Type', contentType)
      if (contentRange) {
        const headers = { 'Content-Range': contentRange, 'Accept-Ranges': 'bytes', 'Content-Length': chunksize }
        res.writeHead(206, headers)
        return stream.pipe(res)
      } else {
        return stream.pipe(res)
      }
    }

    // If it is not in our RDFs we can't even translate,
    // Sorry, we can't help
    if (!possibleRDFType) {
      return next(error(406, 'Cannot serve requested type: ' + contentType))
    }

    // Translate from the contentType found to the possibleRDFType desired
    translate(stream, baseUri, contentType, possibleRDFType, function (err, data) {
      if (err) {
        debug('error translating: ' + req.originalUrl + ' ' + contentType + ' -> ' + possibleRDFType + ' -- ' + 500 + ' ' + err.message)
        return next(error(500, 'Error translating between RDF formats'))
      }
      debug(req.originalUrl + ' translating ' + contentType + ' -> ' + possibleRDFType)
      res.setHeader('Content-Type', possibleRDFType)
      res.send(data)
      return next()
    })
  })
}

function globHandler (req, res, next) {
  const ldp = req.app.locals.ldp
  const root = !ldp.multiuser ? ldp.root : ldp.root + req.hostname + '/'
  const filename = utils.uriToFilename(req.path, root)
  const uri = utils.getFullUri(req)
  const requestUri = url.resolve(uri, req.path)

  const globOptions = {
    noext: true,
    nobrace: true,
    nodir: true
  }

  glob(filename, globOptions, function (err, matches) {
    if (err || matches.length === 0) {
      debugGlob('No files matching the pattern')
      return next(error(404, 'No files matching glob pattern'))
    }

    // Matches found
    const globGraph = $rdf.graph()

    let reqOrigin = utils.getBaseUri(req)

    debugGlob('found matches ' + matches)
    Promise.all(matches.map(match => new Promise((resolve, reject) => {
      const baseUri = reqOrigin + '/' + match.substr(root.length)
      fs.readFile(match, {encoding: 'utf8'}, function (err, fileData) {
        if (err) {
          debugGlob('error ' + err)
          return resolve()
        }
        aclAllow(match, req, res, function (allowed) {
          if (!match.endsWith('.ttl') || !allowed) {
            return resolve()
          }
          try {
            $rdf.parse(fileData, globGraph, baseUri, 'text/turtle')
          } catch (parseErr) {
            debugGlob(`error parsing ${match}: ${parseErr}`)
          }
          return resolve()
        })
      })
    })))
    .then(() => {
      const data = $rdf.serialize(undefined, globGraph, requestUri, 'text/turtle')
      // TODO this should be added as a middleware in the routes
      res.setHeader('Content-Type', 'text/turtle')
      debugGlob('returning turtle')

      res.send(data)
      return next()
    })
  })
}

function aclAllow (match, req, res, callback) {
  const ldp = req.app.locals.ldp

  if (!ldp.webid) {
    return callback(true)
  }

  const root = ldp.multiuser ? ldp.root + req.hostname + '/' : ldp.root
  const relativePath = '/' + _path.relative(root, match)
  res.locals.path = relativePath
  allow('Read', req, res, function (err) {
    callback(err)
  })
}
<commit_msg>Correct use of allow handler.<commit_after>module.exports = handler

const fs = require('fs')
const glob = require('glob')
const _path = require('path')
const $rdf = require('rdflib')
const Negotiator = require('negotiator')
const url = require('url')
const mime = require('mime-types')

const debug = require('debug')('solid:get')
const debugGlob = require('debug')('solid:glob')
const allow = require('./allow')

const utils = require('../utils.js')
const translate = require('../utils.js').translate
const error = require('../http-error')

const RDFs = require('../ldp').RDF_MIME_TYPES

function handler (req, res, next) {
  const ldp = req.app.locals.ldp
  const includeBody = req.method === 'GET'
  const negotiator = new Negotiator(req)
  const baseUri = utils.getFullUri(req)
  const path = res.locals.path || req.path
  const requestedType = negotiator.mediaType()
  let possibleRDFType = negotiator.mediaType(RDFs)
  // Fallback to text/turtle if content type is unknown
  possibleRDFType = (!possibleRDFType) ? 'text/turtle' : possibleRDFType

  res.header('MS-Author-Via', 'SPARQL')

  // Set live updates
  if (ldp.live) {
    res.header('Updates-Via', utils.getBaseUri(req).replace(/^http/, 'ws'))
  }

  debug(req.originalUrl + ' on ' + req.hostname)

  const options = {
    'hostname': req.hostname,
    'path': path,
    'baseUri': baseUri,
    'includeBody': includeBody,
    'possibleRDFType': possibleRDFType,
    'range': req.headers.range
  }
  ldp.get(options, function (err, ret) {
    // use globHandler if magic is detected
    if (err && err.status === 404 && glob.hasMagic(path)) {
      debug('forwarding to glob request')
      return globHandler(req, res, next)
    }

    // Handle error
    if (err) {
      debug(req.method + ' -- Error: ' + err.status + ' ' + err.message)
      return next(err)
    }

    let stream
    let contentType
    let container
    let contentRange
    let chunksize

    if (ret) {
      stream = ret.stream
      contentType = ret.contentType
      container = ret.container
      contentRange = ret.contentRange
      chunksize = ret.chunksize
    }

    // Till here it must exist
    if (!includeBody) {
      debug('HEAD only')
      res.sendStatus(200)
      return next()
    }

    // Handle dataBrowser
    if (requestedType && requestedType.includes('text/html')) {
      let mimeTypeByExt = mime.lookup(_path.basename(path))
      let isHtmlResource = mimeTypeByExt && mimeTypeByExt.includes('html')
      let useDataBrowser = ldp.dataBrowserPath && (
          container ||
          RDFs.includes(contentType) && !isHtmlResource && !ldp.suppressDataBrowser)

      if (useDataBrowser) {
        res.set('Content-Type', 'text/html')
        const defaultDataBrowser = _path.join(__dirname, '../../static/databrowser.html')
        const dataBrowserPath = ldp.dataBrowserPath === 'default' ? defaultDataBrowser : ldp.dataBrowserPath
        debug('   sending data browser file: ' + dataBrowserPath)
        res.sendFile(dataBrowserPath)
        return
      } else if (stream) {
        res.setHeader('Content-Type', contentType)
        return stream.pipe(res)
      }
    }

    // If request accepts the content-type we found
    if (stream && negotiator.mediaType([contentType])) {
      res.setHeader('Content-Type', contentType)
      if (contentRange) {
        const headers = { 'Content-Range': contentRange, 'Accept-Ranges': 'bytes', 'Content-Length': chunksize }
        res.writeHead(206, headers)
        return stream.pipe(res)
      } else {
        return stream.pipe(res)
      }
    }

    // If it is not in our RDFs we can't even translate,
    // Sorry, we can't help
    if (!possibleRDFType) {
      return next(error(406, 'Cannot serve requested type: ' + contentType))
    }

    // Translate from the contentType found to the possibleRDFType desired
    translate(stream, baseUri, contentType, possibleRDFType, function (err, data) {
      if (err) {
        debug('error translating: ' + req.originalUrl + ' ' + contentType + ' -> ' + possibleRDFType + ' -- ' + 500 + ' ' + err.message)
        return next(error(500, 'Error translating between RDF formats'))
      }
      debug(req.originalUrl + ' translating ' + contentType + ' -> ' + possibleRDFType)
      res.setHeader('Content-Type', possibleRDFType)
      res.send(data)
      return next()
    })
  })
}

function globHandler (req, res, next) {
  const ldp = req.app.locals.ldp
  const root = !ldp.multiuser ? ldp.root : ldp.root + req.hostname + '/'
  const filename = utils.uriToFilename(req.path, root)
  const uri = utils.getFullUri(req)
  const requestUri = url.resolve(uri, req.path)

  const globOptions = {
    noext: true,
    nobrace: true,
    nodir: true
  }

  glob(filename, globOptions, function (err, matches) {
    if (err || matches.length === 0) {
      debugGlob('No files matching the pattern')
      return next(error(404, 'No files matching glob pattern'))
    }

    // Matches found
    const globGraph = $rdf.graph()

    let reqOrigin = utils.getBaseUri(req)

    debugGlob('found matches ' + matches)
    Promise.all(matches.map(match => new Promise((resolve, reject) => {
      const baseUri = reqOrigin + '/' + match.substr(root.length)
      fs.readFile(match, {encoding: 'utf8'}, function (err, fileData) {
        if (err) {
          debugGlob('error ' + err)
          return resolve()
        }
        aclAllow(match, req, res, function (allowed) {
          if (!match.endsWith('.ttl') || !allowed) {
            return resolve()
          }
          try {
            $rdf.parse(fileData, globGraph, baseUri, 'text/turtle')
          } catch (parseErr) {
            debugGlob(`error parsing ${match}: ${parseErr}`)
          }
          return resolve()
        })
      })
    })))
    .then(() => {
      const data = $rdf.serialize(undefined, globGraph, requestUri, 'text/turtle')
      // TODO this should be added as a middleware in the routes
      res.setHeader('Content-Type', 'text/turtle')
      debugGlob('returning turtle')

      res.send(data)
      return next()
    })
  })
}

function aclAllow (match, req, res, callback) {
  const ldp = req.app.locals.ldp

  if (!ldp.webid) {
    return callback(true)
  }

  const root = ldp.multiuser ? ldp.root + req.hostname + '/' : ldp.root
  const relativePath = '/' + _path.relative(root, match)
  res.locals.path = relativePath
  allow('Read')(req, res, err => callback(!err))
}
<|endoftext|>


<commit_before>/*
 * Copyright (c) Microsoft.  All rights reserved. Licensed under the MIT license.
 * See LICENSE in the project root for license information.
 */

(function(){
  'use strict';

  // The Office initialize function must be run each time a new page is loaded.
  Office.initialize = function(reason){
    $(document).ready(function(){
      app.initialize();

      $('#rantButton').click(fadeRant);

      displayTotalRantCount();

      // When the user starts typing, clear all visible messages on the screen.
      $('#rantInput').on('input', function() {
        clearMessages();
      });

    });
  };
})();

// Fades whatever the user wrote into "the void".
function fadeRant(){

  // Make sure the message shown after a rant it cleared.
  clearMessages();

  // Only post if rant message is not empty.
  if ($('#rantInput').val() === ''){
    app.showNotification("Nothing to scream","Enter your feelings in the text field before hitting the scream button.");
  }
  else {

  // Store the font size I started with, since I am going to revert to it.
  var originalSize = jQuery('#rantInput').css('fontSize');

  $('#rantInput').animate({
    opacity: 0.00,
    fontSize: "1px"
    }, 1200, function(){

      // Animation complete - show message
      $('#rantMessage').animate({opacity: 1.00},600);

      // Show input field again
      $('#rantInput').val('');
      $('#rantInput').animate({opacity: 1.00, fontSize: originalSize },600);

      updateRantCount();
      displayTotalRantCount();
    });
  }
};

 // Clears notification message and rant message.
 function clearMessages() {
   $("#rantMessage").css({ opacity: 0.0 });
   $('#notification-message').hide();
 }

 // Stores an updated count of the total number of rants this user has "screamed" into roaming settings.
 // See https://msdn.microsoft.com/EN-US/library/office/fp123509.aspx#PersistRoamingSettingsMailApp
 function updateRantCount() {
   var rantCount = getRantCount();
   rantCount++;
   setRantCount(rantCount);
 }

 function getRantCount() {
   var settings = Office.context.roamingSettings;
   var count = settings.get("rantCount");

   // If rantCount has never been set, it will be null.
   if (isNaN(parseInt(count))) {
     count = 0;
   }
   return count;
 }

 function setRantCount(newCount) {
   var settings = Office.context.roamingSettings;
   settings.set("rantCount", newCount);
   settings.saveAsync(saveSettingsCallback);
 }

 function displayTotalRantCount() {
   var total = getRantCount();

   $('#rantCountMessage').text("Total number of rants:" + " " + total);
 }

// Saves all roaming settings.
function saveSettingsCallback(asyncResult) {
    if (asyncResult.status === Office.AsyncResultStatus.Failed) {

        // Handle the failure
        var err = asyncResult.error;
        app.showNotification("Failed to update Rant Count", err.name + ": " + err.message);
    }
}

<commit_msg>Check for empty message.<commit_after>/*
 * Copyright (c) Microsoft.  All rights reserved. Licensed under the MIT license.
 * See LICENSE in the project root for license information.
 */

(function(){
  'use strict';

  // The Office initialize function must be run each time a new page is loaded.
  Office.initialize = function(reason){
    $(document).ready(function(){
      app.initialize();

      $('#rantButton').click(fadeRant);

      displayTotalRantCount();

      // When the user starts typing, clear all visible messages on the screen.
      $('#rantInput').on('input', function() {
        clearMessages();
      });

    });
  };
})();

// Fades whatever the user wrote into 'the void'.
function fadeRant(){

  // Make sure the message shown after a rant it cleared.
  clearMessages();

  // Only post if rant message is not empty.
  if ($('#rantInput').val().trim() === ''){
    app.showNotification('Nothing to scream','Enter your feelings in the text field before hitting the scream button.');
  }
  else {
    // Store the font size I started with, since I am going to revert to it.
    var originalSize = jQuery('#rantInput').css('fontSize');

    $('#rantInput').animate({
        opacity: 0.00,
        fontSize: '1px'
        }, 1200, function(){

        // Animation complete - show message
        $('#rantMessage').animate({opacity: 1.00},600);

        // Show input field again
        $('#rantInput').val('');
        $('#rantInput').animate({opacity: 1.00, fontSize: originalSize },600);

        incrementRantCount();
        displayTotalRantCount();
        });
  }
}

 // Clears notification message and rant message.
 function clearMessages() {
    $('#rantMessage').css({ opacity: 0.0 });
    $('#notification-message').hide();
 }

 function getRantCount() {
    var settings = Office.context.roamingSettings;
    var count = settings.get('rantCount');

    // If rantCount has never been set, it will be null.
    if (isNaN(parseInt(count))) {
        count = 0;
    }
    return count;
 }

  // Stores an updated count of the total number of rants this user has 'screamed' into roaming settings.
 // See https://msdn.microsoft.com/EN-US/library/office/fp123509.aspx#PersistRoamingSettingsMailApp
 function incrementRantCount() {

    var rantCount = getRantCount();
    rantCount++;
    var settings = Office.context.roamingSettings;
    settings.set('rantCount', rantCount);
    settings.saveAsync(saveSettingsCallback);
 }

 function displayTotalRantCount() {
    var total = getRantCount();

    $('#rantCountMessage').text('Total number of rants:' + ' ' + total);
 }

// Saves all roaming settings.
function saveSettingsCallback(asyncResult) {
    if (asyncResult.status === Office.AsyncResultStatus.Failed) {

        // Handle the failure
        var err = asyncResult.error;
        app.showNotification('Failed to update Rant Count', err.name + ': ' + err.message);
    }
}

<|endoftext|>


<commit_before>/*
    coveraje - a simple javascript code coverage tool.

    common helper
    --------------------------
    loads a specific tdd framework helper if requested and runs the file

    Copyright (c) 2011 Wolfgang Kluge (klugesoftware.de, gehirnwindung.de)
    See LICENSE in the root folder for more details.
*/

(function () {
    "use strict";

    var helper = (function () {
        var requirePostfix = "$$_cj_inspected", // see Runtime.js
            path = require("path"),
            Module = require("module");

        function requireSubst(self) {
            return function (m) {

                function compile(content, mod, filename, dirname) {
                    var Script = process.binding('evals').NodeScript;
                    var runInThisContext = Script.runInThisContext;

                    // create wrapper function
                    //
                    var wrapper = Module.wrap(content);

                    var compiledWrapper = runInThisContext(wrapper, filename, true);
                    var args = [mod.exports, requireSubst(mod), mod, filename, dirname];

                    return compiledWrapper.apply(mod.exports, args);
                }

                var pathToCode;
                pathToCode = Module._resolveFilename(m, self || module);
                if (Array.isArray(pathToCode)) pathToCode = pathToCode[1];

                if (pathToCode != null && path.existsSync(pathToCode)) {
                    var code = require("fs").readFileSync(pathToCode, 'utf-8');

                    if (code.length > 1) {
                        if (code.substr(0, 2) === "#!") {
                            code = code.substr(code.indexOf("\n") + 1);
                        }
                    }

                    var filepath = path.resolve(pathToCode);
                    var dirname = path.dirname(filepath);
                    var cacheKey = filepath;

                    // test if there is a coveraje-injected version
                    var cachedModule = Module._cache[filepath + requirePostfix];
                    if (cachedModule) {
                        return cachedModule.exports;
                    }

                    cachedModule = Module._cache[filepath];
                    if (cachedModule) {
                        return cachedModule.exports;
                    }

                    var mod = new Module(filepath, module);
                    Module._cache[filepath] = mod;

                    mod.filename = filepath;
                    mod.paths = Module._nodeModulePaths(dirname);

                    compile(code, mod, filepath, dirname);

                    mod.loaded = true;

                    return mod.exports;
                }
                return require(m);
            };
        }

        return {
            requireSubst: requireSubst
        };
    }());

    exports.run = function (testPath, framework, event, options) {

        var fwh;
        if (framework != null) {
            try {
                fwh = require("./" + framework);
            } catch (ex1) {
                event
                    .error("TDD framework helper '" + framework + "'\n" + ex1.message)
                    .complete();
                return;
            }
        }
        var fullPath = require("path").resolve(testPath);

        // hack: delete from cache if present
        if (fullPath in require.cache) delete require.cache[fullPath];

        var req = helper.requireSubst();
        if (fwh != null) {
            fwh.run(testPath, event, options, req);
        } else {
            var hasOnReady;
            try {
                var otc = req(fullPath).onTestComplete;
                if (typeof otc === "function") {
                    hasOnReady = true;
                    otc(function () {
                        event.complete();
                    });
                }
            } catch (ex2) {
                event.error(ex2);
            }
            if (!hasOnReady) {
                event.complete();
            }
        }
    };

}());<commit_msg>Append resolve, extensions, etc. to require()-substitute<commit_after>/*
    coveraje - a simple javascript code coverage tool.

    common helper
    --------------------------
    loads a specific tdd framework helper if requested and runs the file

    Copyright (c) 2011 Wolfgang Kluge (klugesoftware.de, gehirnwindung.de)
    See LICENSE in the root folder for more details.
*/

(function () {
    "use strict";

    var helper = (function () {
        var requirePostfix = "$$_cj_inspected", // see Runtime.js
            path = require("path"),
            Module = require("module");

        function requireSubst(self) {

            var req = function (m) {

                function compile(content, mod, filename, dirname) {
                    var Script = process.binding('evals').NodeScript;
                    var runInThisContext = Script.runInThisContext;

                    // create wrapper function
                    //
                    var wrapper = Module.wrap(content);

                    var compiledWrapper = runInThisContext(wrapper, filename, true);
                    var args = [mod.exports, requireSubst(mod), mod, filename, dirname];

                    return compiledWrapper.apply(mod.exports, args);
                }

                var pathToCode;
                pathToCode = Module._resolveFilename(m, self || module);
                if (Array.isArray(pathToCode)) pathToCode = pathToCode[1];

                if (pathToCode != null && path.existsSync(pathToCode)) {
                    var code = require("fs").readFileSync(pathToCode, 'utf-8');

                    if (code.length > 1) {
                        if (code.substr(0, 2) === "#!") {
                            code = code.substr(code.indexOf("\n") + 1);
                        }
                    }

                    var filepath = path.resolve(pathToCode);
                    var dirname = path.dirname(filepath);
                    var cacheKey = filepath;

                    // test if there is a coveraje-injected version
                    var cachedModule = Module._cache[filepath + requirePostfix];
                    if (cachedModule) {
                        return cachedModule.exports;
                    }

                    cachedModule = Module._cache[filepath];
                    if (cachedModule) {
                        return cachedModule.exports;
                    }

                    var mod = new Module(filepath, module);
                    Module._cache[filepath] = mod;

                    mod.filename = filepath;
                    mod.paths = Module._nodeModulePaths(dirname);

                    compile(code, mod, filepath, dirname);

                    mod.loaded = true;

                    return mod.exports;
                }
                return require(m);
            };

            req.resolve = require.resolve;
            req.cache = require.cache;
            req.registerExtension = require.registerExtension;
            req.extensions = require.extensions;
            return req;
        }

        return {
            requireSubst: requireSubst
        };
    }());

    exports.run = function (testPath, framework, event, options) {

        var fwh;
        if (framework != null) {
            try {
                fwh = require("./" + framework);
            } catch (ex1) {
                event
                    .error("TDD framework helper '" + framework + "'\n" + ex1.message)
                    .complete();
                return;
            }
        }
        var fullPath = require("path").resolve(testPath);

        // hack: delete from cache if present
        if (fullPath in require.cache) delete require.cache[fullPath];

        var req = helper.requireSubst();
        if (fwh != null) {
            fwh.run(testPath, event, options, req);
        } else {
            var hasOnReady;
            try {
                var otc = req(fullPath).onTestComplete;
                if (typeof otc === "function") {
                    hasOnReady = true;
                    otc(function () {
                        event.complete();
                    });
                }
            } catch (ex2) {
                event.error(ex2);
            }
            if (!hasOnReady) {
                event.complete();
            }
        }
    };

}());<|endoftext|>


<commit_before>'use strict';

const indent = require('../utils/cnsl').indent

  , RE_WRAPPED = /\$m\['[^']+'\] = \(function \(module, exports\) {/;

/**
 * Wrap 'content' in module definition
 * @param {String} id
 * @param {String} content
 * @returns {String}
 */
module.exports = function (id, content) {
  // Reset regex
  RE_WRAPPED.lastIndex = 0;

  // Don't wrap if already wrapped
  if (!RE_WRAPPED.test(content)) {
    content = `$m['${id}']=(function(module,exports){\n  module=this;exports=module.exports;\n${indent(content, 2)}\n  return module.exports;\n}).call({filename:'${id}',exports:{}});`;
  }

  return content;
};<commit_msg>adjust indentation/whitespace<commit_after>'use strict';

const indent = require('../utils/cnsl').indent

  , RE_WRAPPED = /\$m\['[^']+'\] = \(function \(module, exports\) {/;

/**
 * Wrap 'content' in module definition
 * @param {String} id
 * @param {String} content
 * @returns {String}
 */
module.exports = function (id, content) {
  // Reset regex
  RE_WRAPPED.lastIndex = 0;

  // Don't wrap if already wrapped
  if (!RE_WRAPPED.test(content)) {
    content = `$m['${id}']=(function(module,exports){\n  module=this;exports=module.exports;\n\n${indent(content, 1)}\n\n  return module.exports;\n}).call({filename:'${id}',exports:{}});`;
  }

  return content;
};<|endoftext|>


<commit_before>require('core/string');
include('ringo/markdown');
include('ringo/buffer');
include('ringo/skin');
var fileutils = require('ringo/fileutils');

exports.markdown_filter = function(content) {
    var markdown = new Markdown({

        lookupLink: function(id) {
            if (id.startsWith("ng:")) {
                var path = id.substring(3);
                var title = path ? "RingoJS Wiki: " + path : "RingoJS Wiki";
                return ["http://dev.helma.org/ng/" + path.replace(/ /g, '+'), title];
            }
            return null;
        },

        openTag: function(tag, buffer) {
            if (tag === "pre") {
                buffer.append("
");
            } else {
                this.super$openTag(tag, buffer);
            }
        }
    });
    return markdown.process(content);
};

exports.navigation_macro = function(tag, context) {
    return render('./skins/navigation.txt', context);
};

// We override href and matchPath macros to operate relative to this demo app
// by using the rootPath property from our config module rather than the one
// from the request object.
// The rootPath property on the request object used by default implementations
// in ringo/skin/macros contains the root path of the  innermost app,
// which in our case may be the storage or jsdoc app.

exports.href_macro = function(tag) {
    var config = require('./config');
    var path = tag.parameters[0] || '';
    return config.rootPath
        + fileutils.resolveUri('/', config.appPath, path).slice(1);
};

exports.matchPath_macro = function(tag) {
    var config = require('./config');
    var path = tag.parameters[0];
    if (config && ('/' + config.appPath).match(path)) {
        return tag.parameters[1] || "match";
    }
};

/**
 * A test output formatter for displaying ringo/unittest results in a web page
 */
exports.HtmlTestFormatter = function() {
    var buffer = new Buffer();
    var result = "";
    var path = [];

    this.writeHeader = function() {
    };

    this.enterScope = function(name) {
        path.push(name)
        buffer.writeln("
Running \"", path.join("/"), "\"
");
    };

    this.exitScope = function(name) {
        path.pop();
    };

    this.writeTestStart = function(name) {
        buffer.write("
Running ", name, "...");
    };

    this.writeTestPassed = function(time) {
        buffer.writeln("
PASSED
",
                " (" + time + " ms)
");
    };

    this.writeTestFailed = function(exception) {
        buffer.write("
FAILED
 ");
        buffer.write("
");
        exception.message.split(/\n/).forEach(function(line) {
            buffer.writeln(" ".repeat(2), line);
        });
        if (exception.stackTrace != null) {
            exception.stackTrace.forEach(function(line) {
                buffer.writeln(" ".repeat(2), line);
            });
        }
        buffer.write("

");
    };

    this.writeSummary = function(summary) {
        if (summary.testsRun > 0) {
            result = new Buffer();
            result.writeln("
Executed ", summary.testsRun, " tests in ", summary.time, " ms
");
            result.writeln("
Passed ", summary.passed + "; ", "Failed ", summary.failures + "; ", "Errors ", summary.errors + ";
");
        } else {
            result = "
No tests found
";
        }
    };

    this.toString = function() {
        return result  + buffer.toString();
    }
};
<commit_msg>Remove now ununsed ng: link prefix from demo app<commit_after>require('core/string');
include('ringo/markdown');
include('ringo/buffer');
include('ringo/skin');
var fileutils = require('ringo/fileutils');

exports.markdown_filter = function(content) {
    var markdown = new Markdown({
        openTag: function(tag, buffer) {
            if (tag === "pre") {
                buffer.append("
");
            } else {
                this.super$openTag(tag, buffer);
            }
        }
    });
    return markdown.process(content);
};

exports.navigation_macro = function(tag, context) {
    return render('./skins/navigation.txt', context);
};

// We override href and matchPath macros to operate relative to this demo app
// by using the rootPath property from our config module rather than the one
// from the request object.
// The rootPath property on the request object used by default implementations
// in ringo/skin/macros contains the root path of the  innermost app,
// which in our case may be the storage or jsdoc app.

exports.href_macro = function(tag) {
    var config = require('./config');
    var path = tag.parameters[0] || '';
    return config.rootPath
        + fileutils.resolveUri('/', config.appPath, path).slice(1);
};

exports.matchPath_macro = function(tag) {
    var config = require('./config');
    var path = tag.parameters[0];
    if (config && ('/' + config.appPath).match(path)) {
        return tag.parameters[1] || "match";
    }
};

/**
 * A test output formatter for displaying ringo/unittest results in a web page
 */
exports.HtmlTestFormatter = function() {
    var buffer = new Buffer();
    var result = "";
    var path = [];

    this.writeHeader = function() {
    };

    this.enterScope = function(name) {
        path.push(name)
        buffer.writeln("
Running \"", path.join("/"), "\"
");
    };

    this.exitScope = function(name) {
        path.pop();
    };

    this.writeTestStart = function(name) {
        buffer.write("
Running ", name, "...");
    };

    this.writeTestPassed = function(time) {
        buffer.writeln("
PASSED
",
                " (" + time + " ms)
");
    };

    this.writeTestFailed = function(exception) {
        buffer.write("
FAILED
 ");
        buffer.write("
");
        exception.message.split(/\n/).forEach(function(line) {
            buffer.writeln(" ".repeat(2), line);
        });
        if (exception.stackTrace != null) {
            exception.stackTrace.forEach(function(line) {
                buffer.writeln(" ".repeat(2), line);
            });
        }
        buffer.write("

");
    };

    this.writeSummary = function(summary) {
        if (summary.testsRun > 0) {
            result = new Buffer();
            result.writeln("
Executed ", summary.testsRun, " tests in ", summary.time, " ms
");
            result.writeln("
Passed ", summary.passed + "; ", "Failed ", summary.failures + "; ", "Errors ", summary.errors + ";
");
        } else {
            result = "
No tests found
";
        }
    };

    this.toString = function() {
        return result  + buffer.toString();
    }
};
<|endoftext|>


<commit_before>// Copyright 2016 Artem Lytvynov <buntarb@gmail.com>. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS-IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

/**
 * @license Apache-2.0
 * @copyright Artem Lytvynov <buntarb@gmail.com>
 */

goog.provide( 'zz.events.BaseEventTest' );
goog.setTestOnly( 'zz.events.BaseEventTest' );

goog.require( 'goog.testing.jsunit' );
goog.require( 'zz.events.BaseEvent' );<commit_msg>tests were done<commit_after>// Copyright 2016 Artem Lytvynov <buntarb@gmail.com>. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS-IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

/**
 * @license Apache-2.0
 * @copyright Artem Lytvynov <buntarb@gmail.com>
 */

goog.provide( 'zz.events.BaseEventTest' );
goog.setTestOnly( 'zz.events.BaseEventTest' );

goog.require( 'goog.testing.jsunit' );
goog.require( 'goog.events.Event' );
goog.require( 'zz.events.BaseEvent' );

var baseEvent;

function testConstructor( ){

    assertTrue(

        'Instance must be non-null and have the expected class',
        baseEvent instanceof zz.events.BaseEvent
    );

    assertTrue(

        'Instance must be non-null and have the expected class',
        baseEvent instanceof goog.events.Event
    );
}<|endoftext|>


<commit_before>
require(['src/util/api'], function(API) {
    if (typeof IframeBridge != 'undefined') {
        require(['Roc','Sample'], function(Roc, Sample) {
            IframeBridge.onMessage(onMessage);
            IframeBridge.ready();
            function onMessage(data) {
                if(data.type === 'tab.data' || data.type === 'tab.focus') {
                    var roc = new Roc({
                        url: data.message.couchUrl,
                        database: data.message.database
                    });
                    var sample = new Sample(roc, data.message.uuid, 'sample', {track:false});
                }

            }
        });
    } else {
        // we retrieve the cache if it exists
        var externalInfo = JSON.parse(window.localStorage.getItem('external_cache') || "{}");
        var smiles = externalInfo.smiles;
        var molfile = externalInfo.molfile;
        var nmr = API.createData('nmr',[]);

        require(["uri/URI"], function(URI) {
            var uri = new URI(document.location.href);
            var search = uri.search(true);
            if (search.smiles) {
                smiles=search.smiles;
            }

            if (molfile) {
                require(["OCLE"], function (OCLE) {
                    var molecule=OCLE.Molecule.fromMolfile(molfile);
                    API.createData('molfile', molecule.toMolfile());
                });
            } else if(smiles) {
                require(["OCLE"], function (OCLE) {
                    var molecule=OCLE.Molecule.fromSmiles(smiles);
                    API.createData('molfile', molecule.toMolfile());
                });
            } else {
                molfile=window.localStorage.getItem('molfile');
                if (molfile) {
            		API.createData('molfile', molfile);
            	} else {
            	    API.createData('molfile', '');
            	}
            }
         })

        var data = require('src/util/versioning').getData();
        data.onChange(function (evt) {
            if(evt.jpath.length==1 && evt.jpath[0]=='molfile') {
                localStorage.setItem('molfile', evt.target.get());
            }
        });
    }
})
<commit_msg>Update setAndTrackMolfile.js<commit_after>
require(['src/util/api'], function(API) {
    if (typeof IframeBridge != 'undefined') {
        require(['Roc','Sample'], function(Roc, Sample) {
            IframeBridge.onMessage(onMessage);
            IframeBridge.ready();
            function onMessage(data) {
                if(data.type === 'tab.data' || data.type === 'tab.focus') {
                    var roc = new Roc(data.message.couchDB);
                    var sample = new Sample(roc, data.message.uuid, data.message.couchDB.kind, {track:false});
                }

            }
        });
    } else {
        // we retrieve the cache if it exists
        var externalInfo = JSON.parse(window.localStorage.getItem('external_cache') || "{}");
        var smiles = externalInfo.smiles;
        var molfile = externalInfo.molfile;
        var nmr = API.createData('nmr',[]);

        require(["uri/URI"], function(URI) {
            var uri = new URI(document.location.href);
            var search = uri.search(true);
            if (search.smiles) {
                smiles=search.smiles;
            }

            if (molfile) {
                require(["OCLE"], function (OCLE) {
                    var molecule=OCLE.Molecule.fromMolfile(molfile);
                    API.createData('molfile', molecule.toMolfile());
                });
            } else if(smiles) {
                require(["OCLE"], function (OCLE) {
                    var molecule=OCLE.Molecule.fromSmiles(smiles);
                    API.createData('molfile', molecule.toMolfile());
                });
            } else {
                molfile=window.localStorage.getItem('molfile');
                if (molfile) {
            		API.createData('molfile', molfile);
            	} else {
            	    API.createData('molfile', '');
            	}
            }
         })

        var data = require('src/util/versioning').getData();
        data.onChange(function (evt) {
            if(evt.jpath.length==1 && evt.jpath[0]=='molfile') {
                localStorage.setItem('molfile', evt.target.get());
            }
        });
    }
})
<|endoftext|>


<commit_before>/*
 * retina.js - JavaScript helper for rendering high-resolution image variants.
 *
 * https://github.com/imulus/retinajs
 *
 * Copyright (C) 2012 Imulus
 * Copyright (C) 2012 Ben Atkin
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
(function() {

  var root = (typeof exports == 'undefined' ? window : exports);

  var config = {
    // Ensure Content-Type is an image before trying to load @2x image
    // https://github.com/imulus/retinajs/pull/45)
    check_mime_type: true
  };

  root.Retina = Retina;

  function Retina() {}

  Retina.configure = function(options) {
    if (options == null) options = {};
    for (var prop in options) config[prop] = options[prop];
  };

  Retina.init = function(context) {
    if (context == null) context = root;

    var existing_onload = context.onload || new Function;

    context.onload = function() {
      var images = document.getElementsByTagName("img"), retinaImages = [], i, image;
      for (i = 0; i < images.length; i++) {
        image = images[i];
        retinaImages.push(new RetinaImage(image));
      }
      existing_onload();
    }
  };

  Retina.isRetina = function(){
    var mediaQuery = "(-webkit-min-device-pixel-ratio: 1.5),\
                      (min--moz-device-pixel-ratio: 1.5),\
                      (-o-min-device-pixel-ratio: 3/2),\
                      (min-resolution: 1.5dppx)";

    if (root.devicePixelRatio > 1)
      return true;

    if (root.matchMedia && root.matchMedia(mediaQuery).matches)
      return true;

    return false;
  };

  root.RetinaImagePath = RetinaImagePath;

  function RetinaImagePath(path, at_2x_path) {
    this.path = path;
    if (typeof at_2x_path !== "undefined" && at_2x_path !== null) {
      this.at_2x_path = at_2x_path;
      this.perform_check = false;
    } else {
      this.at_2x_path = path.replace(/\.\w+$/, function(match) { return "@2x" + match; });
      this.perform_check = true;
    }
  }

  RetinaImagePath.confirmed_paths = [];

  RetinaImagePath.prototype.is_external = function() {
    return !!(this.path.match(/^https?\:/i) && !this.path.match('//' + document.domain) )
  }

  RetinaImagePath.prototype.check_2x_variant = function(callback) {
    var http, that = this;
    if (this.is_external()) {
      return callback(false);
    } else if (!this.perform_check && typeof this.at_2x_path !== "undefined" && this.at_2x_path !== null) {
      return callback(true);
    } else if (this.at_2x_path in RetinaImagePath.confirmed_paths) {
      return callback(true);
    } else {
      http = new XMLHttpRequest;
      http.open('HEAD', this.at_2x_path);
      http.onreadystatechange = function() {
        if (http.readyState != 4) {
          return callback(false);
        }

        if (http.status >= 200 && http.status <= 399) {
          if (config.check_mime_type) {
            var type = http.getResponseHeader('Content-Type');
            if (type == null || !type.match(/^image/i)) {
              return callback(false);
            }
          }

          RetinaImagePath.confirmed_paths.push(that.at_2x_path);
          return callback(true);
        } else {
          return callback(false);
        }
      }
      http.send();
    }
  }

  function RetinaImage(el) {
    this.el = el;
    this.path = new RetinaImagePath(this.el.getAttribute('src'), this.el.getAttribute('data-at2x'));
    var that = this;
    this.path.check_2x_variant(function(hasVariant) {
      if (hasVariant) that.swap();
    });
  }

  root.RetinaImage = RetinaImage;

  RetinaImage.prototype.swap = function(path) {
    if (typeof path == 'undefined') path = this.path.at_2x_path;

    var that = this;
    function load() {
      if (! that.el.complete) {
        setTimeout(load, 5);
      } else {
        that.el.setAttribute('width', that.el.offsetWidth);
        that.el.setAttribute('height', that.el.offsetHeight);
        that.el.setAttribute('src', path);
      }
    }
    load();
  }

  if (Retina.isRetina()) {
    Retina.init(root);
  }

})();

<commit_msg>Fix retina.js with images not currently visible on the page.<commit_after>/*
 * retina.js - JavaScript helper for rendering high-resolution image variants.
 *
 * https://github.com/imulus/retinajs
 *
 * Copyright (C) 2012 Imulus
 * Copyright (C) 2012 Ben Atkin
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
(function() {

  var root = (typeof exports == 'undefined' ? window : exports);

  var config = {
    // Ensure Content-Type is an image before trying to load @2x image
    // https://github.com/imulus/retinajs/pull/45)
    check_mime_type: true
  };

  root.Retina = Retina;

  function Retina() {}

  Retina.configure = function(options) {
    if (options == null) options = {};
    for (var prop in options) config[prop] = options[prop];
  };

  Retina.init = function(context) {
    if (context == null) context = root;

    var existing_onload = context.onload || new Function;

    context.onload = function() {
      var images = document.getElementsByTagName("img"), retinaImages = [], i, image;
      for (i = 0; i < images.length; i++) {
        image = images[i];
        retinaImages.push(new RetinaImage(image));
      }
      existing_onload();
    }
  };

  Retina.isRetina = function(){
    var mediaQuery = "(-webkit-min-device-pixel-ratio: 1.5),\
                      (min--moz-device-pixel-ratio: 1.5),\
                      (-o-min-device-pixel-ratio: 3/2),\
                      (min-resolution: 1.5dppx)";

    if (root.devicePixelRatio > 1)
      return true;

    if (root.matchMedia && root.matchMedia(mediaQuery).matches)
      return true;

    return false;
  };

  root.RetinaImagePath = RetinaImagePath;

  function RetinaImagePath(path, at_2x_path) {
    this.path = path;
    if (typeof at_2x_path !== "undefined" && at_2x_path !== null) {
      this.at_2x_path = at_2x_path;
      this.perform_check = false;
    } else {
      this.at_2x_path = path.replace(/\.\w+$/, function(match) { return "@2x" + match; });
      this.perform_check = true;
    }
  }

  RetinaImagePath.confirmed_paths = [];

  RetinaImagePath.prototype.is_external = function() {
    return !!(this.path.match(/^https?\:/i) && !this.path.match('//' + document.domain) )
  }

  RetinaImagePath.prototype.check_2x_variant = function(callback) {
    var http, that = this;
    if (this.is_external()) {
      return callback(false);
    } else if (!this.perform_check && typeof this.at_2x_path !== "undefined" && this.at_2x_path !== null) {
      return callback(true);
    } else if (this.at_2x_path in RetinaImagePath.confirmed_paths) {
      return callback(true);
    } else {
      http = new XMLHttpRequest;
      http.open('HEAD', this.at_2x_path);
      http.onreadystatechange = function() {
        if (http.readyState != 4) {
          return callback(false);
        }

        if (http.status >= 200 && http.status <= 399) {
          if (config.check_mime_type) {
            var type = http.getResponseHeader('Content-Type');
            if (type == null || !type.match(/^image/i)) {
              return callback(false);
            }
          }

          RetinaImagePath.confirmed_paths.push(that.at_2x_path);
          return callback(true);
        } else {
          return callback(false);
        }
      }
      http.send();
    }
  }

  function RetinaImage(el) {
    this.el = el;
    this.path = new RetinaImagePath(this.el.getAttribute('src'), this.el.getAttribute('data-at2x'));
    var that = this;
    this.path.check_2x_variant(function(hasVariant) {
      if (hasVariant) that.swap();
    });
  }

  root.RetinaImage = RetinaImage;

  RetinaImage.prototype.swap = function(path) {
    if (typeof path == 'undefined') path = this.path.at_2x_path;

    var that = this;
    function load() {
      if (! that.el.complete) {
        setTimeout(load, 5);
      } else {
        that.el.setAttribute('width', that.el.naturalWidth || that.el.offsetWidth);
        that.el.setAttribute('height', that.el.naturalHeight || that.el.offsetHeight);
        that.el.setAttribute('src', path);
      }
    }
    load();
  }

  if (Retina.isRetina()) {
    Retina.init(root);
  }

})();

<|endoftext|>


<commit_before>/**
 * Emulates stream.setTimeout() behaviour, but respects outgoing data
 * too.
 *
 * @param {Number} timeout Milliseconds
 */
exports.attach = function(stream, timeout) {
    var timer;
    var emitTimeout = function() {
        timer = undefined;
        stream.emit('timeout');
    };
    var updateTimer = function() {
        if (timer)
            clearTimeout(timer);
        timer = setTimeout(emitTimeout, timeout);
    };

    var oldWrite = stream.write;
    stream.write = function() {
        updateTimer();
        oldWrite.apply(this, arguments);
    };
    var clear = function() {
        if (timer)
            clearTimeout(timer);
        if (stream.write !== oldWrite)
            stream.write = oldWrite;
    delete stream.clearTimer;
    };
    stream.clearTimer = clear;
    stream.addListener('data', updateTimer);
    stream.addListener('error', clear);
    stream.addListener('close', clear);
    stream.addListener('end', clear);
};
<commit_msg>Clean up idle_timeout.js<commit_after>'use strict';

/**
 * Emulates stream.setTimeout() behaviour, but respects outgoing data
 * too.
 *
 * @param {Number} timeout Milliseconds
 */
exports.attach = function(stream, timeout) {
    var timer
    var emitTimeout = function() {
        timer = undefined
        stream.emit('timeout')
    }
    var updateTimer = function() {
        if (timer) clearTimeout(timer)
        timer = setTimeout(emitTimeout, timeout)
    }

    var oldWrite = stream.write
    stream.write = function() {
        updateTimer()
        oldWrite.apply(this, arguments)
    }
    var clear = function() {
        if (timer) clearTimeout(timer)
        if (stream.write !== oldWrite) stream.write = oldWrite
        delete stream.clearTimer
    }
    stream.clearTimer = clear
    stream.addListener('data', updateTimer)
    stream.addListener('error', clear)
    stream.addListener('close', clear)
    stream.addListener('end', clear)
}<|endoftext|>


<commit_before>var exec     = require('child_process').exec
  , path     = require('path')
  , fs       = require('fs')
  , exists   = fs.exists || path.exists
  , crypto   = require('crypto')
  , Identify = require('identify.js')

var ImageMagick = module.exports = function(config, logger) {
  if(!config) throw new Error('Where is my config?')

  this.config = config
  this.config.timeouts = this.config.timeouts || {}
  this.config.tmpPathRoot = this.config.tmpPathRoot || '/tmp/node-image-magick'

  this.logger = logger || { log: function(){} }
}

ImageMagick.Templates = {
  tmpPath: "%{dir}/%{file}",

  downloadCmd: "curl --create-dirs -sf '%{source}' -o '%{target}'",
  identifyCmd: "identify -format %m '%{file}'",
  identifyVerboseCmd: "identify -verbose '%{file}'",
  createBlankImageCmd: "convert -bordercolor '#B1B1B1' -background '#eee' -border 1 -size %{size} -fill '#900' -font '/Library/Fonts/Arial Bold.ttf' -pointsize 16 label:' x' '%{tmpfile}'",
  resizeCmd: "-resize '%{size}'",
  fitCmd: "-gravity center -resize '%{size}'^ -extent %{size}",
  cropCmd: "-crop %{crop} +repage -thumbnail '%{size}'",

  checkValue: function(value) {
    if(!value.toString().match(/^[^;"']+$/i))
      throw new Error('Unallowed characters in replacement: ' + value.toString())

    return value
  },

  get: function(key, replacements) {
    var result = ImageMagick.Templates[key]

    for(var k in replacements) {
      var value = ImageMagick.Templates.checkValue(replacements[k])
        , key   = new RegExp("%{" + k + "}", "g")

      result = result.replace(key, value)
    }

    return result
  }
}

ImageMagick.prototype.identify = function(params, callback) {
  if(!params.hasOwnProperty('url'))
    throw new Error('Identify needs url param!')

  Identify.parseFile(ImageMagick.Templates.checkValue(params.url), callback)
}

ImageMagick.prototype.resize = function(params, callback) {
  if(!params.hasOwnProperty('size')) {
    throw new Error('Resize needs size-param with format <width>x<height>!')
  }

  this._convert(ImageMagick.Templates.get('resizeCmd', { size: params.size }), params, callback)
}

ImageMagick.prototype.fit = function(params, callback) {
  if(!params.hasOwnProperty('size'))
    throw new Error('Fit needs size-parameter with format <width>x<height>!')

  this._convert(ImageMagick.Templates.get('fitCmd', { size: params.size }), params, callback)
}

ImageMagick.prototype.crop = function(params, callback) {
  if(!params.hasOwnProperty('crop'))
    throw new Error('Crop needs crop-param with format <width>x<height>+<x>+<y>!')

  var self   = this
  var doCrop = function() {
    var cmd = ImageMagick.Templates.get('cropCmd', {
      crop: params.crop,
      size: params.size || params.crop.split('+')[0]
    })

    self._convert(cmd, params, callback)
  }

  if(params.hasOwnProperty('cropSourceSize')) {
    this._scaleCropParam(params, function() { doCrop() })
  } else {
    doCrop()
  }
}

// private

ImageMagick.prototype.execute = function(cmd, options, callback) {
  var self = this

  this.logger.log('Executing command: ' + cmd)
  exec(cmd, options, function(err, stdout, stderr) {
    self.logger.log('Finished command: ' + cmd)
    callback && callback(err, stdout, stderr)
  })
}

ImageMagick.prototype._scaleCropParam = function(params, callback) {
  var self = this

  this.identify({url: params.url}, function(err, stats) {
    if(err)
      callback && callback(err)
    else {
      params.crop = self._scaleCropInfo(params.crop, params.cropSourceSize.split('x'), stats.Geometry.split('+')[0].split('x'))
      callback && callback()
    }
  })
}

ImageMagick.prototype._scaleCropInfo = function(cropValue, cropSourceSize, sourceDimension) {
  var cropSourceWidth  = cropSourceSize[0]
    , cropSourceHeight = cropSourceSize[1]
    , ratio            = null
    , scaledCropInfo   = null

  if(cropSourceWidth)
    ratio = parseFloat(sourceDimension[0]) / parseFloat(cropSourceWidth)
  else
    ratio = parseFloat(sourceDimension[1]) / parseFloat(cropSourceHeight)

  // before: 200x300+10+20
  // after: [300, 400, 15, 28] (split + multiply by ratio)
  scaledCropInfo = cropValue.split(/[+x]/).map(function(dim) { return parseInt(parseInt(dim) * ratio) })

  // finally: join array to 300x400+15+28
  return [[scaledCropInfo[0], scaledCropInfo[1]].join('x'), scaledCropInfo[2], scaledCropInfo[3]].join('+')
}

ImageMagick.prototype._createTmpPath = function(rand) {
  var shasum = crypto.createHash('sha1')
    , digest

  rand = rand || Date.now()

  shasum.update(rand.toString())

  digest = shasum.digest('hex')

  return this.config.tmpPathRoot +
         '/' + digest.slice(0, 3) +
         '/' + digest.slice(3, 6) +
         '/' + digest.slice(6, 9) +
         '/' + digest.slice(9, 12) +
         '/' + digest.slice(12, 15) +
         '/' + digest.slice(15, 18) +
         '/' + digest.slice(18, 21) +
         '/' + digest.slice(21, 24) +
         '/' + digest.slice(24, 27) +
         '/' + digest.slice(27, 30) +
         '/' + digest.slice(30, 33) +
         '/' + digest.slice(33, 36) +
         '/' + digest.slice(36, 39) +
         '/' + digest.slice(39)
}

ImageMagick.prototype._downloadSource = function(source, target, callback) {
  this.logger.log('Downloading source')
  this.execute(ImageMagick.Templates.get('downloadCmd', {source: source, target: target}), { timeout: this.config.timeouts.download }, callback)
}

ImageMagick.prototype._localizeSource = function(source, tmpPath, callback) {
  var self = this

  this.logger.log('Localizing source')

  var checkSourceExists = function(_path) {
    exists(_path, function(fileExists) {
      callback(null, fileExists, _path)
    })
  }

  if(source.indexOf("http") == 0) {
    var tmpfile = ImageMagick.Templates.get('tmpPath', { dir: tmpPath, file: path.basename(source, path.extname(source)) + '.src' })

    exists(tmpfile, function(fileExists) {
      if(fileExists) {
        self.logger.log('Local source already exists at ' + tmpfile + ', not downloading again')
        callback(null, true, tmpfile)
      } else {
        self._downloadSource(source, tmpfile, function(err, stdout, stderr) {
          if(err && err.killed) {
            callback(err, false, null)
          } else {
            checkSourceExists(tmpfile)
          }
        })
      }
    });

  } else {
    checkSourceExists(source)
  }
}

ImageMagick.prototype._getTempfile = function(source, tmpPath, callback) {
  var self = this

  this._getMimeType(source, function(mimeType) {
    var dir;

    var tmpfile = ImageMagick.Templates.get('tmpPath', { dir: tmpPath, file: path.basename(source, path.extname(source))  + '-converted.' + mimeType })
    self.execute("mkdir -p " + path.dirname(tmpfile), {}, function() { callback(tmpfile) })
  })
}

ImageMagick.prototype._getMimeType = function(file, callback) {
  this.execute(ImageMagick.Templates.get('identifyCmd', { file: file }), { timeout: this.config.timeouts.identify }, function(err, stdout, stderr) {
    var mimeType = stdout.toLowerCase().replace("\n", "")
    callback(mimeType === "" ? "jpeg" : mimeType)
  })
}

ImageMagick.prototype._getFallbackImageCommand = function(_size, tmpfile) {
  var size = _size.split('x').map(function(num){
    return (num == "") ? "" : (parseInt(num) - 2)
  }).join("x")

  return ImageMagick.Templates.get('createBlankImageCmd', { size : size, tmpfile: tmpfile})
}

ImageMagick.prototype._checkSizeLimit = function(size) {
  var sizeLimit = this.config.imageSizeLimit

  if(!sizeLimit) return

  var dimension = size.match(/(\d+).*?(\d+)/).slice(1,3)

  dimension.forEach(function(_size) {
    if(parseInt(_size) > sizeLimit)
      throw new Error('Unallowed size! Requested: ' + size + '; Match: ' + _size + '; Allowed: ' + sizeLimit)
  })
}

ImageMagick.prototype._convert = function(_command, params, callback) {
  var source         = params.url
    , self           = this
    , size           = params.size || params.crop.split('+')[0]
    , pathHashString = source + ':' + _command
    , srcTmpPath     = this._createTmpPath(source)
    , destTmpPath    = this._createTmpPath(pathHashString)

  this._checkSizeLimit(params.size)
  this._localizeSource(source, srcTmpPath, function(err, fileExists, localizedSource) {
    if(err && !fileExists)
      return callback && callback(err, null, null)

    self._getTempfile(localizedSource, destTmpPath, function(tmpfile) {
      exists(tmpfile, function(tmpFileExists) {
        if(tmpFileExists) {
          self.logger.log('Converted file already exists. Skipping convert')
          callback(null, tmpfile)
        } else {
          self.logger.log('Converted file does not exist. Converting...')
          var command = "convert '" + localizedSource + "' " + _command + " '" + tmpfile + "'"

          if(!fileExists) {
            command = self._getFallbackImageCommand(size, tmpfile)
          }

          self.execute(command, { timeout: self.config.timeouts.convert }, function (err, stdout, stderr) {
            callback && callback(err, tmpfile)
          })
        }
      })
    })
  })
}
<commit_msg>added parens<commit_after>var exec     = require('child_process').exec
  , path     = require('path')
  , fs       = require('fs')
  , exists   = fs.exists || path.exists
  , crypto   = require('crypto')
  , Identify = require('identify.js')

var ImageMagick = module.exports = function(config, logger) {
  if(!config) throw new Error('Where is my config?')

  this.config = config
  this.config.timeouts = this.config.timeouts || {}
  this.config.tmpPathRoot = this.config.tmpPathRoot || '/tmp/node-image-magick'

  this.logger = logger || { log: function(){} }
}

ImageMagick.Templates = {
  tmpPath: "%{dir}/%{file}",

  downloadCmd: "curl --create-dirs -sf '%{source}' -o '%{target}'",
  identifyCmd: "identify -format %m '%{file}'",
  identifyVerboseCmd: "identify -verbose '%{file}'",
  createBlankImageCmd: "convert -bordercolor '#B1B1B1' -background '#eee' -border 1 -size %{size} -fill '#900' -font '/Library/Fonts/Arial Bold.ttf' -pointsize 16 label:' x' '%{tmpfile}'",
  resizeCmd: "-resize '%{size}'",
  fitCmd: "-gravity center -resize '%{size}'^ -extent %{size}",
  cropCmd: "-crop %{crop} +repage -thumbnail '%{size}'",

  checkValue: function(value) {
    if(!value.toString().match(/^[^;"']+$/i))
      throw new Error('Unallowed characters in replacement: ' + value.toString())

    return value
  },

  get: function(key, replacements) {
    var result = ImageMagick.Templates[key]

    for(var k in replacements) {
      var value = ImageMagick.Templates.checkValue(replacements[k])
        , key   = new RegExp("%{" + k + "}", "g")

      result = result.replace(key, value)
    }

    return result
  }
}

ImageMagick.prototype.identify = function(params, callback) {
  if(!params.hasOwnProperty('url'))
    throw new Error('Identify needs url param!')

  Identify.parseFile(ImageMagick.Templates.checkValue(params.url), callback)
}

ImageMagick.prototype.resize = function(params, callback) {
  if(!params.hasOwnProperty('size')) {
    throw new Error('Resize needs size-param with format <width>x<height>!')
  }

  this._convert(ImageMagick.Templates.get('resizeCmd', { size: params.size }), params, callback)
}

ImageMagick.prototype.fit = function(params, callback) {
  if(!params.hasOwnProperty('size')) {
    throw new Error('Fit needs size-parameter with format <width>x<height>!')
  }

  this._convert(ImageMagick.Templates.get('fitCmd', { size: params.size }), params, callback)
}

ImageMagick.prototype.crop = function(params, callback) {
  if(!params.hasOwnProperty('crop'))
    throw new Error('Crop needs crop-param with format <width>x<height>+<x>+<y>!')

  var self   = this
  var doCrop = function() {
    var cmd = ImageMagick.Templates.get('cropCmd', {
      crop: params.crop,
      size: params.size || params.crop.split('+')[0]
    })

    self._convert(cmd, params, callback)
  }

  if(params.hasOwnProperty('cropSourceSize')) {
    this._scaleCropParam(params, function() { doCrop() })
  } else {
    doCrop()
  }
}

// private

ImageMagick.prototype.execute = function(cmd, options, callback) {
  var self = this

  this.logger.log('Executing command: ' + cmd)
  exec(cmd, options, function(err, stdout, stderr) {
    self.logger.log('Finished command: ' + cmd)
    callback && callback(err, stdout, stderr)
  })
}

ImageMagick.prototype._scaleCropParam = function(params, callback) {
  var self = this

  this.identify({url: params.url}, function(err, stats) {
    if(err) {
      callback && callback(err)
    } else {
      params.crop = self._scaleCropInfo(params.crop, params.cropSourceSize.split('x'), stats.Geometry.split('+')[0].split('x'))
      callback && callback()
    }
  })
}

ImageMagick.prototype._scaleCropInfo = function(cropValue, cropSourceSize, sourceDimension) {
  var cropSourceWidth  = cropSourceSize[0]
    , cropSourceHeight = cropSourceSize[1]
    , ratio            = null
    , scaledCropInfo   = null

  if(cropSourceWidth) {
    ratio = parseFloat(sourceDimension[0]) / parseFloat(cropSourceWidth)
  } else {
    ratio = parseFloat(sourceDimension[1]) / parseFloat(cropSourceHeight)
  }

  // before: 200x300+10+20
  // after: [300, 400, 15, 28] (split + multiply by ratio)
  scaledCropInfo = cropValue.split(/[+x]/).map(function(dim) { return parseInt(parseInt(dim) * ratio) })

  // finally: join array to 300x400+15+28
  return [[scaledCropInfo[0], scaledCropInfo[1]].join('x'), scaledCropInfo[2], scaledCropInfo[3]].join('+')
}

ImageMagick.prototype._createTmpPath = function(rand) {
  var shasum = crypto.createHash('sha1')
    , digest

  rand = rand || Date.now()

  shasum.update(rand.toString())

  digest = shasum.digest('hex')

  return this.config.tmpPathRoot +
         '/' + digest.slice(0, 3) +
         '/' + digest.slice(3, 6) +
         '/' + digest.slice(6, 9) +
         '/' + digest.slice(9, 12) +
         '/' + digest.slice(12, 15) +
         '/' + digest.slice(15, 18) +
         '/' + digest.slice(18, 21) +
         '/' + digest.slice(21, 24) +
         '/' + digest.slice(24, 27) +
         '/' + digest.slice(27, 30) +
         '/' + digest.slice(30, 33) +
         '/' + digest.slice(33, 36) +
         '/' + digest.slice(36, 39) +
         '/' + digest.slice(39)
}

ImageMagick.prototype._downloadSource = function(source, target, callback) {
  this.logger.log('Downloading source')
  this.execute(ImageMagick.Templates.get('downloadCmd', {source: source, target: target}), { timeout: this.config.timeouts.download }, callback)
}

ImageMagick.prototype._localizeSource = function(source, tmpPath, callback) {
  var self = this

  this.logger.log('Localizing source')

  var checkSourceExists = function(_path) {
    exists(_path, function(fileExists) {
      callback(null, fileExists, _path)
    })
  }

  if(source.indexOf("http") == 0) {
    var tmpfile = ImageMagick.Templates.get('tmpPath', { dir: tmpPath, file: path.basename(source, path.extname(source)) + '.src' })

    exists(tmpfile, function(fileExists) {
      if(fileExists) {
        self.logger.log('Local source already exists at ' + tmpfile + ', not downloading again')
        callback(null, true, tmpfile)
      } else {
        self._downloadSource(source, tmpfile, function(err, stdout, stderr) {
          if(err && err.killed) {
            callback(err, false, null)
          } else {
            checkSourceExists(tmpfile)
          }
        })
      }
    });

  } else {
    checkSourceExists(source)
  }
}

ImageMagick.prototype._getTempfile = function(source, tmpPath, callback) {
  var self = this

  this._getMimeType(source, function(mimeType) {
    var dir;

    var tmpfile = ImageMagick.Templates.get('tmpPath', { dir: tmpPath, file: path.basename(source, path.extname(source))  + '-converted.' + mimeType })
    self.execute("mkdir -p " + path.dirname(tmpfile), {}, function() { callback(tmpfile) })
  })
}

ImageMagick.prototype._getMimeType = function(file, callback) {
  this.execute(ImageMagick.Templates.get('identifyCmd', { file: file }), { timeout: this.config.timeouts.identify }, function(err, stdout, stderr) {
    var mimeType = stdout.toLowerCase().replace("\n", "")
    callback(mimeType === "" ? "jpeg" : mimeType)
  })
}

ImageMagick.prototype._getFallbackImageCommand = function(_size, tmpfile) {
  var size = _size.split('x').map(function(num){
    return (num == "") ? "" : (parseInt(num) - 2)
  }).join("x")

  return ImageMagick.Templates.get('createBlankImageCmd', { size : size, tmpfile: tmpfile})
}

ImageMagick.prototype._checkSizeLimit = function(size) {
  var sizeLimit = this.config.imageSizeLimit

  if(!sizeLimit) return

  var dimension = size.match(/(\d+).*?(\d+)/).slice(1,3)

  dimension.forEach(function(_size) {
    if(parseInt(_size) > sizeLimit)
      throw new Error('Unallowed size! Requested: ' + size + '; Match: ' + _size + '; Allowed: ' + sizeLimit)
  })
}

ImageMagick.prototype._convert = function(_command, params, callback) {
  var source         = params.url
    , self           = this
    , size           = params.size || params.crop.split('+')[0]
    , pathHashString = source + ':' + _command
    , srcTmpPath     = this._createTmpPath(source)
    , destTmpPath    = this._createTmpPath(pathHashString)

  this._checkSizeLimit(params.size)
  this._localizeSource(source, srcTmpPath, function(err, fileExists, localizedSource) {
    if(err && !fileExists)
      return callback && callback(err, null, null)

    self._getTempfile(localizedSource, destTmpPath, function(tmpfile) {
      exists(tmpfile, function(tmpFileExists) {
        if(tmpFileExists) {
          self.logger.log('Converted file already exists. Skipping convert')
          callback(null, tmpfile)
        } else {
          self.logger.log('Converted file does not exist. Converting...')
          var command = "convert '" + localizedSource + "' " + _command + " '" + tmpfile + "'"

          if(!fileExists) {
            command = self._getFallbackImageCommand(size, tmpfile)
          }

          self.execute(command, { timeout: self.config.timeouts.convert }, function (err, stdout, stderr) {
            callback && callback(err, tmpfile)
          })
        }
      })
    })
  })
}
<|endoftext|>


<commit_before>/* jshint node: true */
var spawn = require('child_process').spawn;
module.exports = {
	before: function (ready) {
		'use strict';
		var runner = spawn('node', [
			'../../docs/build.js',
			'../../docs/tests/tests.docs-config.js'
		], {
			cwd: __dirname
		});
		runner.stdout.on('data', function (data) {
			console.log(String(data));
		});

		runner.stderr.on('data', function (data) {
			console.log(String(data));
		});

		runner.on('close', function (code) {
			console.log('exited with code ' + code);
			ready.resolve();
		});
	},
	karma: {
		// base path, that will be used to resolve files and exclude
		basePath: '../../docs/tests/',

		frameworks: ['jasmine'],

		// list of files / patterns to load in the browser
		files: [
		  JASMINE,
		  JASMINE_ADAPTER,
		  { pattern: '../build.js', watched: true, served: false, included: false },
		  { pattern: 'tests.docs-config.js', watched: true, served: false, included: false },
		  { pattern: 'js/main.js', watched: true, served: false, included: false },

		  { pattern: 'lib/jquery-1.9.1.min.js', watched: true, served: true, included: true },
		  { pattern: 'lib/jasmine-jquery.js', watched: true, served: true, included: true },
		  { pattern: 'html/index.html', watched: true, served: true, included: false },

		  { pattern: 'main-tests.js', watched: true, served: true, included: true }
		]
	}
};<commit_msg>updated doc tests<commit_after>/* jshint node: true */
var spawn = require('child_process').spawn;
module.exports = {
	before: function (ready) {
		'use strict';

		console.log('cwd', __dirname);
		console.log('node ../../docs/build.js ../../docs/tests/tests.docs-config.js');

		var runner = spawn('node', [
			'../../docs/build.js',
			'../../docs/tests/tests.docs-config.js'
		], {
			cwd: __dirname
		});
		runner.stdout.on('data', function (data) {
			console.log(String(data));
		});

		runner.stderr.on('data', function (data) {
			console.log(String(data));
		});

		runner.on('close', function (code) {
			console.log('exited with code ' + code);
			ready.resolve();
		});
	},
	karma: {
		// base path, that will be used to resolve files and exclude
		basePath: '../../docs/tests/',

		frameworks: ['jasmine'],

		// list of files / patterns to load in the browser
		files: [
		  JASMINE,
		  JASMINE_ADAPTER,
		  { pattern: '../build.js', watched: true, served: false, included: false },
		  { pattern: 'tests.docs-config.js', watched: true, served: false, included: false },
		  { pattern: 'js/main.js', watched: true, served: false, included: false },

		  { pattern: 'lib/jquery-1.9.1.min.js', watched: true, served: true, included: true },
		  { pattern: 'lib/jasmine-jquery.js', watched: true, served: true, included: true },
		  { pattern: 'html/index.html', watched: true, served: true, included: false },

		  { pattern: 'main-tests.js', watched: true, served: true, included: true }
		]
	}
};<|endoftext|>


<commit_before>(function() {
  "use strict";

  var fs = require("fs");

  function getBufferFromFile(fileName, done) {
    console.log("Reading :" + fileName);

    fs.exists(fileName, function(exists) {
      if (exists) {
        fs.stat(fileName, function(error, stats) {
          if (error) {
            return done(error);
          }

          fs.open(fileName, "r", function(error, fd) {
            if (error) {
              return done(error);
            }
            var buffer = new Buffer(stats.size);

            fs.read(fd, buffer, 0, buffer.length, null, function(error, bytesRead, buffer) {
              fs.close(fd);
              return done(null, buffer, bytesRead);
            });
          });
        });
      } else {
        return done(new Error("File does not exist", indexFile));
      }
    });
  }

  // http://bocoup.com/weblog/getting-bitwise-with-javascript/
  function numToBinaryArray(num) {
    var res = [];
    var index, bitMask;

    for (bitMask = 0x80000000, index = 0; index < 32; bitMask >>>= 1, index++) {
      res[31 - index] = ((bitMask & num) ? 1 : 0);
    }

    console.log("" + num + " -> binary:"+res);
    return res;
  }

  function bufferReader(buffer, bytesRead) {
    var _buffer = buffer;
    var _delta = 0;
    var _bytesRead = bytesRead;

    return {
      readUInt32BE: function() {
        var result = _buffer.readUInt32BE(_delta);
        _delta += 4;
        return result;
      },

      readUInt16BE: function() {
        var result = _buffer.readUInt16BE(_delta);
        _delta += 2;
        return result;
      },

      readString: function() {
        var result = "";
        var state = 0;
        var len = 0;

        while (state !== 99) {
          var b = _buffer.readInt8(_delta);
          _delta++;
          len++;
          console.log("@@ (" + String.fromCharCode(b) + "),(" + b + "), at len=" + len + ",_delta:" + _delta);
          if (state === 0) {
            if (b === 0x00) {
              state = 1;
            } else {
              result = result + String.fromCharCode(b);
            }
          } else if (state === 1) {
            if (_delta % 8 === 0) {
              console.log("@@ delta:" + _delta);
              // var b = _buffer.readInt8(_delta + 1);
              // console.log("@@ next was:("+String.fromCharCode(b)+"),("+b+")");
              // var b = _buffer.readInt8(_delta + 2);
              // console.log("@@ next2 was:("+String.fromCharCode(b)+"),("+b+")");

              state = 99;
            } else {
              if (b !== 0x00) {
                throw new Error("bad string padding:" + b + ", with len:" + len);
              }
            }
          }
        }
        return result;
      },

      slice: function(length) {
        var result = _buffer.slice(_delta, _delta + length);
        _delta += length;
        return result;
      }
    }
  }

  //
  // http://schacon.github.io/gitbook/7_the_git_index.html
  //
  // https://github.com/git/git/blob/master/Documentation/technical/index-format.txt
  // https://code.google.com/p/git-core/source/browse/Documentation/technical/index-format.txt?spec=svne44b6df90cfd6ccbf35c3d147ff5a0e4e22fb17a&r=e44b6df90cfd6ccbf35c3d147ff5a0e4e22fb17a
  //
  // https://github.com/chrisdickinson/git-packidx-parser/blob/master/index.js
  //
  // http://stackoverflow.com/questions/4084921/what-does-the-git-index-contain-exactly
  //
  function parseIndex(fileName, done) {
    getBufferFromFile(fileName, function(error, buffer, bytesRead) {
      if (error) {
        return done(error);
      }

      // prepare Buffer reader
      var br = bufferReader(buffer, bytesRead);

      // check for the 'DIRC' signature
      if (br.readUInt32BE() !== 0x44495243) {
        return done(new Error("Invalid signature:" + Number(buffer.readUInt32BE(0)).toString(16)));
      }

      var version = br.readUInt32BE();

      console.log("@@ version:" + version);

      var numberOfIndexEntries = br.readUInt32BE();

      console.log("@@ numberOfIndexEntries:" + numberOfIndexEntries);

      for (var i = 0; i < numberOfIndexEntries; i++) {
        var ctimeSeconds = br.readUInt32BE();
        var ctimeNanoSeconds = br.readUInt32BE();
        var mtimeSeconds = br.readUInt32BE();
        var mtimeNanoSeconds = br.readUInt32BE();
        var dev = br.readUInt32BE();
        var ino = br.readUInt32BE();
        console.log("@ ino:" + ino);
        var mode = br.readUInt32BE();
        var uid = br.readUInt32BE();
        console.log("@ uid:" + ino);
        var gid = br.readUInt32BE();
        var size = br.readUInt32BE();
        var sha1 = br.slice(20);
        var flags = br.readUInt16BE();
        console.log("@@ flags:" + flags);
        var nameLen = flags & 0x00000FFF
        console.log("nameLen is:" + nameLen)
        var pathName = br.readString();
        console.log("pathName:" + pathName);
      }

      console.log("--");

      return done(null, "youpi!");
    });
  }

  numToBinaryArray(0);
  numToBinaryArray(1);
  numToBinaryArray(128);
  numToBinaryArray(10);

  parseIndex(".git/index", function(err, info) {
    if (err) {
      console.log("ERR:", err);
    } else {
      console.log("DONE");
    }
  });
}());<commit_msg>ref to pthon parser<commit_after>(function() {
  "use strict";

  var fs = require("fs");

  function getBufferFromFile(fileName, done) {
    console.log("Reading :" + fileName);

    fs.exists(fileName, function(exists) {
      if (exists) {
        fs.stat(fileName, function(error, stats) {
          if (error) {
            return done(error);
          }

          fs.open(fileName, "r", function(error, fd) {
            if (error) {
              return done(error);
            }
            var buffer = new Buffer(stats.size);

            fs.read(fd, buffer, 0, buffer.length, null, function(error, bytesRead, buffer) {
              fs.close(fd);
              return done(null, buffer, bytesRead);
            });
          });
        });
      } else {
        return done(new Error("File does not exist", indexFile));
      }
    });
  }

  // http://bocoup.com/weblog/getting-bitwise-with-javascript/
  function numToBinaryArray(num) {
    var res = [];
    var index, bitMask;

    for (bitMask = 0x80000000, index = 0; index < 32; bitMask >>>= 1, index++) {
      res[31 - index] = ((bitMask & num) ? 1 : 0);
    }

    console.log("" + num + " -> binary:"+res);
    return res;
  }

  function bufferReader(buffer, bytesRead) {
    var _buffer = buffer;
    var _delta = 0;
    var _bytesRead = bytesRead;

    return {
      readUInt32BE: function() {
        var result = _buffer.readUInt32BE(_delta);
        _delta += 4;
        return result;
      },

      readUInt16BE: function() {
        var result = _buffer.readUInt16BE(_delta);
        _delta += 2;
        return result;
      },

      readString: function() {
        var result = "";
        var state = 0;
        var len = 0;

        while (state !== 99) {
          var b = _buffer.readInt8(_delta);
          _delta++;
          len++;
          console.log("@@ (" + String.fromCharCode(b) + "),(" + b + "), at len=" + len + ",_delta:" + _delta);
          if (state === 0) {
            if (b === 0x00) {
              state = 1;
            } else {
              result = result + String.fromCharCode(b);
            }
          } else if (state === 1) {
            if (_delta % 8 === 0) {
              console.log("@@ delta:" + _delta);
              // var b = _buffer.readInt8(_delta + 1);
              // console.log("@@ next was:("+String.fromCharCode(b)+"),("+b+")");
              // var b = _buffer.readInt8(_delta + 2);
              // console.log("@@ next2 was:("+String.fromCharCode(b)+"),("+b+")");

              state = 99;
            } else {
              if (b !== 0x00) {
                throw new Error("bad string padding:" + b + ", with len:" + len);
              }
            }
          }
        }
        return result;
      },

      slice: function(length) {
        var result = _buffer.slice(_delta, _delta + length);
        _delta += length;
        return result;
      }
    }
  }

  //
  // http://schacon.github.io/gitbook/7_the_git_index.html
  //
  // https://github.com/git/git/blob/master/Documentation/technical/index-format.txt
  // https://code.google.com/p/git-core/source/browse/Documentation/technical/index-format.txt?spec=svne44b6df90cfd6ccbf35c3d147ff5a0e4e22fb17a&r=e44b6df90cfd6ccbf35c3d147ff5a0e4e22fb17a
  //
  // https://github.com/chrisdickinson/git-packidx-parser/blob/master/index.js
  // https://github.com/sbp/gin/blob/master/gin
  //
  // http://stackoverflow.com/questions/4084921/what-does-the-git-index-contain-exactly
  //
  function parseIndex(fileName, done) {
    getBufferFromFile(fileName, function(error, buffer, bytesRead) {
      if (error) {
        return done(error);
      }

      // prepare Buffer reader
      var br = bufferReader(buffer, bytesRead);

      // check for the 'DIRC' signature
      if (br.readUInt32BE() !== 0x44495243) {
        return done(new Error("Invalid signature:" + Number(buffer.readUInt32BE(0)).toString(16)));
      }

      var version = br.readUInt32BE();

      console.log("@@ version:" + version);

      var numberOfIndexEntries = br.readUInt32BE();

      console.log("@@ numberOfIndexEntries:" + numberOfIndexEntries);

      for (var i = 0; i < numberOfIndexEntries; i++) {
        var ctimeSeconds = br.readUInt32BE();
        var ctimeNanoSeconds = br.readUInt32BE();
        var mtimeSeconds = br.readUInt32BE();
        var mtimeNanoSeconds = br.readUInt32BE();
        var dev = br.readUInt32BE();
        var ino = br.readUInt32BE();
        console.log("@ ino:" + ino);
        var mode = br.readUInt32BE();
        var uid = br.readUInt32BE();
        console.log("@ uid:" + ino);
        var gid = br.readUInt32BE();
        var size = br.readUInt32BE();
        var sha1 = br.slice(20);
        var flags = br.readUInt16BE();
        console.log("@@ flags:" + flags);
        var nameLen = flags & 0x00000FFF
        console.log("nameLen is:" + nameLen)
        var pathName = br.readString();
        console.log("pathName:" + pathName);
      }

      console.log("--");

      return done(null, "youpi!");
    });
  }

  numToBinaryArray(0);
  numToBinaryArray(1);
  numToBinaryArray(128);
  numToBinaryArray(10);

  parseIndex(".git/index", function(err, info) {
    if (err) {
      console.log("ERR:", err);
    } else {
      console.log("DONE");
    }
  });
}());
<|endoftext|>


<commit_before>'use strict';

var major_progression = [0, 2, 4, 5, 7, 9, 11, 12, 11, 9, 7, 5, 4, 2, 0];
var minor_progression = [0, 2, 3, 5, 7, 8, 11, 12, 11, 8, 7, 5, 3, 2, 0];
var melodic_minor_progression = [0, 2, 3, 5, 7, 9, 11, 12, 10, 8, 7, 5, 3, 2, 0];

var major_fifths = ['C', 'G', 'D', 'A', 'E', 'B', 'G♭', 'D♭', 'A♭', 'E♭', 'B♭', 'F'];
var minor_fifths = ['A', 'E', 'B', 'F♯', 'C♯', 'G♯', 'D♯', 'B♭', 'F', 'C', 'G', 'D'];

var major_chromatic = ['C', 'D♭', 'D', 'E♭', 'E', 'F', 'G♭', 'G', 'A♭', 'A', 'B♭', 'B'];
var minor_chromatic = ['A', 'B♭', 'B', 'C', 'C♯', 'D', 'D♯', 'E', 'F', 'F♯', 'G', 'G♯'];

var myFace = function() {
  return "what";
}

angular.module('myApp.scale', ['ngRoute', 'ngCookies', 'ui.bootstrap'])

.config(['$routeProvider', function($routeProvider) {
  $routeProvider.when('/scale', {
    templateUrl: 'scale/scale.html',
    controller: 'ScaleCtrl'
  });
}])

.controller('ScaleCtrl', ['$scope', '$cookies', function($scope, $cookies) {
  $scope.debug = false;

  $scope.cookie = $cookies.getObject('scaler') || {};

  $scope.updateField = function(field, value) {
    $scope.cookie[field] = value;
  };

  $scope.updateData = function() {
    var now = new Date();
    var expiryDate = new Date(now.getFullYear() + 10, now.getMonth(), now.getDate());
    $cookies.putObject('scaler', $scope.cookie, {expires: expiryDate});
  };

  $scope.getField = function(field) {
    if ($scope.cookie.hasOwnProperty(field)) {
        return $scope.cookie[field];
    }
    return null;
  };

  $scope.major = "";
  $scope.tempos = {normal: 80};
  $scope.tempoIncrease = $scope.getField('tempoIncrease') ? $scope.getField('tempoIncrease') : 4;
  $scope.selected = $scope.getField('selected') ? $scope.getField('selected') : [];
  $scope.keysPerDay = $scope.getField('keysPerDay') ? $scope.getField('keysPerDay') : 3;
  $scope.doneToday = $scope.getField('doneToday') ? $scope.getField('doneToday') : 0;

  $scope.forToday = [];
  $scope.forTheFuture = [];

  $scope.lastUsedDate = $scope.getField("lastUsedDate");
  if (!$scope.lastUsedDate) {
    $scope.lastUsedDate = new Date()
    $scope.lastUsedDate.setDate($scope.lastUsedDate.getDate() - 1);
  } else {
    $scope.lastUsedDate = new Date($scope.lastUsedDate);
  }
  $scope.lastUsedDate.setHours(0,0,0,0); // In case the time is non-pure date

  $scope.majors = major_chromatic;
  $scope.minors = minor_chromatic;

  $scope.collectLists = function() {
    $scope.forToday = [];
    var numForToday = $scope.keysPerDay - $scope.doneToday;
    var selected = $scope.selected.slice();
    if (numForToday > 0) {
      while (numForToday-- && selected.length > 0) {
        $scope.forToday.push(selected.shift());
      }
    }
    $scope.forTheFuture = selected;
  };

  $scope.newDay = function() {
    $scope.doneToday = 0;
    $scope.updateField("doneToday", 0);
    $scope.updateData();
  };

  $scope.today = new Date();
  $scope.today.setHours(0,0,0,0);
  if ($scope.lastUsedDate.valueOf() !== $scope.today.valueOf()) {
    $scope.newDay();
  }

  $scope.collectLists();

  $scope.changeKeysPerDay = function() {
    $scope.updateField("keysPerDay", $scope.keysPerDay);
    $scope.updateData();
    $scope.collectLists();
  };

  $scope.changeTempoIncrease = function() {
    $scope.updateField("tempoIncrease", $scope.tempoIncrease);
    $scope.updateData();
  };

  $scope.resetDoneToday = function() {
    $scope.doneToday = 0;
    $scope.updateField("doneToday", 0);
    $scope.updateData();
    $scope.collectLists();
  };

  $scope.addToList = function(key, majorminor) {
    var newElement = {key: key + " " + majorminor, tempo: parseInt($scope.tempos.normal, 10)};
    $scope.selected.push(newElement);
    $scope.collectLists();
    $scope.updateField("selected", $scope.selected);
    $scope.updateData();
  };

  $scope.addAllToList = function(keys, majorminor) {
    keys.forEach(function(element, index, array) {
      $scope.addToList(element, majorminor);
    });
  };

  $scope.removeFromList = function(item) {
    var index = $scope.selected.indexOf(item);
    if (index > -1)
    {
      $scope.selected.splice(index, 1);
    }
    $scope.collectLists();
    $scope.updateField("selected", $scope.selected);
    $scope.updateData();
  };

  $scope.increaseTempo = function(item) {
    var index = $scope.selected.indexOf(item);
    if (index > -1)
    {
      $scope.selected.splice(index, 1);
      item.tempo += $scope.tempoIncrease;
      $scope.selected.push(item);
      $scope.doneToday += 1;
    }
    $scope.collectLists();

    $scope.updateField("selected", $scope.selected);
    var date = new Date();
    $scope.updateField("lastUsedDate", date.toISOString());
    $scope.updateField("doneToday", $scope.doneToday);
    $scope.updateData();
  };

}]);
<commit_msg>Move to localStorage. Oh my God, Santiago and Peralta forever<commit_after>'use strict';

var major_progression = [0, 2, 4, 5, 7, 9, 11, 12, 11, 9, 7, 5, 4, 2, 0];
var minor_progression = [0, 2, 3, 5, 7, 8, 11, 12, 11, 8, 7, 5, 3, 2, 0];
var melodic_minor_progression = [0, 2, 3, 5, 7, 9, 11, 12, 10, 8, 7, 5, 3, 2, 0];

var major_fifths = ['C', 'G', 'D', 'A', 'E', 'B', 'G♭', 'D♭', 'A♭', 'E♭', 'B♭', 'F'];
var minor_fifths = ['A', 'E', 'B', 'F♯', 'C♯', 'G♯', 'D♯', 'B♭', 'F', 'C', 'G', 'D'];

var major_chromatic = ['C', 'D♭', 'D', 'E♭', 'E', 'F', 'G♭', 'G', 'A♭', 'A', 'B♭', 'B'];
var minor_chromatic = ['A', 'B♭', 'B', 'C', 'C♯', 'D', 'D♯', 'E', 'F', 'F♯', 'G', 'G♯'];

var myFace = function() {
  return "what";
}

angular.module('myApp.scale', ['ngRoute', 'ui.bootstrap'])

.config(['$routeProvider', function($routeProvider) {
  $routeProvider.when('/scale', {
    templateUrl: 'scale/scale.html',
    controller: 'ScaleCtrl'
  });
}])

.controller('ScaleCtrl', ['$scope', function($scope) {
  $scope.debug = false;

  $scope.localStorage = localStorage;

  $scope.updateField = function(field, value) {
    $scope.localStorage.setItem(field, JSON.stringify(value));
  };

  $scope.updateData = function() {
    // Legacy, keeping for when we move to databases
  };

  $scope.getField = function(field) {
    return JSON.parse($scope.localStorage.getItem(field));
  };

  $scope.major = "";
  $scope.tempos = {normal: 80};
  $scope.tempoIncrease = $scope.getField('tempoIncrease') ? $scope.getField('tempoIncrease') : 4;
  $scope.selected = $scope.getField('selected') ? $scope.getField('selected') : [];
  $scope.keysPerDay = $scope.getField('keysPerDay') ? $scope.getField('keysPerDay') : 3;
  $scope.doneToday = $scope.getField('doneToday') ? $scope.getField('doneToday') : 0;

  $scope.forToday = [];
  $scope.forTheFuture = [];

  $scope.lastUsedDate = $scope.getField("lastUsedDate");
  if (!$scope.lastUsedDate) {
    $scope.lastUsedDate = new Date()
    $scope.lastUsedDate.setDate($scope.lastUsedDate.getDate() - 1);
  } else {
    $scope.lastUsedDate = new Date($scope.lastUsedDate);
  }
  $scope.lastUsedDate.setHours(0,0,0,0); // In case the time is non-pure date

  $scope.majors = major_chromatic;
  $scope.minors = minor_chromatic;

  $scope.collectLists = function() {
    $scope.forToday = [];
    var numForToday = $scope.keysPerDay - $scope.doneToday;
    var selected = $scope.selected.slice();
    if (numForToday > 0) {
      while (numForToday-- && selected.length > 0) {
        $scope.forToday.push(selected.shift());
      }
    }
    $scope.forTheFuture = selected;
  };

  $scope.newDay = function() {
    $scope.doneToday = 0;
    $scope.updateField("doneToday", 0);
    $scope.updateData();
  };

  $scope.today = new Date();
  $scope.today.setHours(0,0,0,0);
  if ($scope.lastUsedDate.valueOf() !== $scope.today.valueOf()) {
    $scope.newDay();
  }

  $scope.collectLists();

  $scope.changeKeysPerDay = function() {
    $scope.updateField("keysPerDay", $scope.keysPerDay);
    $scope.updateData();
    $scope.collectLists();
  };

  $scope.changeTempoIncrease = function() {
    $scope.updateField("tempoIncrease", $scope.tempoIncrease);
    $scope.updateData();
  };

  $scope.resetDoneToday = function() {
    $scope.doneToday = 0;
    $scope.updateField("doneToday", 0);
    $scope.updateData();
    $scope.collectLists();
  };

  $scope.addToList = function(key, majorminor) {
    var newElement = {key: key + " " + majorminor, tempo: parseInt($scope.tempos.normal, 10)};
    $scope.selected.push(newElement);
    $scope.collectLists();
    $scope.updateField("selected", $scope.selected);
    $scope.updateData();
  };

  $scope.addAllToList = function(keys, majorminor) {
    keys.forEach(function(element, index, array) {
      $scope.addToList(element, majorminor);
    });
  };

  $scope.removeFromList = function(item) {
    var index = $scope.selected.indexOf(item);
    if (index > -1)
    {
      $scope.selected.splice(index, 1);
    }
    $scope.collectLists();
    $scope.updateField("selected", $scope.selected);
    $scope.updateData();
  };

  $scope.increaseTempo = function(item) {
    var index = $scope.selected.indexOf(item);
    if (index > -1)
    {
      $scope.selected.splice(index, 1);
      item.tempo += $scope.tempoIncrease;
      $scope.selected.push(item);
      $scope.doneToday += 1;
    }
    $scope.collectLists();

    $scope.updateField("selected", $scope.selected);
    var date = new Date();
    $scope.updateField("lastUsedDate", date.toISOString());
    $scope.updateField("doneToday", $scope.doneToday);
    $scope.updateData();
  };

}]);
<|endoftext|>