<commit_before>/*
 * grunt-ivantage-svn-changelog
 * https://github.com/iVantage/grunt-ivantage-svn-changelog
 *
 * Copyright (c) 2013 iVantage Health Analytics
 * Licensed under the MIT license.
 */

'use strict';

module.exports = function(grunt) {

  var sh = require('shelljs')
    , Handlebars = require('handlebars');

  var getHeadRev
    , getRevFromKey
    , getRevFromTag
    , getRevFromSvnInfo
    , getLastSemverTag;

  var getCommitHeaderType
    , getCommitHeaderScope
    , getCommitHeaderSummary;

  var Parser = require('svn-log-parse').Parser
    , parser = new Parser();

  var changelogTpl = Handlebars.compile(grunt.file.read(__dirname + '/../assets/changeset.md.handlebars'));

  grunt.registerMultiTask('ivantage_svn_changelog', 'Build changelogs from your svn commit message history', function() {

    if(!sh.which('svn')) {
      grunt.fail.fatal('ivantage_svn_changelog requires the svn command line tools');
    }

    // Note the final changelog will honor this order
    var allFlags = [
      'feature',
      'fix',
      'style',
      'docs',
      'chore',
      'refactor',
      'test',
      'admin',
      'partial'
    ];

    var opts = this.options({
      // See the `allFlags` var
      flags: ['feature', 'fix'],

      revFrom: 'LAST_SEMVER_TAG',
      revTo: 'HEAD',

      // Should be a beanstalk(?) changeset url with a placeholder for the
      // revision number
      changesetUrl: '#{{revision}}',

      outFile: 'CHANGELOG.md'
    });

    var revFrom = +getRevFromKey(opts.revFrom)
      , revTo = +getRevFromKey(opts.revTo);

    // Makes sure we only get legal flags
    opts.flags = opts.flags.filter(function(f) {
      return -1 !== allFlags.indexOf(f);
    });

    if(revFrom > 0) {
      var cmd = sh.exec('svn log -r ' + revFrom + ':' + revTo, {silent: true});
      if(cmd.code === 0) {
        var logs = parser.parse(cmd.output);

        // The first line of every message should be of the form:
        // <type>:(<scope>): <summary>
        var ix, firstLine, type, scope, summary, revision;

        var scopes = [], messages = {};

        var initScopeFlags = function(scope) {
          allFlags.forEach(function(f) {
            messages[scope].flags[f] = [];
          });
        };

        for(ix = logs.length; ix--;) {
          firstLine = logs[ix].message.split(/\r\n?/)[0];
          type = getCommitHeaderType(firstLine);
          scope = getCommitHeaderScope(firstLine);
          summary = getCommitHeaderSummary(firstLine);
          revision = logs[ix].revision.replace(/^r/, '');

          if(-1 !== opts.flags.indexOf(type)) {
            if(!messages.hasOwnProperty(scope)) {
              messages[scope] = {
                label: scope,
                flags: {}
              };

              // Make sure these are added in sorted order
              initScopeFlags(scope);
            }

            messages[scope].flags[type].push({
              summary: summary,
              revision: revision,
              changeset: opts.changesetUrl.replace('{{revision}}', revision)
            });
          }

        }

        // We had to add all flags to keep their order - now go through and
        // clear out the empty ones
        Object.keys(messages).forEach(function(scope) {
          var ix, f;
          for(ix = allFlags.length; ix--;) {
            f = allFlags[ix];
            if(0 === messages[scope].flags[f].length) {
              delete messages[scope].flags[f];
            }
          }
        });

        var messagesSorted = {};

        // Sort our scopes so we get consistent output, there's no
        // good/gaurenteed way to sort object keys so... just create a new
        // object and assign it keys in alpha order
        Object.keys(messages).forEach(function(scope) {
          messagesSorted[scope] = messages[scope];
        });

        var changelogMd = changelogTpl({
          messages: messagesSorted,
          revFrom: revFrom,
          revTo: revTo
        });
        grunt.file.write(opts.outFile, changelogMd);

        grunt.log.ok('CHANGELOG written to: ' + opts.outFile);

        return;
      }
    }
    grunt.fail.fatal('Could not resolve ' + revFrom + ' to a revision number');

  });

  getRevFromKey = function(revKey) {
    // Could be:
    // - 'HEAD'
    // - TAG:<tag name>
    // - 'LAST_SEMVER_TAG'
    // - an actual revision number

    // Could be 'HEAD'
    if('HEAD' === revKey) {
      return getHeadRev();
    }

    if(/LAST_SEMVER_TAG/.test(revKey+'')) {
      var parts = revKey.split(':')
        , numTagsAgo = parts.length === 2 ? parts[1] : 1;
      var lastSemverTag = getLastSemverTag(numTagsAgo);
      return getRevFromTag(lastSemverTag);
    }

    // Could be 'TAG:<tag>'
    if(/TAG:.*/.test(revKey + '')) {
      return getRevFromTag(revKey.replace(/^TAG:/, ''));
    }

    // Could just be a number
    if(/\d+/.test(revKey + '')) {
      return revKey;
    }
  };

  getLastSemverTag = function(numTagsAgo) {
    var cmd = sh.exec('node "'  + __dirname + '/../util/last-semver-tag.js" ' + numTagsAgo, {silent: true});
    if(cmd.code === 0) {
      var tag = cmd.output.trim();
      if(tag.length) {
        return tag;
      }
    }
    grunt.fail.fatal('Ouch, could not get your last semver tag');
  };

  getHeadRev = function() {
    var cmd = sh.exec('svn info -r HEAD', {silent: true});
    if(cmd.code === 0) {
      return getRevFromSvnInfo(cmd.output);
    } else {
      grunt.fail.fatal('Could not get rev number for HEAD');
    }
  };

  getRevFromTag = function(tag) {
    var cmd = sh.exec('svn info "^/tags/' + tag + '"', {silent: true});
    if(cmd.code === 0) {
      return getRevFromSvnInfo(cmd.output);
    } else {
      grunt.fail.fatal('Could not get rev number for tag ' + tag);
    }
  };

  getRevFromSvnInfo = function(svnInfo) {
    var lines = svnInfo.split(/\r?\n/g), l, ix;
    for(ix = lines.length; ix--;) {
      l = lines[ix].split(':');
      if(l.length === 2) {
        if(l[0].trim() === 'Last Changed Rev') {
          return +l[1].trim();
        }
      }
    }
    return -1;
  };

  getCommitHeaderType = function(header) {
    var parts = header.split(':');
    return parts[0].replace(/\(.*/, '').trim();
  };

  getCommitHeaderScope = function(header) {
    var parts = header.split(':')
      , scope = parts[0];

    if(-1 === scope.indexOf('(') || -1 === scope.indexOf(')')) {
      return 'misc';
    }

    scope = scope
      .replace(/.*\(/, '')
      .replace(/\).*/, '')
      .trim();

    return scope.length ? scope : 'misc';
  };

  getCommitHeaderSummary = function(header) {
    var parts = header.split(':');
    return parts.length === 2 ? parts[1].trim() : '';
  };

};

<commit_msg>fix: Correctly handle new lines for *nix systems<commit_after>/*
 * grunt-ivantage-svn-changelog
 * https://github.com/iVantage/grunt-ivantage-svn-changelog
 *
 * Copyright (c) 2013 iVantage Health Analytics
 * Licensed under the MIT license.
 */

'use strict';

module.exports = function(grunt) {

  var sh = require('shelljs')
    , Handlebars = require('handlebars');

  var getHeadRev
    , getRevFromKey
    , getRevFromTag
    , getRevFromSvnInfo
    , getLastSemverTag;

  var getCommitHeaderType
    , getCommitHeaderScope
    , getCommitHeaderSummary;

  var Parser = require('svn-log-parse').Parser
    , parser = new Parser();

  var changelogTpl = Handlebars.compile(grunt.file.read(__dirname + '/../assets/changeset.md.handlebars'));

  grunt.registerMultiTask('ivantage_svn_changelog', 'Build changelogs from your svn commit message history', function() {

    if(!sh.which('svn')) {
      grunt.fail.fatal('ivantage_svn_changelog requires the svn command line tools');
    }

    // Note the final changelog will honor this order
    var allFlags = [
      'feature',
      'fix',
      'style',
      'docs',
      'chore',
      'refactor',
      'test',
      'admin',
      'partial'
    ];

    var opts = this.options({
      // See the `allFlags` var
      flags: ['feature', 'fix'],

      revFrom: 'LAST_SEMVER_TAG',
      revTo: 'HEAD',

      // Should be a beanstalk(?) changeset url with a placeholder for the
      // revision number
      changesetUrl: '#{{revision}}',

      outFile: 'CHANGELOG.md'
    });

    var revFrom = +getRevFromKey(opts.revFrom)
      , revTo = +getRevFromKey(opts.revTo);

    // Makes sure we only get legal flags
    opts.flags = opts.flags.filter(function(f) {
      return -1 !== allFlags.indexOf(f);
    });

    if(revFrom > 0) {
      var cmd = sh.exec('svn log -r ' + revFrom + ':' + revTo, {silent: true});
      if(cmd.code === 0) {
        var logs = parser.parse(cmd.output);

        // The first line of every message should be of the form:
        // <type>:(<scope>): <summary>
        var ix, firstLine, type, scope, summary, revision;

        var scopes = [], messages = {};

        var initScopeFlags = function(scope) {
          allFlags.forEach(function(f) {
            messages[scope].flags[f] = [];
          });
        };

        for(ix = logs.length; ix--;) {
          firstLine = logs[ix].message.split(/\r?\n/)[0];
          type = getCommitHeaderType(firstLine);
          scope = getCommitHeaderScope(firstLine);
          summary = getCommitHeaderSummary(firstLine);
          revision = logs[ix].revision.replace(/^r/, '');

          if(-1 !== opts.flags.indexOf(type)) {
            if(!messages.hasOwnProperty(scope)) {
              messages[scope] = {
                label: scope,
                flags: {}
              };

              // Make sure these are added in sorted order
              initScopeFlags(scope);
            }

            messages[scope].flags[type].push({
              summary: summary,
              revision: revision,
              changeset: opts.changesetUrl.replace('{{revision}}', revision)
            });
          }

        }

        // We had to add all flags to keep their order - now go through and
        // clear out the empty ones
        Object.keys(messages).forEach(function(scope) {
          var ix, f;
          for(ix = allFlags.length; ix--;) {
            f = allFlags[ix];
            if(0 === messages[scope].flags[f].length) {
              delete messages[scope].flags[f];
            }
          }
        });

        var messagesSorted = {};

        // Sort our scopes so we get consistent output, there's no
        // good/gaurenteed way to sort object keys so... just create a new
        // object and assign it keys in alpha order
        Object.keys(messages).forEach(function(scope) {
          messagesSorted[scope] = messages[scope];
        });

        var changelogMd = changelogTpl({
          messages: messagesSorted,
          revFrom: revFrom,
          revTo: revTo
        });
        grunt.file.write(opts.outFile, changelogMd);

        grunt.log.ok('CHANGELOG written to: ' + opts.outFile);

        return;
      }
    }
    grunt.fail.fatal('Could not resolve ' + revFrom + ' to a revision number');

  });

  getRevFromKey = function(revKey) {
    // Could be:
    // - 'HEAD'
    // - TAG:<tag name>
    // - 'LAST_SEMVER_TAG'
    // - an actual revision number

    // Could be 'HEAD'
    if('HEAD' === revKey) {
      return getHeadRev();
    }

    if(/LAST_SEMVER_TAG/.test(revKey+'')) {
      var parts = revKey.split(':')
        , numTagsAgo = parts.length === 2 ? parts[1] : 1;
      var lastSemverTag = getLastSemverTag(numTagsAgo);
      return getRevFromTag(lastSemverTag);
    }

    // Could be 'TAG:<tag>'
    if(/TAG:.*/.test(revKey + '')) {
      return getRevFromTag(revKey.replace(/^TAG:/, ''));
    }

    // Could just be a number
    if(/\d+/.test(revKey + '')) {
      return revKey;
    }
  };

  getLastSemverTag = function(numTagsAgo) {
    var cmd = sh.exec('node "'  + __dirname + '/../util/last-semver-tag.js" ' + numTagsAgo, {silent: true});
    if(cmd.code === 0) {
      var tag = cmd.output.trim();
      if(tag.length) {
        return tag;
      }
    }
    grunt.fail.fatal('Ouch, could not get your last semver tag');
  };

  getHeadRev = function() {
    var cmd = sh.exec('svn info -r HEAD', {silent: true});
    if(cmd.code === 0) {
      return getRevFromSvnInfo(cmd.output);
    } else {
      grunt.fail.fatal('Could not get rev number for HEAD');
    }
  };

  getRevFromTag = function(tag) {
    var cmd = sh.exec('svn info "^/tags/' + tag + '"', {silent: true});
    if(cmd.code === 0) {
      return getRevFromSvnInfo(cmd.output);
    } else {
      grunt.fail.fatal('Could not get rev number for tag ' + tag);
    }
  };

  getRevFromSvnInfo = function(svnInfo) {
    var lines = svnInfo.split(/\r?\n/g), l, ix;
    for(ix = lines.length; ix--;) {
      l = lines[ix].split(':');
      if(l.length === 2) {
        if(l[0].trim() === 'Last Changed Rev') {
          return +l[1].trim();
        }
      }
    }
    return -1;
  };

  getCommitHeaderType = function(header) {
    var parts = header.split(':');
    return parts[0].replace(/\(.*/, '').trim();
  };

  getCommitHeaderScope = function(header) {
    var parts = header.split(':')
      , scope = parts[0];

    if(-1 === scope.indexOf('(') || -1 === scope.indexOf(')')) {
      return 'misc';
    }

    scope = scope
      .replace(/.*\(/, '')
      .replace(/\).*/, '')
      .trim();

    return scope.length ? scope : 'misc';
  };

  getCommitHeaderSummary = function(header) {
    var parts = header.split(':');
    return parts.length === 2 ? parts[1].trim() : '';
  };

};

<|endoftext|>


<commit_before>'use strict';
/**
 * If a pattern matches the token stream,
 * then run transform.
 */

const utils = require('./utils.js');

module.exports = [
  {
    /**
     * ```python {.cls}
     * for i in range(10):
     *     print(i)
     * ```
     */
    name: 'fenced code blocks',
    tests: [
      {
        shift: 0,
        block: true,
        info: utils.hasCurly('end')
      }
    ],
    transform: (tokens, i) => {
      let token = tokens[i];
      let start = token.info.lastIndexOf('{');
      let attrs = utils.getAttrs(token.info, start);
      utils.addAttrs(attrs, token);
      token.info = utils.removeCurly(token.info);
    }
  }, {
    /**
     * bla `click()`{.c} ![](img.png){.d}
     *
     * differs from 'inline attributes' as it does
     * not have a closing tag (nesting: -1)
     */
    name: 'inline nesting 0',
    tests: [
      {
        shift: 0,
        type: 'inline',
        children: [
          {
            shift: -1,
            type: (str) => str === 'image' || str === 'code_inline'
          }, {
            shift: 0,
            type: 'text',
            content: utils.hasCurly('start')
          }
        ]
      }
    ],
    transform: (tokens, i, j) => {
      let token = tokens[i].children[j];
      let endChar = token.content.indexOf('}');
      let attrToken = tokens[i].children[j - 1];
      let attrs = utils.getAttrs(token.content, 0);
      utils.addAttrs(attrs, attrToken);
      token.content = token.content.slice(endChar + 1);
    }
  }, {
    /**
     * | h1 |
     * | -- |
     * | c1 |
     * {.c}
     */
    name: 'tables',
    tests: [
      {
        // let this token be i, such that for-loop continues at
        // next token after tokens.splice
        shift: 0,
        type: 'table_close'
      }, {
        shift: 1,
        type: 'paragraph_open'
      }, {
        shift: 2,
        type: 'inline',
        content: utils.hasCurly('only')
      }
    ],
    transform: (tokens, i) => {
      let token = tokens[i + 2];
      let tableOpen = utils.getMatchingOpeningToken(tokens, i);
      let attrs = utils.getAttrs(token.content, 0);
      // add attributes
      utils.addAttrs(attrs, tableOpen);
      // remove
{.c}

      tokens.splice(i + 1, 3);
    }
  }, {
    /**
     * *emphasis*{.with attrs=1}
     */
    name: 'inline attributes',
    tests: [
      {
        shift: 0,
        type: 'inline',
        children: [
          {
            shift: -1,
            nesting: -1  // closing inline tag, {.a}
          }, {
            shift: 0,
            type: 'text',
            content: utils.hasCurly('start')
          }
        ]
      }
    ],
    transform: (tokens, i, j) => {
      let token = tokens[i].children[j];
      let content = token.content;
      let attrs = utils.getAttrs(content, 0);
      let openingToken = utils.getMatchingOpeningToken(tokens[i].children, j - 1);
      utils.addAttrs(attrs, openingToken);
      token.content = content.slice(content.indexOf('}') + 1);
    }
  }, {
    /**
     * - item
     * {.a}
     */
    name: 'list softbreak',
    tests: [
      {
        shift: -2,
        type: 'list_item_open'
      }, {
        shift: 0,
        type: 'inline',
        children: [
          {
            position: -2,
            type: 'softbreak'
          }, {
            position: -1,
            content: utils.hasCurly('only')
          }
        ]
      }
    ],
    transform: (tokens, i, j) => {
      let token = tokens[i].children[j];
      let content = token.content;
      let attrs = utils.getAttrs(content, 0);
      let ii = i - 2;
      while (tokens[ii - 1] &&
        tokens[ii - 1].type !== 'ordered_list_open' &&
        tokens[ii - 1].type !== 'bullet_list_open') { ii--; }
      utils.addAttrs(attrs, tokens[ii - 1]);
      tokens[i].children = tokens[i].children.slice(0, -2);
    }
  }, {
    /**
     * - nested list
     *   - with double \n
     *   {.a} <-- apply to nested ul
     *
     * {.b} <-- apply to root

     */
    name: 'list double softbreak',
    tests: [
      {
        // let this token be i = 0 so that we can erase
        // the
{.a}
 tokens below
        shift: 0,
        type: (str) =>
          str === 'bullet_list_close' ||
          str === 'ordered_list_close'
      }, {
        shift: 1,
        type: 'paragraph_open'
      }, {
        shift: 2,
        type: 'inline',
        content: utils.hasCurly('only'),
        children: (arr) => arr.length === 1
      }, {
        shift: 3,
        type: 'paragraph_close'
      }
    ],
    transform: (tokens, i) => {
      let token = tokens[i + 2];
      let content = token.content;
      let attrs = utils.getAttrs(content, 0);
      let openingToken = utils.getMatchingOpeningToken(tokens, i);
      utils.addAttrs(attrs, openingToken);
      tokens.splice(i + 1, 3);
    }
  }, {
    /**
     * - end of {.list-item}
     */
    name: 'list item end',
    tests: [
      {
        shift: -2,
        type: 'list_item_open'
      }, {
        shift: 0,
        type: 'inline',
        children: [
          {
            position: -1,
            content: utils.hasCurly('end')
          }
        ]
      }
    ],
    transform: (tokens, i, j) => {
      let token = tokens[i].children[j];
      let content = token.content;
      let attrs = utils.getAttrs(content, content.lastIndexOf('{'));
      utils.addAttrs(attrs, tokens[i - 2]);
      let trimmed = content.slice(0, content.lastIndexOf('{'));
      token.content = last(trimmed) !== ' ' ?
        trimmed : trimmed.slice(0, -1);
    }
  }, {
    /**
     * something with softbreak
     * {.cls}
     */
    name: '\n{.a} softbreak then curly in start',
    tests: [
      {
        shift: 0,
        type: 'inline',
        children: [
          {
            position: -2,
            type: 'softbreak'
          }, {
            position: -1,
            type: 'text',
            content: utils.hasCurly('only')
          }
        ]
      }
    ],
    transform: (tokens, i, j) => {
      let token = tokens[i].children[j];
      let attrs = utils.getAttrs(token.content, 0);
      // find last closing tag
      let ii = i + 1;
      while (tokens[ii + 1] && tokens[ii + 1].nesting === -1) { ii++; }
      let openingToken = utils.getMatchingOpeningToken(tokens, ii);
      utils.addAttrs(attrs, openingToken);
      tokens[i].children = tokens[i].children.slice(0, -2);
    }
  }, {
    /**
     * end of {.block}
     */
    name: 'end of block',
    tests: [
      {
        shift: 0,
        type: 'inline',
        children: [
          {
            position: -1,
            content: utils.hasCurly('end')
          }
        ]
      }
    ],
    transform: (tokens, i, j) => {
      let token = tokens[i].children[j];
      let content = token.content;
      let attrs = utils.getAttrs(content, content.lastIndexOf('{'));
      let ii = i + 1;
      while (tokens[ii + 1] && tokens[ii + 1].nesting === -1) { ii++; }
      let openingToken = utils.getMatchingOpeningToken(tokens, ii);
      utils.addAttrs(attrs, openingToken);
      let trimmed = content.slice(0, content.lastIndexOf('{'));
      token.content = last(trimmed) !== ' ' ?
        trimmed : trimmed.slice(0, -1);
    }
  }
];

// get last element of array or string
function last(arr) {
  return arr.slice(-1)[0];
}

<commit_msg>fix bug arve0/markdown-it-implicit-figures#18<commit_after>'use strict';
/**
 * If a pattern matches the token stream,
 * then run transform.
 */

const utils = require('./utils.js');

module.exports = [
  {
    /**
     * ```python {.cls}
     * for i in range(10):
     *     print(i)
     * ```
     */
    name: 'fenced code blocks',
    tests: [
      {
        shift: 0,
        block: true,
        info: utils.hasCurly('end')
      }
    ],
    transform: (tokens, i) => {
      let token = tokens[i];
      let start = token.info.lastIndexOf('{');
      let attrs = utils.getAttrs(token.info, start);
      utils.addAttrs(attrs, token);
      token.info = utils.removeCurly(token.info);
    }
  }, {
    /**
     * bla `click()`{.c} ![](img.png){.d}
     *
     * differs from 'inline attributes' as it does
     * not have a closing tag (nesting: -1)
     */
    name: 'inline nesting 0',
    tests: [
      {
        shift: 0,
        type: 'inline',
        children: [
          {
            shift: -1,
            type: (str) => str === 'image' || str === 'code_inline'
          }, {
            shift: 0,
            type: 'text',
            content: utils.hasCurly('start')
          }
        ]
      }
    ],
    transform: (tokens, i, j) => {
      let token = tokens[i].children[j];
      let endChar = token.content.indexOf('}');
      let attrToken = tokens[i].children[j - 1];
      let attrs = utils.getAttrs(token.content, 0);
      utils.addAttrs(attrs, attrToken);
      if (token.content.length === (endChar + 1)) {
        tokens[i].children.splice(j, 1);
      } else {
        token.content = token.content.slice(endChar + 1);
      }
    }
  }, {
    /**
     * | h1 |
     * | -- |
     * | c1 |
     * {.c}
     */
    name: 'tables',
    tests: [
      {
        // let this token be i, such that for-loop continues at
        // next token after tokens.splice
        shift: 0,
        type: 'table_close'
      }, {
        shift: 1,
        type: 'paragraph_open'
      }, {
        shift: 2,
        type: 'inline',
        content: utils.hasCurly('only')
      }
    ],
    transform: (tokens, i) => {
      let token = tokens[i + 2];
      let tableOpen = utils.getMatchingOpeningToken(tokens, i);
      let attrs = utils.getAttrs(token.content, 0);
      // add attributes
      utils.addAttrs(attrs, tableOpen);
      // remove
{.c}

      tokens.splice(i + 1, 3);
    }
  }, {
    /**
     * *emphasis*{.with attrs=1}
     */
    name: 'inline attributes',
    tests: [
      {
        shift: 0,
        type: 'inline',
        children: [
          {
            shift: -1,
            nesting: -1  // closing inline tag, {.a}
          }, {
            shift: 0,
            type: 'text',
            content: utils.hasCurly('start')
          }
        ]
      }
    ],
    transform: (tokens, i, j) => {
      let token = tokens[i].children[j];
      let content = token.content;
      let attrs = utils.getAttrs(content, 0);
      let openingToken = utils.getMatchingOpeningToken(tokens[i].children, j - 1);
      utils.addAttrs(attrs, openingToken);
      token.content = content.slice(content.indexOf('}') + 1);
    }
  }, {
    /**
     * - item
     * {.a}
     */
    name: 'list softbreak',
    tests: [
      {
        shift: -2,
        type: 'list_item_open'
      }, {
        shift: 0,
        type: 'inline',
        children: [
          {
            position: -2,
            type: 'softbreak'
          }, {
            position: -1,
            content: utils.hasCurly('only')
          }
        ]
      }
    ],
    transform: (tokens, i, j) => {
      let token = tokens[i].children[j];
      let content = token.content;
      let attrs = utils.getAttrs(content, 0);
      let ii = i - 2;
      while (tokens[ii - 1] &&
        tokens[ii - 1].type !== 'ordered_list_open' &&
        tokens[ii - 1].type !== 'bullet_list_open') { ii--; }
      utils.addAttrs(attrs, tokens[ii - 1]);
      tokens[i].children = tokens[i].children.slice(0, -2);
    }
  }, {
    /**
     * - nested list
     *   - with double \n
     *   {.a} <-- apply to nested ul
     *
     * {.b} <-- apply to root

     */
    name: 'list double softbreak',
    tests: [
      {
        // let this token be i = 0 so that we can erase
        // the
{.a}
 tokens below
        shift: 0,
        type: (str) =>
          str === 'bullet_list_close' ||
          str === 'ordered_list_close'
      }, {
        shift: 1,
        type: 'paragraph_open'
      }, {
        shift: 2,
        type: 'inline',
        content: utils.hasCurly('only'),
        children: (arr) => arr.length === 1
      }, {
        shift: 3,
        type: 'paragraph_close'
      }
    ],
    transform: (tokens, i) => {
      let token = tokens[i + 2];
      let content = token.content;
      let attrs = utils.getAttrs(content, 0);
      let openingToken = utils.getMatchingOpeningToken(tokens, i);
      utils.addAttrs(attrs, openingToken);
      tokens.splice(i + 1, 3);
    }
  }, {
    /**
     * - end of {.list-item}
     */
    name: 'list item end',
    tests: [
      {
        shift: -2,
        type: 'list_item_open'
      }, {
        shift: 0,
        type: 'inline',
        children: [
          {
            position: -1,
            content: utils.hasCurly('end')
          }
        ]
      }
    ],
    transform: (tokens, i, j) => {
      let token = tokens[i].children[j];
      let content = token.content;
      let attrs = utils.getAttrs(content, content.lastIndexOf('{'));
      utils.addAttrs(attrs, tokens[i - 2]);
      let trimmed = content.slice(0, content.lastIndexOf('{'));
      token.content = last(trimmed) !== ' ' ?
        trimmed : trimmed.slice(0, -1);
    }
  }, {
    /**
     * something with softbreak
     * {.cls}
     */
    name: '\n{.a} softbreak then curly in start',
    tests: [
      {
        shift: 0,
        type: 'inline',
        children: [
          {
            position: -2,
            type: 'softbreak'
          }, {
            position: -1,
            type: 'text',
            content: utils.hasCurly('only')
          }
        ]
      }
    ],
    transform: (tokens, i, j) => {
      let token = tokens[i].children[j];
      let attrs = utils.getAttrs(token.content, 0);
      // find last closing tag
      let ii = i + 1;
      while (tokens[ii + 1] && tokens[ii + 1].nesting === -1) { ii++; }
      let openingToken = utils.getMatchingOpeningToken(tokens, ii);
      utils.addAttrs(attrs, openingToken);
      tokens[i].children = tokens[i].children.slice(0, -2);
    }
  }, {
    /**
     * end of {.block}
     */
    name: 'end of block',
    tests: [
      {
        shift: 0,
        type: 'inline',
        children: [
          {
            position: -1,
            content: utils.hasCurly('end')
          }
        ]
      }
    ],
    transform: (tokens, i, j) => {
      let token = tokens[i].children[j];
      let content = token.content;
      let attrs = utils.getAttrs(content, content.lastIndexOf('{'));
      let ii = i + 1;
      while (tokens[ii + 1] && tokens[ii + 1].nesting === -1) { ii++; }
      let openingToken = utils.getMatchingOpeningToken(tokens, ii);
      utils.addAttrs(attrs, openingToken);
      let trimmed = content.slice(0, content.lastIndexOf('{'));
      token.content = last(trimmed) !== ' ' ?
        trimmed : trimmed.slice(0, -1);
    }
  }
];

// get last element of array or string
function last(arr) {
  return arr.slice(-1)[0];
}

<|endoftext|>


<commit_before>sys = require('sys');
assert = require('assert');
Client = require(__dirname+"/../lib/").Client;
Parser = require(__dirname+"/../lib/").Parser;

test = function(name, action) {
  for(var i = 0; i < test.tabout; i++) {
    name = ' ' + name;
  }
  test.tabout += 2;
  console.log(name);
  action();
  test.tabout -= 2;
};
test.tabout = 0;

stringToHex = function(string) {

};

hexToString = function(hexArray) {
  return new Buffer(hexArray).toString('utf8');
}
<commit_msg>whitespace<commit_after>sys = require('sys');
assert = require('assert');
Client = require(__dirname+"/../lib/").Client;
Parser = require(__dirname+"/../lib/").Parser;

test = function(name, action) {
  for(var i = 0; i < test.tabout; i++) {
    name = ' ' + name;
  }
  test.tabout += 2;
  console.log(name);
  action();

  test.tabout -= 2;
};
test.tabout = 0;

stringToHex = function(string) {

};

hexToString = function(hexArray) {
  return new Buffer(hexArray).toString('utf8');
}
<|endoftext|>


<commit_before>import React from 'react';
import { formValueSelector } from 'redux-form';
import { connect } from 'react-redux';
import PropTypes from 'prop-types';

import Grid from 'material-ui/Grid';
import CountryField from '../forms/fields/projectFields/locationField/countryField';
import YearFieldForm from '../forms/yearFieldForm';
import TextFieldForm from '../forms/textFieldForm';
import RadioForm from '../forms/radioForm';
import { visibleIfYes, visibleIfNo, BOOL_VAL } from '../../helpers/formHelper';
import { PLACEHOLDERS } from '../../helpers/constants';
import FileForm from '../forms/fileForm';
import DatePickerForm from '../forms/datePickerForm';

const messages = {
  yearOfEstablishment: 'Year of establishment in country of origin',
  selectYear: 'Select year',
  registrationCountry: 'Is organization registered to operate in the country of origin?',
  registrationDoc: 'Does the organization have Registration Document?',
  date: 'Registration Date',
  number: 'Registration number (If applicable)',
  document: 'Please upload Registration Document',
  comment: 'Comment',
  name: 'Name of registering authority',
  expireDate: 'Expiration date',
  govDocTooltip: 'Governing document: is a formal document with information about the structure ' +
  'and governance of an organization, outlining the purposes of the organization and how it will ' +
  'be run. A governing document may come in the form of a trust deed, constitution, memorandum ' +
  'and articles of association, or another formal, legal document.',
  haveGovDoc: 'Does the Organization have a Governing Document?',
  governingDoc: 'Please upload Governing Document',
  haveRefLetter: 'Does the organization have a letter o reference from a donor agency, government authority or community association?',
  referenceLetter: 'Please upload letter of reference',
  nameOfRefferer: 'Name of referring organization',
  received: 'Date Received',
};

const BasicInformation = (props) => {
  const { isRegistered, hasRegistrationDoc, hasGovDoc, hasRefLetter } = props;
  return (
    <Grid item>
      <Grid container direction="column" spacing={16}>
        <Grid item sm={6} xs={12}>
          <YearFieldForm
            fieldName="json.partner_profile.year_establishment"
            label={messages.yearOfEstablishment}
            placeholder={messages.selectYear}
          />
        </Grid>
        <Grid item>
          <RadioForm
            fieldName="json.partner_profile.registered_to_operate_in_country"
            label={messages.registrationCountry}
            values={BOOL_VAL}
          />
        </Grid>
        {visibleIfYes(isRegistered)
            && <Grid item>
              <Grid container direction="row">
                <Grid item sm={4} xs={12}>
                  <DatePickerForm
                    fieldName="json.registration_document.issue_date"
                    label={messages.date}
                    placeholder={PLACEHOLDERS.provide}
                  />
                </Grid>
                <Grid item sm={8} xs={12}>
                  <TextFieldForm
                    label={messages.number}
                    fieldName="json.registration_document.registration_number"
                    optional
                    placeholder={PLACEHOLDERS.provide}
                  />
                </Grid>
              </Grid>
              <Grid container direction="column">
                <Grid item>
                  <TextFieldForm
                    label={messages.name}
                    fieldName="json.registration_document.issuing_authority"
                    placeholder={PLACEHOLDERS.provide}
                  />
                </Grid>
                <Grid item sm={4} xs={12}>
                  <DatePickerForm
                    fieldName="json.registration_document.expiry_date"
                    label={messages.expireDate}
                    optional
                    placeholder={PLACEHOLDERS.provide}
                  />
                </Grid>
                <Grid item>
                  <RadioForm
                    fieldName="json.registration_document.have_registration_doc"
                    label={messages.registrationDoc}
                    values={BOOL_VAL}
                  />
                </Grid>
                {visibleIfYes(hasRegistrationDoc) && <Grid item>
                  <FileForm
                    fieldName="json.registration_document.document"
                    formName="registration"
                    sectionName="registration_document"
                    localUpload
                    label={messages.document}
                  />
                </Grid>}
                {visibleIfNo(hasRegistrationDoc) && <Grid item>
                  <TextFieldForm
                    label={messages.comment}
                    fieldName="json.partner_profile.missing_registration_document_comment"
                    placeholder={PLACEHOLDERS.provide}
                  />
                </Grid>}
              </Grid>
            </Grid>}
        {visibleIfNo(isRegistered) && <Grid item>
          <TextFieldForm
            label={messages.comment}
            fieldName="json.partner_profile.missing_registration_document_comment"
            textFieldProps={{
              multiline: true,
              InputProps: {
                inputProps: {
                  maxLength: '500',
                },
              },
            }}
          />
        </Grid>}
        <Grid item sm={6} xs={12}>
          <RadioForm
            fieldName="json.partner_profile.have_governing_document"
            label={messages.haveGovDoc}
            values={BOOL_VAL}
          />
        </Grid>
        {visibleIfYes(hasGovDoc) && <Grid item sm={6} xs={12}>
          <FileForm
            fieldName="json.governing_document.document"
            formName="registration"
            sectionName="governing_document"
            localUpload
            label={messages.governingDoc}
            infoText={messages.govDocTooltip}
          />
        </Grid>}
        {visibleIfNo(hasGovDoc) && <Grid item>
          <TextFieldForm
            label={messages.comment}
            fieldName="json.partner_profile.missing_governing_document_comment"
            textFieldProps={{
              multiline: true,
              InputProps: {
                inputProps: {
                  maxLength: '500',
                },
              },
            }}
          />
        </Grid>}
        <Grid item>
          <RadioForm
            fieldName="json.recommendation_document.have_ref_letter"
            label={messages.haveRefLetter}
            values={BOOL_VAL}
          />
        </Grid>
        {visibleIfYes(hasRefLetter) && <Grid item sm={12} xs={12}>
          <Grid container direction="row">
            <Grid item sm={6} xs={12}>
              <TextFieldForm
                label={messages.nameOfRefferer}
                fieldName="json.recommendation_document.organization_name"
                placeholder={PLACEHOLDERS.provide}
              />
            </Grid>

            <Grid item sm={6} xs={12}>
              <DatePickerForm
                fieldName="json.recommendation_document.date_received"
                label={messages.received}
              />
            </Grid>
          </Grid>
          <FileForm
            fieldName="json.recommendation_document.evidence_file"
            formName="registration"
            sectionName="recommendation_document"
            localUpload
            label={messages.referenceLetter}
          />
        </Grid>}
      </Grid>
    </Grid>
  );
};

BasicInformation.propTypes = {
  isRegistered: PropTypes.bool,
  hasRegistrationDoc: PropTypes.bool,
  hasGovDoc: PropTypes.bool,
  hasRefLetter: PropTypes.bool,
};

const selector = formValueSelector('registration');
const connectedBasicInformation = connect(
  state => ({
    isRegistered: selector(state, 'json.partner_profile.registered_to_operate_in_country'),
    hasRegistrationDoc: selector(state, 'json.registration_document.have_registration_doc'),
    hasGovDoc: selector(state, 'json.partner_profile.have_governing_document'),
    hasRefLetter: selector(state, 'json.recommendation_document.have_ref_letter'),
  }),
)(BasicInformation);

export default connectedBasicInformation;
<commit_msg>rename field section<commit_after>import React from 'react';
import { formValueSelector } from 'redux-form';
import { connect } from 'react-redux';
import PropTypes from 'prop-types';

import Grid from 'material-ui/Grid';
import CountryField from '../forms/fields/projectFields/locationField/countryField';
import YearFieldForm from '../forms/yearFieldForm';
import TextFieldForm from '../forms/textFieldForm';
import RadioForm from '../forms/radioForm';
import { visibleIfYes, visibleIfNo, BOOL_VAL } from '../../helpers/formHelper';
import { PLACEHOLDERS } from '../../helpers/constants';
import FileForm from '../forms/fileForm';
import DatePickerForm from '../forms/datePickerForm';

const messages = {
  yearOfEstablishment: 'Year of establishment in country of origin',
  selectYear: 'Select year',
  registrationCountry: 'Is organization registered to operate in the country of origin?',
  registrationDoc: 'Does the organization have Registration Document?',
  date: 'Registration Date',
  number: 'Registration number (If applicable)',
  document: 'Please upload Registration Document',
  comment: 'Comment',
  name: 'Name of registering authority',
  expireDate: 'Expiration date',
  govDocTooltip: 'Governing document: is a formal document with information about the structure ' +
  'and governance of an organization, outlining the purposes of the organization and how it will ' +
  'be run. A governing document may come in the form of a trust deed, constitution, memorandum ' +
  'and articles of association, or another formal, legal document.',
  haveGovDoc: 'Does the Organization have a Governing Document?',
  governingDoc: 'Please upload Governing Document',
  haveRefLetter: 'Does the organization have a letter o reference from a donor agency, government authority or community association?',
  referenceLetter: 'Please upload letter of reference',
  nameOfRefferer: 'Name of referring organization',
  received: 'Date Received',
};

const BasicInformation = (props) => {
  const { isRegistered, hasRegistrationDoc, hasGovDoc, hasRefLetter } = props;
  return (
    <Grid item>
      <Grid container direction="column" spacing={16}>
        <Grid item sm={6} xs={12}>
          <YearFieldForm
            fieldName="json.partner_profile.year_establishment"
            label={messages.yearOfEstablishment}
            placeholder={messages.selectYear}
          />
        </Grid>
        <Grid item>
          <RadioForm
            fieldName="json.partner_profile.registered_to_operate_in_country"
            label={messages.registrationCountry}
            values={BOOL_VAL}
          />
        </Grid>
        {visibleIfYes(isRegistered)
            && <Grid item>
              <Grid container direction="row">
                <Grid item sm={4} xs={12}>
                  <DatePickerForm
                    fieldName="json.registration_document.issue_date"
                    label={messages.date}
                    placeholder={PLACEHOLDERS.provide}
                  />
                </Grid>
                <Grid item sm={8} xs={12}>
                  <TextFieldForm
                    label={messages.number}
                    fieldName="json.registration_document.registration_number"
                    optional
                    placeholder={PLACEHOLDERS.provide}
                  />
                </Grid>
              </Grid>
              <Grid container direction="column">
                <Grid item>
                  <TextFieldForm
                    label={messages.name}
                    fieldName="json.registration_document.issuing_authority"
                    placeholder={PLACEHOLDERS.provide}
                  />
                </Grid>
                <Grid item sm={4} xs={12}>
                  <DatePickerForm
                    fieldName="json.registration_document.expiry_date"
                    label={messages.expireDate}
                    optional
                    placeholder={PLACEHOLDERS.provide}
                  />
                </Grid>
                <Grid item>
                  <RadioForm
                    fieldName="json.registration_document.have_registration_doc"
                    label={messages.registrationDoc}
                    values={BOOL_VAL}
                  />
                </Grid>
                {visibleIfYes(hasRegistrationDoc) && <Grid item>
                  <FileForm
                    fieldName="json.registration_document.document"
                    formName="registration"
                    sectionName="registration_document"
                    localUpload
                    label={messages.document}
                  />
                </Grid>}
                {visibleIfNo(hasRegistrationDoc) && <Grid item>
                  <TextFieldForm
                    label={messages.comment}
                    fieldName="json.partner_profile.missing_registration_document_comment"
                    placeholder={PLACEHOLDERS.provide}
                  />
                </Grid>}
              </Grid>
            </Grid>}
        {visibleIfNo(isRegistered) && <Grid item>
          <TextFieldForm
            label={messages.comment}
            fieldName="json.partner_profile.missing_registration_document_comment"
            textFieldProps={{
              multiline: true,
              InputProps: {
                inputProps: {
                  maxLength: '500',
                },
              },
            }}
          />
        </Grid>}
        <Grid item sm={6} xs={12}>
          <RadioForm
            fieldName="json.partner_profile.have_governing_document"
            label={messages.haveGovDoc}
            values={BOOL_VAL}
          />
        </Grid>
        {visibleIfYes(hasGovDoc) && <Grid item sm={6} xs={12}>
          <FileForm
            fieldName="json.governing_document.document"
            formName="registration"
            sectionName="governing_document"
            localUpload
            label={messages.governingDoc}
            infoText={messages.govDocTooltip}
          />
        </Grid>}
        {visibleIfNo(hasGovDoc) && <Grid item>
          <TextFieldForm
            label={messages.comment}
            fieldName="json.partner_profile.missing_governing_document_comment"
            textFieldProps={{
              multiline: true,
              InputProps: {
                inputProps: {
                  maxLength: '500',
                },
              },
            }}
          />
        </Grid>}
        <Grid item>
          <RadioForm
            fieldName="json.partner_profile.have_ref_letter"
            label={messages.haveRefLetter}
            values={BOOL_VAL}
          />
        </Grid>
        {visibleIfYes(hasRefLetter) && <Grid item sm={12} xs={12}>
          <Grid container direction="row">
            <Grid item sm={6} xs={12}>
              <TextFieldForm
                label={messages.nameOfRefferer}
                fieldName="json.recommendation_document.organization_name"
                placeholder={PLACEHOLDERS.provide}
              />
            </Grid>

            <Grid item sm={6} xs={12}>
              <DatePickerForm
                fieldName="json.recommendation_document.date_received"
                label={messages.received}
              />
            </Grid>
          </Grid>
          <FileForm
            fieldName="json.recommendation_document.evidence_file"
            formName="registration"
            sectionName="recommendation_document"
            localUpload
            label={messages.referenceLetter}
          />
        </Grid>}
      </Grid>
    </Grid>
  );
};

BasicInformation.propTypes = {
  isRegistered: PropTypes.bool,
  hasRegistrationDoc: PropTypes.bool,
  hasGovDoc: PropTypes.bool,
  hasRefLetter: PropTypes.bool,
};

const selector = formValueSelector('registration');
const connectedBasicInformation = connect(
  state => ({
    isRegistered: selector(state, 'json.partner_profile.registered_to_operate_in_country'),
    hasRegistrationDoc: selector(state, 'json.registration_document.have_registration_doc'),
    hasGovDoc: selector(state, 'json.partner_profile.have_governing_document'),
    hasRefLetter: selector(state, 'json.recommendation_document.have_ref_letter'),
  }),
)(BasicInformation);

export default connectedBasicInformation;
<|endoftext|>


<commit_before>(function ($) {

    var csscls = PhpDebugBar.utils.makecsscls('phpdebugbar-widgets-');

    /**
     * Widget for the displaying sql queries
     *
     * Options:
     *  - data
     */
    var SQLQueriesWidget = PhpDebugBar.Widgets.SQLQueriesWidget = PhpDebugBar.Widget.extend({
        className: csscls('sqlqueries'),
        onFilterClick: function (el, cls, reverse, reset) {
            if (typeof (reset) != 'undefined' && reset) {
                this.$toolbar.find(csscls('.filter')).each(function () {
                    $(this).addClass(csscls('excluded'));
                });
                this.$list.$el.find("li").show();
            }

            $(el).toggleClass(csscls('excluded'));

            var excludedLabels = [];
            this.$toolbar.find(csscls('filter') + csscls('excluded')).each(function () {
                excludedLabels.push(this.rel);
            });

            if (typeof (reverse) != 'undefined' && reverse) {
                this.$list.$el.find("li:not(." + csscls(cls) + ')').toggle();
            } else {
                this.$list.$el.find("li:not(." + csscls(cls) + ')').toggle();
            }

            this.set('exclude', excludedLabels);
        },
        render: function () {
            this.$status = $('
').addClass(csscls('status')).appendTo(this.$el);

            this.$toolbar = $('

').addClass(csscls('toolbar')).appendTo(this.$el);

            var filters = [], self = this;

            this.$list = new PhpDebugBar.Widgets.ListWidget({itemRenderer: function (li, stmt) {
                    $('').addClass(csscls('sql')).html(PhpDebugBar.Widgets.highlight(stmt.sql, 'sql')).appendTo(li);
                    if (stmt.duration_str) {
                        $('').addClass(csscls('duration')).text(stmt.duration_str).appendTo(li);
                    }
                    if (stmt.memory_str) {
                        $('').addClass(csscls('memory')).text(stmt.memory_str).appendTo(li);
                    }
                    if (typeof (stmt.row_count) != 'undefined') {
                        $('').addClass(csscls('row-count')).text(stmt.row_count).appendTo(li);
                    }
                    if (typeof (stmt.source) != 'undefined' && stmt.source) {
                        $('').addClass(csscls('source')).text(stmt.source).appendTo(li);
                    }
                    if (typeof (stmt.stmt_id) != 'undefined' && stmt.stmt_id) {
                        $('').addClass(csscls('stmt-id')).text(stmt.stmt_id).appendTo(li);
                    }
                    if (typeof stmt.warn !== 'undefined' && stmt.warn) {
                        li.addClass(csscls('database-time-warning'));
                    }
                    if (stmt.database) {
                        $('').addClass(csscls('database')).text(stmt.database).appendTo(li);
                        li.addClass(csscls('database' + stmt.database));
                        if ($.inArray(stmt.database, filters) == -1) {
                            filters.push(stmt.database);
                        }
                    }
                    if (typeof (stmt.is_success) != 'undefined' && !stmt.is_success) {
                        li.addClass(csscls('error'));
                        li.append($('').addClass(csscls('error')).text("[" + stmt.error_code + "] " + stmt.error_message));
                    }
                    if (stmt.params) {
                        var table;
                        switch ($.type(stmt.params)) {
                            case 'string':
                                table = $('
' + stmt.params + '
').appendTo(li);
                                break;
                            case 'array':
                                if ($.isEmptyObject(stmt.params)) {
                                    break;
                                }
                                table = $('

Params

').addClass(csscls('params')).appendTo(li);
                                for (var key in stmt.params) {
                                    if (typeof stmt.params[key] !== 'function') {
                                        table.append('
' + key + '	' + stmt.params[key] + '
');
                                    }
                                }
                                break;
                        }
                        if (table) {
                            li.css('cursor', 'pointer').click(function () {
                                if (table.is(':visible')) {
                                    table.hide();
                                } else {
                                    table.show();
                                }
                            });
                        }
                    }
                }
            });

            this.$list.$el.appendTo(this.$el);

            this.bindAttr('data', function (data) {
                this.$list.set('data', data.statements);
                this.$status.empty();

                // Search for duplicate statements.
                for (var sql = {}, duplicate = 0, i = 0; i < data.statements.length; i++) {
                    var stmt = data.statements[i].sql;
                    if (data.statements[i].params && !$.isEmptyObject(data.statements[i].params)) {
                        stmt += ' {' + $.param(data.statements[i].params, false) + '}';
                    }
                    sql[stmt] = sql[stmt] || {keys: []};
                    sql[stmt].keys.push(i);
                }
                // Add classes to all duplicate SQL statements.
                for (var stmt in sql) {
                    if (sql[stmt].keys.length > 1) {
                        duplicate++;
                        for (var i = 0; i < sql[stmt].keys.length; i++) {
                            // Add a visual badge
                            var $badge = $('' + duplicate + '');
                            this.$list.$el.find('.' + csscls('list-item')).eq(sql[stmt].keys[i])
                                    .addClass(csscls('sql-duplicate')).addClass(csscls('sql-duplicate-' + duplicate)).append($badge);
                        }
                    }
                }

                var t = $('').text(data.nb_statements + " statements were executed").appendTo(this.$status);
                if (data.nb_failed_statements) {
                    t.append(", " + data.nb_failed_statements + " of which failed");
                }
                if (duplicate) {
                    t.append(", " + duplicate + " of which were duplicated");
                }
                if (data.accumulated_duration_str) {
                    this.$status.append($('').addClass(csscls('duration')).text(data.accumulated_duration_str));
                }
                if (data.memory_usage_str) {
                    this.$status.append($('').addClass(csscls('memory')).text(data.memory_usage_str));
                }

                // We have multiple database or duplicates, show filters
                if (filters.length > 1 || duplicate) {
                    self.$toolbar.empty();

                    if (filters.length > 1) {
                        $.each(filters, function (index, value) {
                            $('')
                                    .addClass(csscls('filter'))
                                    .text('db:' + value)
                                    .attr('rel', value)
                                    .on('click', function () {
                                        self.onFilterClick(this, 'database-' + value);
                                    })
                                    .appendTo(self.$toolbar);
                        });
                    } else {
                        filters = [];
                    }

                    if (duplicate) {
                        $('')
                                .addClass(csscls('filter'))
                                .addClass(csscls('excluded'))
                                .text('all duplicates')
                                .attr('rel', '_duplicated')
                                .on('click', function () {
                                    self.onFilterClick(this, 'sql-duplicate', true);
                                })
                                .appendTo(self.$toolbar);

                        for (var i = duplicate; i > 0; i--) {
                            $('')
                                    .addClass(csscls('filter'))
                                    .addClass(csscls('excluded'))
                                    .data('duplicate', i)
                                    .text('duplicates ' + i)
                                    .attr('rel', '_duplicated_' + i)
                                    .on('click', function () {
                                        self.onFilterClick(this, 'sql-duplicate-' + $(this).data('duplicate'), true, true);
                                    })
                                    .appendTo(self.$toolbar);
                        }
                    }
                    self.$toolbar.show();
                    self.$list.$el.css("margin-bottom", "24px");
                }
            });
        }

    });

})(PhpDebugBar.$);
<commit_msg>add tooltip<commit_after>(function ($) {

    var csscls = PhpDebugBar.utils.makecsscls('phpdebugbar-widgets-');

    /**
     * Widget for the displaying sql queries
     *
     * Options:
     *  - data
     */
    var SQLQueriesWidget = PhpDebugBar.Widgets.SQLQueriesWidget = PhpDebugBar.Widget.extend({
        className: csscls('sqlqueries'),
        onFilterClick: function (el, cls, reverse, reset) {
            if (typeof (reset) != 'undefined' && reset) {
                this.$toolbar.find(csscls('.filter')).each(function () {
                    $(this).addClass(csscls('excluded'));
                });
                this.$list.$el.find("li").show();
            }

            $(el).toggleClass(csscls('excluded'));

            var excludedLabels = [];
            this.$toolbar.find(csscls('filter') + csscls('excluded')).each(function () {
                excludedLabels.push(this.rel);
            });

            if (typeof (reverse) != 'undefined' && reverse) {
                this.$list.$el.find("li:not(." + csscls(cls) + ')').toggle();
            } else {
                this.$list.$el.find("li:not(." + csscls(cls) + ')').toggle();
            }

            this.set('exclude', excludedLabels);
        },
        render: function () {
            this.$status = $('
').addClass(csscls('status')).appendTo(this.$el);

            this.$toolbar = $('

').addClass(csscls('toolbar')).appendTo(this.$el);

            var filters = [], self = this;

            this.$list = new PhpDebugBar.Widgets.ListWidget({itemRenderer: function (li, stmt) {
                    $('').addClass(csscls('sql')).html(PhpDebugBar.Widgets.highlight(stmt.sql, 'sql')).appendTo(li);
                    if (stmt.duration_str) {
                        $('').addClass(csscls('duration')).text(stmt.duration_str).appendTo(li);
                    }
                    if (stmt.memory_str) {
                        $('').addClass(csscls('memory')).text(stmt.memory_str).appendTo(li);
                    }
                    if (typeof (stmt.row_count) != 'undefined') {
                        $('').addClass(csscls('row-count')).text(stmt.row_count).appendTo(li);
                    }
                    if (typeof (stmt.source) != 'undefined' && stmt.source) {
                        $('').addClass(csscls('source')).text(stmt.source).appendTo(li);
                    }
                    if (typeof (stmt.stmt_id) != 'undefined' && stmt.stmt_id) {
                        $('').addClass(csscls('stmt-id')).text(stmt.stmt_id).appendTo(li);
                    }
                    if (typeof stmt.warn !== 'undefined' && stmt.warn) {
                        li.addClass(csscls('database-time-warning'));
                    }
                    if (stmt.database) {
                        $('').addClass(csscls('database')).text(stmt.database).appendTo(li);
                        li.addClass(csscls('database' + stmt.database));
                        if ($.inArray(stmt.database, filters) == -1) {
                            filters.push(stmt.database);
                        }
                    }
                    if (typeof (stmt.is_success) != 'undefined' && !stmt.is_success) {
                        li.addClass(csscls('error'));
                        li.append($('').addClass(csscls('error')).text("[" + stmt.error_code + "] " + stmt.error_message));
                    }
                    if (stmt.params) {
                        var table;
                        switch ($.type(stmt.params)) {
                            case 'string':
                                table = $('
' + stmt.params + '
').appendTo(li);
                                break;
                            case 'array':
                                if ($.isEmptyObject(stmt.params)) {
                                    break;
                                }
                                table = $('

Params

').addClass(csscls('params')).appendTo(li);
                                for (var key in stmt.params) {
                                    if (typeof stmt.params[key] !== 'function') {
                                        table.append('
' + key + '	' + stmt.params[key] + '
');
                                    }
                                }
                                break;
                        }
                        if (table) {
                            li.css('cursor', 'pointer').click(function () {
                                if (table.is(':visible')) {
                                    table.hide();
                                } else {
                                    table.show();
                                }
                            });
                        }
                    }
                }
            });

            this.$list.$el.appendTo(this.$el);

            this.bindAttr('data', function (data) {
                this.$list.set('data', data.statements);
                this.$status.empty();

                // Search for duplicate statements.
                for (var sql = {}, duplicate = 0, i = 0; i < data.statements.length; i++) {
                    var stmt = data.statements[i].sql;
                    if (data.statements[i].params && !$.isEmptyObject(data.statements[i].params)) {
                        stmt += ' {' + $.param(data.statements[i].params, false) + '}';
                    }
                    sql[stmt] = sql[stmt] || {keys: []};
                    sql[stmt].keys.push(i);
                }
                // Add classes to all duplicate SQL statements.
                for (var stmt in sql) {
                    if (sql[stmt].keys.length > 1) {
                        duplicate++;
                        for (var i = 0; i < sql[stmt].keys.length; i++) {
                            // Add a visual badge
                            var $badge = $('' + duplicate + '');
                            this.$list.$el.find('.' + csscls('list-item')).eq(sql[stmt].keys[i])
                                    .addClass(csscls('sql-duplicate')).addClass(csscls('sql-duplicate-' + duplicate)).append($badge);
                        }
                    }
                }

                var t = $('').text(data.nb_statements + " statements were executed").appendTo(this.$status);
                if (data.nb_failed_statements) {
                    t.append(", " + data.nb_failed_statements + " of which failed");
                }
                if (duplicate) {
                    t.append(", " + duplicate + " of which were duplicated");
                }
                if (data.accumulated_duration_str) {
                    this.$status.append($('').addClass(csscls('duration')).text(data.accumulated_duration_str));
                }
                if (data.memory_usage_str) {
                    this.$status.append($('').addClass(csscls('memory')).text(data.memory_usage_str));
                }

                // We have multiple database or duplicates, show filters
                if (filters.length > 1 || duplicate) {
                    self.$toolbar.empty();

                    if (filters.length > 1) {
                        $.each(filters, function (index, value) {
                            $('')
                                    .addClass(csscls('filter'))
                                    .text('db:' + value)
                                    .attr('rel', value)
                                    .on('click', function () {
                                        self.onFilterClick(this, 'database-' + value);
                                    })
                                    .appendTo(self.$toolbar);
                        });
                    } else {
                        filters = [];
                    }

                    if (duplicate) {
                        $('')
                                .addClass(csscls('filter'))
                                .addClass(csscls('excluded'))
                                .text('all duplicates')
                                .attr('rel', '_duplicated')
                                .on('click', function () {
                                    self.onFilterClick(this, 'sql-duplicate', true);
                                })
                                .appendTo(self.$toolbar);

                        for (var i = duplicate; i > 0; i--) {
                            $('')
                                    .addClass(csscls('filter'))
                                    .addClass(csscls('excluded'))
                                    .data('duplicate', i)
                                    .text('duplicates ' + i)
                                    .attr('rel', '_duplicated_' + i)
                                    .on('click', function () {
                                        self.onFilterClick(this, 'sql-duplicate-' + $(this).data('duplicate'), true, true);
                                    })
                                    .appendTo(self.$toolbar);
                        }
                    }
                    self.$toolbar.show();
                    self.$list.$el.css("margin-bottom", "24px");
                }
            });
        }

    });

})(PhpDebugBar.$);
<|endoftext|>


<commit_before>(function($, root) {
  "use strict"

  var GOVUK = root.GOVUK = {
    Modules: {}
  };

  GOVUK.find = function(container) {

    var modules,
        pattern = '[data-module]',
        container = container || $('body');

    modules = container.find(pattern);

    // Include container if it matches pattern, as that could
    // be a module too
    if (container.is(pattern)) {
      modules.push(container);
    }

    return modules;
  }

  GOVUK.start = function(container) {

    var modules = this.find(container);

    for (var i = 0, l = modules.length; i < l; i++) {

      var module,
          element = $(modules[i]),
          type = camelCaseAndCapitalise(element.data('module'));

      if (typeof GOVUK.Modules[type] === "function") {
        module = new GOVUK.Modules[type]();
        module.start(element);
      }
    }

    // eg selectable-table to SelectableTable
    function camelCaseAndCapitalise(string) {
      return capitaliseFirstLetter(camelCase(string));
    }

    // http://stackoverflow.com/questions/6660977/convert-hyphens-to-camel-case-camelcase
    function camelCase(string) {
      return string.replace(/-([a-z])/g, function (g) {
        return g[1].toUpperCase();
      });
    }

    // http://stackoverflow.com/questions/1026069/capitalize-the-first-letter-of-string-in-javascript
    function capitaliseFirstLetter(string) {
      return string.charAt(0).toUpperCase() + string.slice(1);
    }

  }

  GOVUK.startAll = function() {
    GOVUK.start();
  }

})(jQuery, window);
<commit_msg>Rename pattern to moduleSelector<commit_after>(function($, root) {
  "use strict"

  var GOVUK = root.GOVUK = {
    Modules: {}
  };

  GOVUK.find = function(container) {

    var modules,
        moduleSelector = '[data-module]',
        container = container || $('body');

    modules = container.find(moduleSelector);

    // Include container if it matches pattern, as that could
    // be a module too
    if (container.is(moduleSelector)) {
      modules.push(container);
    }

    return modules;
  }

  GOVUK.start = function(container) {

    var modules = this.find(container);

    for (var i = 0, l = modules.length; i < l; i++) {

      var module,
          element = $(modules[i]),
          type = camelCaseAndCapitalise(element.data('module'));

      if (typeof GOVUK.Modules[type] === "function") {
        module = new GOVUK.Modules[type]();
        module.start(element);
      }
    }

    // eg selectable-table to SelectableTable
    function camelCaseAndCapitalise(string) {
      return capitaliseFirstLetter(camelCase(string));
    }

    // http://stackoverflow.com/questions/6660977/convert-hyphens-to-camel-case-camelcase
    function camelCase(string) {
      return string.replace(/-([a-z])/g, function (g) {
        return g[1].toUpperCase();
      });
    }

    // http://stackoverflow.com/questions/1026069/capitalize-the-first-letter-of-string-in-javascript
    function capitaliseFirstLetter(string) {
      return string.charAt(0).toUpperCase() + string.slice(1);
    }

  }

  GOVUK.startAll = function() {
    GOVUK.start();
  }

})(jQuery, window);
<|endoftext|>


<commit_before>/**
 * mutation-testing-karma
 *
 * @author Marco Stahl
 * @author Jimi van der Woning
 * @author Martin Koster
 */
'use strict';
var _ = require('lodash'),
    fs = require('fs'),
    path = require('path'),
    Q = require('q'),
    xml2js = require('xml2js');

var CopyUtils = require('../utils/CopyUtils'),
    IOUtils = require('../utils/IOUtils'),
    KarmaServer = require('../lib/KarmaServer');

exports.init = function(grunt, opts) {
    if(opts.testFramework !== 'karma') {
        return;
    }

    var karmaServers = [],
        karmaConfig,
        karmaConfigOrig,
        fileSpecs = {},
        baseCoverage = {},
        port = 12111;

    function startServer(config, callback) {
        var server = new KarmaServer(config, port++);
        karmaServers.push(server);
        server.start().done(function(instance) {
            callback(instance);
        });
    }

    function stopServers() {
        karmaServers.forEach(function(instance) {
            instance.kill();
        });
        karmaServers = [];
    }

    function getCoverage(specFile) {
        var deferred = Q.defer(),
            files = specFile ? opts.code.concat(specFile) : opts.code,
            config = _.merge({}, karmaConfig, { files: files }, {
                reporters: ['coverage'],
                preprocessors: _.zipObject(_.map(opts.mutate, function(file) {
                    return [file, 'coverage'];
                })),
                coverageReporter: {
                    type: 'cobertura',
                    dir: 'coverage',
                    subdir: '.',
                    file: (specFile ? specFile : 'dummy') + 'coverage.xml'
                }
            }),
            coverageFile = path.join(config.basePath, config.coverageReporter.dir, config.coverageReporter.file);

        startServer(config, function(instance) {
            instance.runTests().done(function() {
                getFileLineCoverage(coverageFile).then(function(fileLineCoverage) {
                    instance.kill();
                    deferred.resolve(fileLineCoverage);
                }, function(error) {
                    deferred.reject(error);
                });
            });
        });

        return deferred.promise;
    }

    function parseCoverage(xmlData) {
        var deferred = Q.defer();
        xml2js.parseString(xmlData, function(err, data) {
            if(err) {
                console.warn('Error', err);
                deferred.reject(err);
            } else {
                deferred.resolve(data);
            }
        });
        return deferred.promise;
    }

    function stripOffBasePath(fileName) {
        var basePath = IOUtils.normalizeWindowsPath(_.last(opts.basePath.split(karmaConfig.basePath))).slice(1);
        return _.last(IOUtils.normalizeWindowsPath(fileName).split(basePath));
    }

    function getFileLineCoverage(coverageFile) {
        var deferred = Q.defer(),
            fileLineCoverage = {};

        try {
            IOUtils.readFileEventually(coverageFile, karmaConfig.waitForServerTime * 1000).done(function(xmlData) {
                parseCoverage(xmlData).done(function(coverageData) {
                    coverageData.coverage.packages.forEach(function(pkgs) {
                        pkgs['package'].forEach(function(pkg) {
                            pkg.classes.forEach(function(clss) {
                                clss['class'].forEach(function(cls) {
                                    var fileName = IOUtils.normalizeWindowsPath(cls.$['filename']),
                                        lineCoverage = Number(cls.$['line-rate']);
                                    fileLineCoverage[fileName] = lineCoverage;
                                });
                            });
                        });
                    });

                    deferred.resolve(fileLineCoverage);
                });
            });
        } catch(err) {
            console.warn("Error", err);
            deferred.reject(err);
        }

        return deferred.promise;
    }

    function findCodeSpecs() {
        var deferred = Q.defer(),
            codeSpecs = {};

        if(karmaConfig.fileSpecs) {
            if(_.isString(karmaConfig.fileSpecs)) {
                try {
                    karmaConfig.fileSpecs = JSON.parse(fs.readFileSync(karmaConfig.fileSpecs));
                } catch(error) {
                    deferred.reject(error);
                    return deferred.promise;
                }
            }

            // Create a mapping from source code to its specs, or to all specs when not explicitly provided
            _.forEach(opts.mutate, function(file) {
                file = IOUtils.normalizeWindowsPath(file);
                var mutateFileSpecs = _.find(karmaConfig.fileSpecs, function(fsSpecs, fsFile) {
                    return file.indexOf(IOUtils.normalizeWindowsPath(fsFile)) !== -1;
                });

                codeSpecs[file] = mutateFileSpecs || _.map(opts.specs, function(spec) {
                    return stripOffBasePath(spec);
                });
            });

            deferred.resolve(codeSpecs);
        } else {
            getCoverage().done(function(coverage) {
                baseCoverage = coverage;

                var specCoveragePromises = [];
                _.forEach(opts.specs, function(specFile) {
                    var deferred = Q.defer();

                    getCoverage(specFile).then(function(specCoverage) {
                        _.forOwn(specCoverage, function(coverage, file) {
                            var relativeFile = stripOffBasePath(file),
                                relativeSpecFile = stripOffBasePath(specFile);
                            if(coverage > baseCoverage[file]) {
                                if(codeSpecs[relativeFile]) {
                                    codeSpecs[relativeFile].push(relativeSpecFile);
                                } else {
                                    codeSpecs[relativeFile] = [relativeSpecFile];
                                }
                            }
                        });
                        deferred.resolve(specCoverage);
                    }, function(error) {
                        deferred.reject(error);
                    });

                    specCoveragePromises.push(deferred.promise);
                });

                Q.all(specCoveragePromises).then(function() {
                    deferred.resolve(codeSpecs);
                }, function(error) {
                    deferred.reject(error);
                });
            });
        }

        return deferred.promise;
    }

    opts.before = function(doneBefore) {
        karmaConfig = _.extend(
            {
                // defaults, but can be overwritten
                basePath: '.',
                reporters: [],
                logLevel: 'INFO',
                waitForServerTime: 5
            },
            opts.karma,
            {
                // can't be overwritten, because important for us
                configFile: opts.karma && opts.karma.configFile ? path.resolve(opts.karma.configFile) : undefined,
                background: false,
                singleRun: false,
                autoWatch: false,
                port: port
            }
        );

        function finalizeBefore(callback) {
            findCodeSpecs().then(function(codeSpecs) {
                grunt.log.writeln("Found pairs of code files and specs:\n", JSON.stringify(codeSpecs, null, 2));
                _.forEach(codeSpecs, function(specs, code) {
                    fileSpecs[code] = _.map(specs, function(spec) {
                        return path.join(opts.basePath, spec);
                    });
                });
                callback();
            });
        }

        if(!opts.mutateProductionCode) {
            CopyUtils.copyToTemp(opts.code.concat(opts.specs), 'mutation-testing').done(function(tempDirPath) {
                // Set the basePath relative to the temp dir
                karmaConfig.basePath = tempDirPath;
                opts.basePath = path.join(tempDirPath, opts.basePath);

                // Set the paths to the files to be mutated relative to the temp dir
                opts.mutate = _.map(opts.mutate, function(file) {
                    return path.join(tempDirPath, file);
                });

                finalizeBefore(doneBefore);
            });
        } else {
            finalizeBefore(doneBefore);
        }

        process.on('exit', function() {
            stopServers();
        });
    };

    opts.beforeEach = function(done) {
        var currentFileSpecs;

        // Find the specs for the current mutation file
        currentFileSpecs = _.find(fileSpecs, function(specs, file) {
            return opts.currentFile.replace(/\\/g, '/').indexOf(file) !== -1;
        });

        karmaConfig.files = opts.code.concat(currentFileSpecs || []);

        startServer(karmaConfig, function(instance) {
            opts.currentInstance = instance;
            done();
        });
    };

    opts.test = function(done) {
        opts.currentInstance.runTests().then(function(testSuccess) {
            done(testSuccess);
        }, function(error) {
            grunt.log.warn('\n' + error);
            startServer(karmaConfig, function(instance) {
                opts.currentInstance = instance;
                done(false);
            });
        });
    };

    opts.afterEach = function(done) {
        opts.currentInstance.kill();
        done();
    };

    opts.after = function() {
        stopServers();
    };
};
<commit_msg>Fixed default waitForServerTime set in two locations<commit_after>/**
 * mutation-testing-karma
 *
 * @author Marco Stahl
 * @author Jimi van der Woning
 * @author Martin Koster
 */
'use strict';
var _ = require('lodash'),
    fs = require('fs'),
    path = require('path'),
    Q = require('q'),
    xml2js = require('xml2js');

var CopyUtils = require('../utils/CopyUtils'),
    IOUtils = require('../utils/IOUtils'),
    KarmaServer = require('../lib/KarmaServer');

exports.init = function(grunt, opts) {
    if(opts.testFramework !== 'karma') {
        return;
    }

    var karmaServers = [],
        karmaConfig,
        karmaConfigOrig,
        fileSpecs = {},
        baseCoverage = {},
        port = 12111;

    function startServer(config, callback) {
        var server = new KarmaServer(config, port++);
        karmaServers.push(server);
        server.start().done(function(instance) {
            callback(instance);
        });
    }

    function stopServers() {
        karmaServers.forEach(function(instance) {
            instance.kill();
        });
        karmaServers = [];
    }

    function getCoverage(specFile) {
        var deferred = Q.defer(),
            files = specFile ? opts.code.concat(specFile) : opts.code,
            config = _.merge({}, karmaConfig, { files: files }, {
                reporters: ['coverage'],
                preprocessors: _.zipObject(_.map(opts.mutate, function(file) {
                    return [file, 'coverage'];
                })),
                coverageReporter: {
                    type: 'cobertura',
                    dir: 'coverage',
                    subdir: '.',
                    file: (specFile ? specFile : 'dummy') + 'coverage.xml'
                }
            }),
            coverageFile = path.join(config.basePath, config.coverageReporter.dir, config.coverageReporter.file);

        startServer(config, function(instance) {
            instance.runTests().done(function() {
                getFileLineCoverage(coverageFile).then(function(fileLineCoverage) {
                    instance.kill();
                    deferred.resolve(fileLineCoverage);
                }, function(error) {
                    deferred.reject(error);
                });
            });
        });

        return deferred.promise;
    }

    function parseCoverage(xmlData) {
        var deferred = Q.defer();
        xml2js.parseString(xmlData, function(err, data) {
            if(err) {
                console.warn('Error', err);
                deferred.reject(err);
            } else {
                deferred.resolve(data);
            }
        });
        return deferred.promise;
    }

    function stripOffBasePath(fileName) {
        var basePath = IOUtils.normalizeWindowsPath(_.last(opts.basePath.split(karmaConfig.basePath))).slice(1);
        return _.last(IOUtils.normalizeWindowsPath(fileName).split(basePath));
    }

    function getFileLineCoverage(coverageFile) {
        var deferred = Q.defer(),
            fileLineCoverage = {};

        try {
            IOUtils.readFileEventually(coverageFile, karmaConfig.waitForServerTime * 1000).done(function(xmlData) {
                parseCoverage(xmlData).done(function(coverageData) {
                    coverageData.coverage.packages.forEach(function(pkgs) {
                        pkgs['package'].forEach(function(pkg) {
                            pkg.classes.forEach(function(clss) {
                                clss['class'].forEach(function(cls) {
                                    var fileName = IOUtils.normalizeWindowsPath(cls.$['filename']),
                                        lineCoverage = Number(cls.$['line-rate']);
                                    fileLineCoverage[fileName] = lineCoverage;
                                });
                            });
                        });
                    });

                    deferred.resolve(fileLineCoverage);
                });
            });
        } catch(err) {
            console.warn("Error", err);
            deferred.reject(err);
        }

        return deferred.promise;
    }

    function findCodeSpecs() {
        var deferred = Q.defer(),
            codeSpecs = {};

        if(karmaConfig.fileSpecs) {
            if(_.isString(karmaConfig.fileSpecs)) {
                try {
                    karmaConfig.fileSpecs = JSON.parse(fs.readFileSync(karmaConfig.fileSpecs));
                } catch(error) {
                    deferred.reject(error);
                    return deferred.promise;
                }
            }

            // Create a mapping from source code to its specs, or to all specs when not explicitly provided
            _.forEach(opts.mutate, function(file) {
                file = IOUtils.normalizeWindowsPath(file);
                var mutateFileSpecs = _.find(karmaConfig.fileSpecs, function(fsSpecs, fsFile) {
                    return file.indexOf(IOUtils.normalizeWindowsPath(fsFile)) !== -1;
                });

                codeSpecs[file] = mutateFileSpecs || _.map(opts.specs, function(spec) {
                    return stripOffBasePath(spec);
                });
            });

            deferred.resolve(codeSpecs);
        } else {
            getCoverage().done(function(coverage) {
                baseCoverage = coverage;

                var specCoveragePromises = [];
                _.forEach(opts.specs, function(specFile) {
                    var deferred = Q.defer();

                    getCoverage(specFile).then(function(specCoverage) {
                        _.forOwn(specCoverage, function(coverage, file) {
                            var relativeFile = stripOffBasePath(file),
                                relativeSpecFile = stripOffBasePath(specFile);
                            if(coverage > baseCoverage[file]) {
                                if(codeSpecs[relativeFile]) {
                                    codeSpecs[relativeFile].push(relativeSpecFile);
                                } else {
                                    codeSpecs[relativeFile] = [relativeSpecFile];
                                }
                            }
                        });
                        deferred.resolve(specCoverage);
                    }, function(error) {
                        deferred.reject(error);
                    });

                    specCoveragePromises.push(deferred.promise);
                });

                Q.all(specCoveragePromises).then(function() {
                    deferred.resolve(codeSpecs);
                }, function(error) {
                    deferred.reject(error);
                });
            });
        }

        return deferred.promise;
    }

    opts.before = function(doneBefore) {
        karmaConfig = _.extend(
            {
                // defaults, but can be overwritten
                basePath: '.',
                reporters: [],
                logLevel: 'INFO'
            },
            opts.karma,
            {
                // can't be overwritten, because important for us
                configFile: opts.karma && opts.karma.configFile ? path.resolve(opts.karma.configFile) : undefined,
                background: false,
                singleRun: false,
                autoWatch: false,
                port: port
            }
        );

        function finalizeBefore(callback) {
            findCodeSpecs().then(function(codeSpecs) {
                grunt.log.writeln("Found pairs of code files and specs:\n", JSON.stringify(codeSpecs, null, 2));
                _.forEach(codeSpecs, function(specs, code) {
                    fileSpecs[code] = _.map(specs, function(spec) {
                        return path.join(opts.basePath, spec);
                    });
                });
                callback();
            });
        }

        if(!opts.mutateProductionCode) {
            CopyUtils.copyToTemp(opts.code.concat(opts.specs), 'mutation-testing').done(function(tempDirPath) {
                // Set the basePath relative to the temp dir
                karmaConfig.basePath = tempDirPath;
                opts.basePath = path.join(tempDirPath, opts.basePath);

                // Set the paths to the files to be mutated relative to the temp dir
                opts.mutate = _.map(opts.mutate, function(file) {
                    return path.join(tempDirPath, file);
                });

                finalizeBefore(doneBefore);
            });
        } else {
            finalizeBefore(doneBefore);
        }

        process.on('exit', function() {
            stopServers();
        });
    };

    opts.beforeEach = function(done) {
        var currentFileSpecs;

        // Find the specs for the current mutation file
        currentFileSpecs = _.find(fileSpecs, function(specs, file) {
            return opts.currentFile.replace(/\\/g, '/').indexOf(file) !== -1;
        });

        karmaConfig.files = opts.code.concat(currentFileSpecs || []);

        startServer(karmaConfig, function(instance) {
            opts.currentInstance = instance;
            done();
        });
    };

    opts.test = function(done) {
        opts.currentInstance.runTests().then(function(testSuccess) {
            done(testSuccess);
        }, function(error) {
            grunt.log.warn('\n' + error);
            startServer(karmaConfig, function(instance) {
                opts.currentInstance = instance;
                done(false);
            });
        });
    };

    opts.afterEach = function(done) {
        opts.currentInstance.kill();
        done();
    };

    opts.after = function() {
        stopServers();
    };
};
<|endoftext|>


<commit_before>import React from 'react';

import SPELLS from 'common/SPELLS';
import ITEMS from 'common/ITEMS';
import { formatPercentage } from 'common/format';
import { calculatePrimaryStat } from 'common/stats';
import ItemStatistic from 'interface/statistics/ItemStatistic';
import BoringItemValueText from 'interface/statistics/components/BoringItemValueText';
import STATISTIC_ORDER from 'interface/others/STATISTIC_ORDER';

import Analyzer from 'parser/core/Analyzer';
import Abilities from 'parser/core/modules/Abilities';

const BASE_ITEM_LEVEL = 300;
const BASE_AGILITY_BUFF = 593;

/**
 * Azerokk's Resonating Heart
 * Equip: Your attacks have a chance to harmonize with the shard, granting you X Agility for 15 sec.
 *
 * Test log: http://wowanalyzer.com/report/PcaGB6n41NDMrbmA/1-Mythic+Champion+of+the+Light+-+Kill+(1:37)/Baboune/statistics
 */
class AzerokksResonatingHeart extends Analyzer {
  static dependencies = {
    abilities: Abilities,
  };

  constructor(...args) {
    super(...args);
    this.active = this.selectedCombatant.hasTrinket(ITEMS.AZEROKKS_RESONATING_HEART.id);

    if(!this.active) {
      return;
    }

    this.procs = 0;

    const itemLevel = this.selectedCombatant.getItem(ITEMS.AZEROKKS_RESONATING_HEART.id).itemLevel;
    this.agilityBuff = calculatePrimaryStat(BASE_ITEM_LEVEL, BASE_AGILITY_BUFF, itemLevel);
  }

  on_byPlayer_applybuff(event) {
    this.handleBuff(event);
  }

  on_byPlayer_refreshbuff(event) {
    this.handleBuff(event);
  }

  handleBuff(event) {
    if(event.ability.guid !== SPELLS.BENEFICIAL_VIBRATIONS.id) {
      return;
    }

    this.procs++;
  }

  get uptime() {
    return this.selectedCombatant.getBuffUptime(SPELLS.BENEFICIAL_VIBRATIONS.id) / this.owner.fightDuration;
  }

  get averageAgility() {
    return (this.agilityBuff * this.uptime).toFixed(0);
  }

  statistic() {
    return (
      <ItemStatistic
        size="flexible"
        tooltip={<>You procced {SPELLS.BENEFICIAL_VIBRATIONS.name} {this.procs} times with an uptime of {formatPercentage(this.uptime)}%.</>}
      >
        <BoringItemValueText item={ITEMS.AZEROKKS_RESONATING_HEART}>
          {this.averageAgility} Avg. agility gained
        </BoringItemValueText>
      </ItemStatistic>
    );
  }
}

export default AzerokksResonatingHeart;
<commit_msg>Update AzerokksResonatingHeart.js<commit_after>import React from 'react';

import SPELLS from 'common/SPELLS';
import ITEMS from 'common/ITEMS';
import { formatPercentage } from 'common/format';
import { calculatePrimaryStat } from 'common/stats';
import ItemStatistic from 'interface/statistics/ItemStatistic';
import BoringItemValueText from 'interface/statistics/components/BoringItemValueText';

import Analyzer from 'parser/core/Analyzer';
import Abilities from 'parser/core/modules/Abilities';

const BASE_ITEM_LEVEL = 300;
const BASE_AGILITY_BUFF = 593;

/**
 * Azerokk's Resonating Heart
 * Equip: Your attacks have a chance to harmonize with the shard, granting you X Agility for 15 sec.
 *
 * Test log: http://wowanalyzer.com/report/PcaGB6n41NDMrbmA/1-Mythic+Champion+of+the+Light+-+Kill+(1:37)/Baboune/statistics
 */
class AzerokksResonatingHeart extends Analyzer {
  static dependencies = {
    abilities: Abilities,
  };

  constructor(...args) {
    super(...args);
    this.active = this.selectedCombatant.hasTrinket(ITEMS.AZEROKKS_RESONATING_HEART.id);

    if(!this.active) {
      return;
    }

    this.procs = 0;

    const itemLevel = this.selectedCombatant.getItem(ITEMS.AZEROKKS_RESONATING_HEART.id).itemLevel;
    this.agilityBuff = calculatePrimaryStat(BASE_ITEM_LEVEL, BASE_AGILITY_BUFF, itemLevel);
  }

  on_byPlayer_applybuff(event) {
    this.handleBuff(event);
  }

  on_byPlayer_refreshbuff(event) {
    this.handleBuff(event);
  }

  handleBuff(event) {
    if(event.ability.guid !== SPELLS.BENEFICIAL_VIBRATIONS.id) {
      return;
    }

    this.procs++;
  }

  get uptime() {
    return this.selectedCombatant.getBuffUptime(SPELLS.BENEFICIAL_VIBRATIONS.id) / this.owner.fightDuration;
  }

  get averageAgility() {
    return (this.agilityBuff * this.uptime).toFixed(0);
  }

  statistic() {
    return (
      <ItemStatistic
        size="flexible"
        tooltip={<>You procced {SPELLS.BENEFICIAL_VIBRATIONS.name} {this.procs} times with an uptime of {formatPercentage(this.uptime)}%.</>}
      >
        <BoringItemValueText item={ITEMS.AZEROKKS_RESONATING_HEART}>
          {this.averageAgility} Avg. agility gained
        </BoringItemValueText>
      </ItemStatistic>
    );
  }
}

export default AzerokksResonatingHeart;
<|endoftext|>