<commit_before>/*!
 * Bootstrap Customizer (http://getbootstrap.com/customize/)
 * Copyright 2011-2014 Twitter, Inc.
 *
 * Licensed under the Creative Commons Attribution 3.0 Unported License. For
 * details, see http://creativecommons.org/licenses/by/3.0/.
 */

/* global JSZip, less, saveAs, UglifyJS, __js, __less, __fonts */

window.onload = function () { // wait for load in a dumb way because B-0
  'use strict';
  var cw = '/*!\n' +
           ' * Bootstrap v3.2.0 (http://getbootstrap.com)\n' +
           ' * Copyright 2011-2014 Twitter, Inc.\n' +
           ' * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n' +
           ' */\n\n'

  function showError(msg, err) {
    $('
' +
        '
' +
          '×' +
          '
' + msg + '
' +
          (err.extract ? '
' + err.extract.join('\n') + '
' : '') +
        '
' +
      '
').appendTo('body').alert()
    throw err
  }

  function showSuccess(msg) {
    $('
' +
      '<button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>' + msg +
    '
').insertAfter('.bs-customize-download')
  }

  function showCallout(msg, showUpTop) {
    var callout = $('
' +
       '
Attention!
' +
      '
' + msg + '
' +
    '
')

    if (showUpTop) {
      callout.appendTo('.bs-docs-container')
    } else {
      callout.insertAfter('.bs-customize-download')
    }
  }

  function getQueryParam(key) {
    key = key.replace(/[*+?^$.\[\]{}()|\\\/]/g, '\\$&') // escape RegEx meta chars
    var match = location.search.match(new RegExp('[?&]' + key + '=([^&]+)(&|$)'))
    return match && decodeURIComponent(match[1].replace(/\+/g, ' '))
  }

  function getCustomizerData() {
    var data = {
      css: [],
      js: []
    }
    $('#less-section input:checked').each(function () {
    });

    if ($.isEmptyObject(data.vars) && !data.css.length && !data.js.length) return

    return data
  }

  function generateZip(css, js, fonts, config, complete) {
    if (!css && !js) return showError('Ruh roh! No Bootstrap files selected.', new Error('no Bootstrap'))

    var zip = new JSZip()

    if (css) {
      var cssFolder = zip.folder('css')
      for (var fileName in css) {
        cssFolder.file(fileName, css[fileName])
      }
    }

    if (js) {
      var jsFolder = zip.folder('js')
      for (var jsFileName in js) {
        jsFolder.file(jsFileName, js[jsFileName])
      }
    }

    if (fonts) {
      var fontsFolder = zip.folder('fonts')
      for (var fontsFileName in fonts) {
        fontsFolder.file(fontsFileName, fonts[fontsFileName], { base64: true })
      }
    }

    if (config) {
      zip.file('config.json', config)
    }

    var content = zip.generate({ type: 'blob' })

    complete(content)
  }

  function generateCustomLess(vars) {
    var result = ''

    for (var key in vars) {
      result += key + ': ' + vars[key] + ';\n'
    }

    return result + '\n\n'
  }

  function generateFonts() {
    var glyphicons = $('#less-section [value="glyphicons.less"]:checked')
    if (glyphicons.length) {
      return __fonts
    }
  }

  // Returns an Array of @import'd filenames in the order
  // in which they appear in the file.
  function includedLessFilenames(lessFilename) {
    var IMPORT_REGEX = /^@import [\"|\'](.*?)[\"|\'];/; //\\"
    var lessLines = __less[lessFilename].split('\n')

    var imports = []
    $.each(lessLines, function (index, lessLine) {
      var match = IMPORT_REGEX.exec(lessLine)
      if (match) {
        var importee = match[1]
        var transitiveImports = includedLessFilenames(importee)
        $.each(transitiveImports, function (index, transitiveImportee) {
          if ($.inArray(transitiveImportee, imports) === -1) {
            imports.push(transitiveImportee)
          }
        })
        imports.push(importee)
      }
    })

    return imports
  }

  function generateLESS(lessFilename, lessFileIncludes, vars) {
    var lessSource = __less[lessFilename]

    var lessFilenames = includedLessFilenames(lessFilename)
    $.each(lessFilenames, function (index, filename) {
      var fileInclude = lessFileIncludes[filename]

      // Files not explicitly unchecked are compiled into the final stylesheet.
      // Core stylesheets like 'normalize.less' are not included in the form
      // since disabling them would wreck everything, and so their 'fileInclude'
      // will be 'undefined'.
      if (fileInclude || (fileInclude == null))    lessSource += __less[filename]

      // Custom variables are added after Bootstrap variables so the custom
      // ones take precedence.
      if (('variables.less' === filename) && vars) lessSource += generateCustomLess(vars)
    })

    lessSource = lessSource.replace(/@import[^\n]*/gi, '') // strip any imports
    return lessSource
  }

  function compileLESS(lessSource, baseFilename, intoResult) {
    $(".console").text(lessSource)
    var parser = new less.Parser({
      paths: ['variables.less', 'mixins.less'],
      optimization: 0,
      filename: baseFilename + '.css'
    })

    parser.parse(lessSource, function (err, tree) {
      if (err) {
        return showError('Ruh roh! Could not parse less files.', err)
      }
      intoResult[baseFilename + '.css']     = cw + tree.toCSS()
      intoResult[baseFilename + '.min.css'] = cw + tree.toCSS({ compress: true })
    })
  }

  function generateCSS() {
    var oneChecked = false
    var lessFileIncludes = {}
    $('#less-section input').each(function () {
      var $this = $(this)
      var checked = $this.is(':checked')
      lessFileIncludes[$this.val()] = checked

      oneChecked = oneChecked || checked
    })

    if (!oneChecked) return false

    var result = {}
    var vars = {}

    $('#less-variables-section input')
      .each(function () {
        $(this).val() && (vars[$(this).prev().text()] = $(this).val())
      })

    var bsLessSource    = generateLESS('sui.less', lessFileIncludes, vars)
    //var themeLessSource = generateLESS('theme.less',     lessFileIncludes, vars)

    try {
      compileLESS(bsLessSource, 'sui', result)
      //compileLESS(themeLessSource, 'bootstrap-theme', result)
    } catch (err) {
      return showError('Ruh roh! Could not parse less files.', err)
    }

    return result
  }

  function uglify(js) {
    var ast = UglifyJS.parse(js)
    ast.figure_out_scope()

    var compressor = UglifyJS.Compressor()
    var compressedAst = ast.transform(compressor)

    compressedAst.figure_out_scope()
    compressedAst.compute_char_frequency()
    compressedAst.mangle_names()

    var stream = UglifyJS.OutputStream()
    compressedAst.print(stream)

    return stream.toString()
  }

  function generateJS() {
    var $checked = $('#plugin-section input:checked')
    var jqueryCheck = 'if (typeof jQuery === "undefined") { throw new Error("Bootstrap\'s JavaScript requires jQuery") }\n\n'

    if (!$checked.length) return false

    var js = $checked
      .map(function () { return __js[this.value] })
      .toArray()
      .join('\n')

    js = jqueryCheck + js

    return {
      'bootstrap.js': js,
      'bootstrap.min.js': uglify(js)
    }
  }

  var inputsComponent = $('#less-section input')
  var inputsPlugin    = $('#plugin-section input')
  var inputsVariables = $('#less-variables-section input')

  $('#less-section .toggle').on('click', function (e) {
    e.preventDefault()
    inputsComponent.prop('checked', !inputsComponent.is(':checked'))
  })

  $('#plugin-section .toggle').on('click', function (e) {
    e.preventDefault()
    inputsPlugin.prop('checked', !inputsPlugin.is(':checked'))
  })

  $('#less-variables-section .toggle').on('click', function (e) {
    e.preventDefault()
    inputsVariables.val('')
  })

  $('[data-dependencies]').on('click', function () {
    if (!$(this).is(':checked')) return
    var dependencies = this.getAttribute('data-dependencies')
    if (!dependencies) return
    dependencies = dependencies.split(',')
    for (var i = 0; i < dependencies.length; i++) {
      var dependency = $('[value="' + dependencies[i] + '"]')
      dependency && dependency.prop('checked', true)
    }
  })

  $('[data-dependents]').on('click', function () {
    if ($(this).is(':checked')) return
    var dependents = this.getAttribute('data-dependents')
    if (!dependents) return
    dependents = dependents.split(',')
    for (var i = 0; i < dependents.length; i++) {
      var dependent = $('[value="' + dependents[i] + '"]')
      dependent && dependent.prop('checked', false)
    }
  })

  var $compileBtn = $('#customize-download')

  $compileBtn.on('click', function (e) {
    var configData = getCustomizerData()
    var configJson = JSON.stringify(configData, null, 2)

    e.preventDefault()

    $compileBtn.attr('disabled', 'disabled')

    generateZip(generateCSS(), generateJS(), generateFonts(), configJson, function (blob) {
      $compileBtn.removeAttr('disabled')
      saveAs(blob, 'bootstrap.zip')
    })
  });

  // browser support alert
  (function () {
    function failback() {
      $('.bs-docs-section, .bs-docs-sidebar').css('display', 'none')
      showCallout('Looks like your current browser doesn\'t support the Bootstrap Customizer. Please take a second ' +
                    'to upgrade to a more modern browser (other than Safari).', true)
    }
    /**
     * Based on:
     *   Blob Feature Check v1.1.0
     *   https://github.com/ssorallen/blob-feature-check/
     *   License: Public domain (http://unlicense.org)
     */
    var url = window.webkitURL || window.URL // Safari 6 uses "webkitURL".
    var svg = new Blob(
      ['<svg xmlns=\'http://www.w3.org/2000/svg\'></svg>'],
      { type: 'image/svg+xml;charset=utf-8' }
    )
    var objectUrl = url.createObjectURL(svg);
    if (/^blob:/.exec(objectUrl) === null) {
      // `URL.createObjectURL` created a URL that started with something other
      // than "blob:", which means it has been polyfilled and is not supported by
      // this browser.
      failback()
    } else {
      $('')
        .on('load', function () {
          $compileBtn.prop('disabled', false)
        })
        .on('error', failback)
        .attr('src', objectUrl)
    }
  })();

}
<commit_msg>update<commit_after>/*!
 * Bootstrap Customizer (http://getbootstrap.com/customize/)
 * Copyright 2011-2014 Twitter, Inc.
 *
 * Licensed under the Creative Commons Attribution 3.0 Unported License. For
 * details, see http://creativecommons.org/licenses/by/3.0/.
 */

/* global JSZip, less, saveAs, UglifyJS, __js, __less, __fonts */

window.onload = function () { // wait for load in a dumb way because B-0
  'use strict';
  var cw = '/*!\n' +
           ' * Bootstrap v3.2.0 (http://getbootstrap.com)\n' +
           ' * Copyright 2011-2014 Twitter, Inc.\n' +
           ' * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n' +
           ' */\n\n'

  function showError(msg, err) {
    $('
' +
        '
' +
          '×' +
          '
' + msg + '
' +
          (err.extract ? '
' + err.extract.join('\n') + '
' : '') +
        '
' +
      '
').appendTo('body').alert()
    throw err
  }

  function showSuccess(msg) {
    $('
' +
      '<button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>' + msg +
    '
').insertAfter('.bs-customize-download')
  }

  function showCallout(msg, showUpTop) {
    var callout = $('
' +
       '
Attention!
' +
      '
' + msg + '
' +
    '
')

    if (showUpTop) {
      callout.appendTo('.bs-docs-container')
    } else {
      callout.insertAfter('.bs-customize-download')
    }
  }

  function getQueryParam(key) {
    key = key.replace(/[*+?^$.\[\]{}()|\\\/]/g, '\\$&') // escape RegEx meta chars
    var match = location.search.match(new RegExp('[?&]' + key + '=([^&]+)(&|$)'))
    return match && decodeURIComponent(match[1].replace(/\+/g, ' '))
  }

  function getCustomizerData() {
    var data = {
      css: [],
      js: []
    }
    var put = function(v) {
    }
    $('#less-section input:checked').each(function () {
      var value = this.value, css = data.css;
      if(/,/.test(value)) {
        value.split(",").forEach(put);
      } else {
        put(value)
      }
    });

    if ($.isEmptyObject(data.vars) && !data.css.length && !data.js.length) return

    return data
  }

  function generateZip(css, js, fonts, config, complete) {
    if (!css && !js) return showError('Ruh roh! No Bootstrap files selected.', new Error('no Bootstrap'))

    var zip = new JSZip()

    if (css) {
      var cssFolder = zip.folder('css')
      for (var fileName in css) {
        cssFolder.file(fileName, css[fileName])
      }
    }

    if (js) {
      var jsFolder = zip.folder('js')
      for (var jsFileName in js) {
        jsFolder.file(jsFileName, js[jsFileName])
      }
    }

    if (fonts) {
      var fontsFolder = zip.folder('fonts')
      for (var fontsFileName in fonts) {
        fontsFolder.file(fontsFileName, fonts[fontsFileName], { base64: true })
      }
    }

    if (config) {
      zip.file('config.json', config)
    }

    var content = zip.generate({ type: 'blob' })

    complete(content)
  }

  function generateCustomLess(vars) {
    var result = ''

    for (var key in vars) {
      result += key + ': ' + vars[key] + ';\n'
    }

    return result + '\n\n'
  }

  function generateFonts() {
    var glyphicons = $('#less-section [value="glyphicons.less"]:checked')
    if (glyphicons.length) {
      return __fonts
    }
  }

  // Returns an Array of @import'd filenames in the order
  // in which they appear in the file.
  function includedLessFilenames(lessFilename) {
    var IMPORT_REGEX = /^@import [\"|\'](.*?)[\"|\'];/; //\\"
    var lessLines = __less[lessFilename].split('\n')

    var imports = []
    $.each(lessLines, function (index, lessLine) {
      var match = IMPORT_REGEX.exec(lessLine)
      if (match) {
        var importee = match[1]
        var transitiveImports = includedLessFilenames(importee)
        $.each(transitiveImports, function (index, transitiveImportee) {
          if ($.inArray(transitiveImportee, imports) === -1) {
            imports.push(transitiveImportee)
          }
        })
        imports.push(importee)
      }
    })

    return imports
  }

  function generateLESS(lessFilename, lessFileIncludes, vars) {
    var lessSource = __less[lessFilename]

    var lessFilenames = includedLessFilenames(lessFilename)
    $.each(lessFilenames, function (index, filename) {
      var fileInclude = lessFileIncludes[filename]

      // Files not explicitly unchecked are compiled into the final stylesheet.
      // Core stylesheets like 'normalize.less' are not included in the form
      // since disabling them would wreck everything, and so their 'fileInclude'
      // will be 'undefined'.
      if (fileInclude || (fileInclude == null))    lessSource += __less[filename]

      // Custom variables are added after Bootstrap variables so the custom
      // ones take precedence.
      if (('variables.less' === filename) && vars) lessSource += generateCustomLess(vars)
    })

    lessSource = lessSource.replace(/@import[^\n]*/gi, '') // strip any imports
    return lessSource
  }

  function compileLESS(lessSource, baseFilename, intoResult) {
    $(".console").text(lessSource)
    var parser = new less.Parser({
      paths: ['variables.less', 'mixins.less'],
      optimization: 0,
      filename: baseFilename + '.css'
    })

    parser.parse(lessSource, function (err, tree) {
      if (err) {
        return showError('Ruh roh! Could not parse less files.', err)
      }
      intoResult[baseFilename + '.css']     = cw + tree.toCSS()
      intoResult[baseFilename + '.min.css'] = cw + tree.toCSS({ compress: true })
    })
  }

  function generateCSS() {
    var oneChecked = false
    var lessFileIncludes = {}
    $('#less-section input').each(function () {
      var $this = $(this)
      var checked = $this.is(':checked')
      lessFileIncludes[$this.val()] = checked

      oneChecked = oneChecked || checked
    })

    if (!oneChecked) return false

    var result = {}
    var vars = {}

    $('#less-variables-section input')
      .each(function () {
        $(this).val() && (vars[$(this).prev().text()] = $(this).val())
      })

    var bsLessSource    = generateLESS('sui.less', lessFileIncludes, vars)
    //var themeLessSource = generateLESS('theme.less',     lessFileIncludes, vars)

    try {
      compileLESS(bsLessSource, 'sui', result)
      //compileLESS(themeLessSource, 'bootstrap-theme', result)
    } catch (err) {
      return showError('Ruh roh! Could not parse less files.', err)
    }

    return result
  }

  function uglify(js) {
    var ast = UglifyJS.parse(js)
    ast.figure_out_scope()

    var compressor = UglifyJS.Compressor()
    var compressedAst = ast.transform(compressor)

    compressedAst.figure_out_scope()
    compressedAst.compute_char_frequency()
    compressedAst.mangle_names()

    var stream = UglifyJS.OutputStream()
    compressedAst.print(stream)

    return stream.toString()
  }

  function generateJS() {
    var $checked = $('#plugin-section input:checked')
    var jqueryCheck = 'if (typeof jQuery === "undefined") { throw new Error("Bootstrap\'s JavaScript requires jQuery") }\n\n'

    if (!$checked.length) return false

    var js = $checked
      .map(function () { return __js[this.value] })
      .toArray()
      .join('\n')

    js = jqueryCheck + js

    return {
      'bootstrap.js': js,
      'bootstrap.min.js': uglify(js)
    }
  }

  var inputsComponent = $('#less-section input')
  var inputsPlugin    = $('#plugin-section input')
  var inputsVariables = $('#less-variables-section input')

  $('#less-section .toggle').on('click', function (e) {
    e.preventDefault()
    inputsComponent.prop('checked', !inputsComponent.is(':checked'))
  })

  $('#plugin-section .toggle').on('click', function (e) {
    e.preventDefault()
    inputsPlugin.prop('checked', !inputsPlugin.is(':checked'))
  })

  $('#less-variables-section .toggle').on('click', function (e) {
    e.preventDefault()
    inputsVariables.val('')
  })

  $('[data-dependencies]').on('click', function () {
    if (!$(this).is(':checked')) return
    var dependencies = this.getAttribute('data-dependencies')
    if (!dependencies) return
    dependencies = dependencies.split(',')
    for (var i = 0; i < dependencies.length; i++) {
      var dependency = $('[value="' + dependencies[i] + '"]')
      dependency && dependency.prop('checked', true)
    }
  })

  $('[data-dependents]').on('click', function () {
    if ($(this).is(':checked')) return
    var dependents = this.getAttribute('data-dependents')
    if (!dependents) return
    dependents = dependents.split(',')
    for (var i = 0; i < dependents.length; i++) {
      var dependent = $('[value="' + dependents[i] + '"]')
      dependent && dependent.prop('checked', false)
    }
  })

  var $compileBtn = $('#customize-download')

  $compileBtn.on('click', function (e) {
    var configData = getCustomizerData()
    var configJson = JSON.stringify(configData, null, 2)

    e.preventDefault()

    $compileBtn.attr('disabled', 'disabled')

    generateZip(generateCSS(), generateJS(), generateFonts(), configJson, function (blob) {
      $compileBtn.removeAttr('disabled')
      saveAs(blob, 'bootstrap.zip')
    })
  });

  // browser support alert
  (function () {
    function failback() {
      $('.bs-docs-section, .bs-docs-sidebar').css('display', 'none')
      showCallout('Looks like your current browser doesn\'t support the Bootstrap Customizer. Please take a second ' +
                    'to upgrade to a more modern browser (other than Safari).', true)
    }
    /**
     * Based on:
     *   Blob Feature Check v1.1.0
     *   https://github.com/ssorallen/blob-feature-check/
     *   License: Public domain (http://unlicense.org)
     */
    var url = window.webkitURL || window.URL // Safari 6 uses "webkitURL".
    var svg = new Blob(
      ['<svg xmlns=\'http://www.w3.org/2000/svg\'></svg>'],
      { type: 'image/svg+xml;charset=utf-8' }
    )
    var objectUrl = url.createObjectURL(svg);
    if (/^blob:/.exec(objectUrl) === null) {
      // `URL.createObjectURL` created a URL that started with something other
      // than "blob:", which means it has been polyfilled and is not supported by
      // this browser.
      failback()
    } else {
      $('')
        .on('load', function () {
          $compileBtn.prop('disabled', false)
        })
        .on('error', failback)
        .attr('src', objectUrl)
    }
  })();

}
<|endoftext|>


<commit_before>const validSqlRegex = /^[a-z0-9_]+$/,
      entypeRegex = /^[a-z0-9_]{1,20}$/,
      evnameRegex = /^(@set|[a-z0-9_]{1,40})$/,
      isoRegex = /(\d{4})-(\d{2})-(\d{2})T((\d{2}):(\d{2}):(\d{2}))\.(\d{3})Z/,
      reservedWords = new Set(require('./reserved-words'))

function validateEvent(opts, event) {
  var errors = []

  if (event[event.entype === 'user' ? 'user_id' : 'enid'] == null) {
    errors.push('you must specify user_id if entype is `user`, otherwise you must specify the `enid`')
  }
  if (event.user_id != null && (typeof event.user_id !== 'string' || event.user_id.length > 40 || !event.user_id.length)) {
    errors.push('user_id must be a string less than 40 characters long')
  }
  if (!entypeRegex.test(event.entype)) {
    errors.push('entype does not match ' + entypeRegex.toString())
  }
  if (!evnameRegex.test(event.evname)) {
    errors.push('evname does not match ' + evnameRegex.toString())
  }
  if (event.ts != null && !isoRegex.test(event.ts)) {
    errors.push('ts is not a valid ISO timestamp')
  }
  if (event.body != null) {
    if (typeof event.body !== 'object') {
      errors.push('body must be an object')
    } else {
      for (var k in event.body) {
        if (!validSqlRegex.test(k)) {
          errors.push(`Body key ${k} does not match ${validSqlRegex.toString()}`)
        }
        if (reservedWords.has(k.toUpperCase())) {
          if (opts.transformReservedWordKeys) {
            event.body[k + '_'] = event.body[k]
            delete event.body[k]
          } else {
            errors.push(`Body key ${k} is a reserved SQL keyword`)
          }
        }
      }
    }
  }

  return errors
}

module.exports = validateEvent.bind(null, {})

// Convience method if you just need a yes or no answer
module.exports.isValid = e => !validateEvent({}, e).length

// Create a validator with transformation options
module.exports.withOptions = opts => validateEvent.bind(null, opts)

// Validate the events overall length. This is a separate method as it is expensive,
// and often can be avoided when parsing and building the event from a CSV by pre-checking the line length
module.exports.hasValidLength = e => !e.body || JSON.stringify(e.body).length < 32768<commit_msg>check enid length is less than 40<commit_after>const validSqlRegex = /^[a-z0-9_]+$/,
      entypeRegex = /^[a-z0-9_]{1,20}$/,
      evnameRegex = /^(@set|[a-z0-9_]{1,40})$/,
      isoRegex = /(\d{4})-(\d{2})-(\d{2})T((\d{2}):(\d{2}):(\d{2}))\.(\d{3})Z/,
      reservedWords = new Set(require('./reserved-words'))

function validateEvent(opts, event) {
  var errors = []

  if (event[event.entype === 'user' ? 'user_id' : 'enid'] == null) {
    errors.push('you must specify user_id if entype is `user`, otherwise you must specify the `enid`')
  }
  if (event.user_id != null && (typeof event.user_id !== 'string' || event.user_id.length > 40 || !event.user_id.length)) {
    errors.push('user_id must be a string less than 40 characters long')
  }
  if (event.enid != null && (typeof event.enid !== 'string' || event.enid.length > 40 || !event.enid.length)) {
    errors.push('enid must be a string less than 40 characters long')
  }
  if (!entypeRegex.test(event.entype)) {
    errors.push('entype does not match ' + entypeRegex.toString())
  }
  if (!evnameRegex.test(event.evname)) {
    errors.push('evname does not match ' + evnameRegex.toString())
  }
  if (event.ts != null && !isoRegex.test(event.ts)) {
    errors.push('ts is not a valid ISO timestamp')
  }
  if (event.body != null) {
    if (typeof event.body !== 'object') {
      errors.push('body must be an object')
    } else {
      for (var k in event.body) {
        if (!validSqlRegex.test(k)) {
          errors.push(`Body key ${k} does not match ${validSqlRegex.toString()}`)
        }
        if (reservedWords.has(k.toUpperCase())) {
          if (opts.transformReservedWordKeys) {
            event.body[k + '_'] = event.body[k]
            delete event.body[k]
          } else {
            errors.push(`Body key ${k} is a reserved SQL keyword`)
          }
        }
      }
    }
  }

  return errors
}

module.exports = validateEvent.bind(null, {})

// Convience method if you just need a yes or no answer
module.exports.isValid = e => !validateEvent({}, e).length

// Create a validator with transformation options
module.exports.withOptions = opts => validateEvent.bind(null, opts)

// Validate the events overall length. This is a separate method as it is expensive,
// and often can be avoided when parsing and building the event from a CSV by pre-checking the line length
module.exports.hasValidLength = e => !e.body || JSON.stringify(e.body).length < 32768
<|endoftext|>


<commit_before>/**
 * html替换
 * @param text
 */
function htmlEscape(text){
    return text.replace(/[<>&/g,function(match,pos,originalText){
        switch (match){
            case "<":
                return "<";
        }
    })
}<commit_msg>5.6.3<commit_after>/**
 * html替换
 * @param text
 */
function htmlEscape(text){
    return text.replace(/[<>&/g,function(match,pos,originalText){
        switch (match){
            case "<":
                return "<";
            case ">":
                return ">";
        }
    })
}<|endoftext|>


<commit_before>'use strict';

/*
* When adding modules to the namespace, ensure that they are added in alphabetical order according to module name.
*/

// MODULES //

var setReadOnly = require( '@stdlib/utils/define-read-only-property' );

// MAIN //

/**
* Top-level namespace.
*
* @namespace beta
*/
var beta = {};

/**
* @name cdf
* @memberof beta
* @readonly
* @type {Function}
* @see {@link module:@stdlib/math/base/dist/beta/cdf}
*/
setReadOnly( beta, 'cdf', require( '@stdlib/math/base/dist/beta/cdf' ) );

/**
* @name entropy
* @memberof beta
* @readonly
* @type {Function}
* @see {@link module:@stdlib/math/base/dist/beta/entropy}
*/
setReadOnly( beta, 'entropy', require( '@stdlib/math/base/dist/beta/entropy' ) );

/**
* @name kurtosis
* @memberof beta
* @readonly
* @type {Function}
* @see {@link module:@stdlib/math/base/dist/beta/kurtosis}
*/
setReadOnly( beta, 'kurtosis', require( '@stdlib/math/base/dist/beta/kurtosis' ) );

/**
* @name logpdf
* @memberof beta
* @readonly
* @type {Function}
* @see {@link module:@stdlib/math/base/dist/beta/logpdf}
*/
setReadOnly( beta, 'logpdf', require( '@stdlib/math/base/dist/beta/logpdf' ) );

/**
* @name mean
* @memberof beta
* @readonly
* @type {Function}
* @see {@link module:@stdlib/math/base/dist/beta/mean}
*/
setReadOnly( beta, 'mean', require( '@stdlib/math/base/dist/beta/mean' ) );

/**
* @name median
* @memberof beta
* @readonly
* @type {Function}
* @see {@link module:@stdlib/math/base/dist/beta/median}
*/
setReadOnly( beta, 'median', require( '@stdlib/math/base/dist/beta/median' ) );

/**
* @name mgf
* @memberof beta
* @readonly
* @type {Function}
* @see {@link module:@stdlib/math/base/dist/beta/mgf}
*/
setReadOnly( beta, 'mgf', require( '@stdlib/math/base/dist/beta/mgf' ) );

/**
* @name mode
* @memberof beta
* @readonly
* @type {Function}
* @see {@link module:@stdlib/math/base/dist/beta/mode}
*/
setReadOnly( beta, 'mode', require( '@stdlib/math/base/dist/beta/mode' ) );

/**
* @name pdf
* @memberof beta
* @readonly
* @type {Function}
* @see {@link module:@stdlib/math/base/dist/beta/pdf}
*/
setReadOnly( beta, 'pdf', require( '@stdlib/math/base/dist/beta/pdf' ) );

/**
* @name quantile
* @memberof beta
* @readonly
* @type {Function}
* @see {@link module:@stdlib/math/base/dist/beta/quantile}
*/
setReadOnly( beta, 'quantile', require( '@stdlib/math/base/dist/beta/quantile' ) );

/**
* @name skewness
* @memberof beta
* @readonly
* @type {Function}
* @see {@link module:@stdlib/math/base/dist/beta/skewness}
*/
setReadOnly( beta, 'skewness', require( '@stdlib/math/base/dist/beta/skewness' ) );

/**
* @name variance
* @memberof beta
* @readonly
* @type {Function}
* @see {@link module:@stdlib/math/base/dist/beta/variance}
*/
setReadOnly( beta, 'variance', require( '@stdlib/math/base/dist/beta/variance' ) );

// EXPORTS //

module.exports = beta;
<commit_msg>Export constructor to namespace<commit_after>'use strict';

/*
* When adding modules to the namespace, ensure that they are added in alphabetical order according to module name.
*/

// MODULES //

var setReadOnly = require( '@stdlib/utils/define-read-only-property' );

// MAIN //

/**
* Top-level namespace.
*
* @namespace beta
*/
var beta = {};

/**
* @name Beta
* @memberof beta
* @readonly
* @type {Function}
* @see {@link module:@stdlib/math/base/dist/beta/ctor}
*/
setReadOnly( beta, 'Beta', require( '@stdlib/math/base/dist/beta/ctor' ) );

/**
* @name cdf
* @memberof beta
* @readonly
* @type {Function}
* @see {@link module:@stdlib/math/base/dist/beta/cdf}
*/
setReadOnly( beta, 'cdf', require( '@stdlib/math/base/dist/beta/cdf' ) );

/**
* @name entropy
* @memberof beta
* @readonly
* @type {Function}
* @see {@link module:@stdlib/math/base/dist/beta/entropy}
*/
setReadOnly( beta, 'entropy', require( '@stdlib/math/base/dist/beta/entropy' ) );

/**
* @name kurtosis
* @memberof beta
* @readonly
* @type {Function}
* @see {@link module:@stdlib/math/base/dist/beta/kurtosis}
*/
setReadOnly( beta, 'kurtosis', require( '@stdlib/math/base/dist/beta/kurtosis' ) );

/**
* @name logpdf
* @memberof beta
* @readonly
* @type {Function}
* @see {@link module:@stdlib/math/base/dist/beta/logpdf}
*/
setReadOnly( beta, 'logpdf', require( '@stdlib/math/base/dist/beta/logpdf' ) );

/**
* @name mean
* @memberof beta
* @readonly
* @type {Function}
* @see {@link module:@stdlib/math/base/dist/beta/mean}
*/
setReadOnly( beta, 'mean', require( '@stdlib/math/base/dist/beta/mean' ) );

/**
* @name median
* @memberof beta
* @readonly
* @type {Function}
* @see {@link module:@stdlib/math/base/dist/beta/median}
*/
setReadOnly( beta, 'median', require( '@stdlib/math/base/dist/beta/median' ) );

/**
* @name mgf
* @memberof beta
* @readonly
* @type {Function}
* @see {@link module:@stdlib/math/base/dist/beta/mgf}
*/
setReadOnly( beta, 'mgf', require( '@stdlib/math/base/dist/beta/mgf' ) );

/**
* @name mode
* @memberof beta
* @readonly
* @type {Function}
* @see {@link module:@stdlib/math/base/dist/beta/mode}
*/
setReadOnly( beta, 'mode', require( '@stdlib/math/base/dist/beta/mode' ) );

/**
* @name pdf
* @memberof beta
* @readonly
* @type {Function}
* @see {@link module:@stdlib/math/base/dist/beta/pdf}
*/
setReadOnly( beta, 'pdf', require( '@stdlib/math/base/dist/beta/pdf' ) );

/**
* @name quantile
* @memberof beta
* @readonly
* @type {Function}
* @see {@link module:@stdlib/math/base/dist/beta/quantile}
*/
setReadOnly( beta, 'quantile', require( '@stdlib/math/base/dist/beta/quantile' ) );

/**
* @name skewness
* @memberof beta
* @readonly
* @type {Function}
* @see {@link module:@stdlib/math/base/dist/beta/skewness}
*/
setReadOnly( beta, 'skewness', require( '@stdlib/math/base/dist/beta/skewness' ) );

/**
* @name variance
* @memberof beta
* @readonly
* @type {Function}
* @see {@link module:@stdlib/math/base/dist/beta/variance}
*/
setReadOnly( beta, 'variance', require( '@stdlib/math/base/dist/beta/variance' ) );

// EXPORTS //

module.exports = beta;
<|endoftext|>


<commit_before>import React from 'react';
import _ from 'lodash';
import {
  XAxis,
  YAxis,
  FlexibleWidthXYPlot,
  VerticalGridLines,
  HorizontalGridLines,
  LineSeries,
  AreaSeries,
  DiscreteColorLegend,
  Crosshair,
} from 'react-vis';
import {Segment} from 'semantic-ui-react';

import {truncateString, displayValue} from '../../util/runhelpers.js';
import {smartNames} from '../../util/plotHelpers.js';
import {format} from 'd3-format';
import Highlight from './highlight.js';
import {Button, Container} from 'semantic-ui-react';

class LinePlotPlot extends React.PureComponent {
  // Implements the actual plot and data as a PureComponent, so that we don't
  // re-render every time the crosshair (highlight) changes.
  state = {
    lastDrawLocation: null,
  };

  render() {
    const smallSizeThresh = 50;
    const {lastDrawLocation} = this.state;
    let {height, xAxis, yScale, lines, disabled, xScale, yAxis} = this.props;
    let xType = 'linear';
    if (xAxis == 'Absolute Time') {
      xType = 'time';
    } else if (xScale == 'log') {
      // this is not actually implemented
      xType = 'log';
    }

    if (!yAxis) {
      yAxis = '';
    }

    let nullGraph = false;
    let smallGraph = false;

    let maxDataLength = _.max(
      lines.filter(line => line.data.length).map((line, i) => line.data.length)
    );

    if (!maxDataLength) {
      nullGraph = true;
    } else if (
      maxDataLength < smallSizeThresh &&
      lines &&
      _.max(
        lines.map(
          (line, i) =>
            line ? _.max(line.data.map((points, i) => points.x)) : 0
        )
      ) < smallSizeThresh
    ) {
      if (maxDataLength < 2) {
        nullGraph = true;
      } else {
        smallGraph = true;
      }
    }

    return (
      // SML: I turned off animation, it was making stuff uncomfortably slow even
      // with the smallGraph detection.
      <FlexibleWidthXYPlot
        animation={false}
        yType={yScale}
        xType={xType}
        height={height}>
        <XAxis
          title={truncateString(xAxis)}
          tickTotal={5}
          tickValues={smallGraph ? _.range(1, smallSizeThresh) : null}
          tickFormat={xType != 'time' ? tick => format('.2s')(tick) : null}
          style={{
            line: {stroke: '999'},
            ticks: {stroke: '999'},
            text: {stroke: 'none', fill: 'aaa', fontWeight: 600},
          }}
        />
        <YAxis
          title={truncateString(yAxis)}
          tickValues={null}
          tickFormat={tick => format('.2r')(tick)}
          style={{
            line: {stroke: '999'},
            ticks: {stroke: '999'},
            text: {stroke: 'none', fill: 'aaa', fontWeight: 600},
          }}
        />
        {lines
          .map(
            (line, i) =>
              !disabled[line.title] ? (
                line.area ? (
                  <AreaSeries
                    key={i}
                    color={line.color}
                    data={line.data}
                    getNull={d => d.y !== null}
                    stroke={'#0000'}
                  />
                ) : (
                  <LineSeries
                    key={i}
                    color={line.color}
                    data={line.data}
                    nullAccessor={d => d.y !== null}
                    strokeDasharray={
                      line.mark === 'dashed'
                        ? '4,2'
                        : line.mark === 'dotted' ? '1,1' : undefined
                    }
                    strokeStyle={'solid'}
                  />
                )
              ) : null
          )
          .filter(o => o)
          .reverse() // revese so the top line is the first line
        }
        <Highlight
          onBrushEnd={area => {
            this.setState({
              lastDrawLocation: area,
            });
          }}
        />
      </FlexibleWidthXYPlot>
    );
  }
}

class LinePlotCrosshair extends React.PureComponent {
  // This doesn't contain the data, just the react-vis crosshair (the hover popup
  // that shows y-values at the current x-value).

  _setup(props) {
    // highlights is a map from x-value to list of y-information for each line at
    // that x-value
    this.highlights = {};

    let enabledLines = props.lines.filter(
      line => !props.disabled[line.title] && line.data.length > 0 && !line.aux
    );

    let longestLine = _.max(enabledLines.map(line => line.data.length));

    if (longestLine > 200) {
      // we're going to average points
      let maxX = _.max(
        enabledLines.map(line => {
          return line.data[line.data.length - 1].x;
        })
      );
      let minX = _.min(enabledLines.map(line => line.data[0].x));
      let steps = 50;
      let step = (maxX - minX) / 50;
      // we're gonna make an index for each line since they're sorted
      // and increment them until the x value is higher than our current slice
      let embededLinesIdx = enabledLines.map(line => 0);

      for (let i = 0; i < steps; i++) {
        let minSlice = i * step + minX;
        let maxSlice = (i + 1) * step + minX;
        let avgSlice = (i + 0.5) * step + minX;
        this.highlights[avgSlice] = [];

        for (let j = 0; j < embededLinesIdx.length; j++) {
          let data = [];
          let line = enabledLines[j];
          while (
            line.data[embededLinesIdx[j]] &&
            line.data[embededLinesIdx[j]].x < maxSlice
          ) {
            data.push(enabledLines[j].data[embededLinesIdx[j]].y);
            embededLinesIdx[j]++;
          }
          if (data.length > 0) {
            this.highlights[avgSlice].push({
              title: line.title.toString ? line.title.toString() : line.title,
              color: line.color,
              x: avgSlice,
              y: _.mean(data),
              mark: line.mark,
            });
          }
        }
      }
    } else {
      // we're going to calculate every point exactly
      for (var line of enabledLines) {
        for (var point of line.data) {
          if (_.isNil(this.highlights[point.x])) {
            this.highlights[point.x] = [];
          }
          this.highlights[point.x].push({
            title: line.title.toString ? line.title.toString() : line.title,
            color: line.color,
            x: point.x,
            y: point.y,
            mark: line.mark,
          });
        }
      }
    }

    // False line is a straight line that fits within the chart data. We render
    // it transparently and just use it for it's onNearestX callback.
    this.falseLine = [];
    if (enabledLines.length > 0) {
      let y = enabledLines[0].data[0].y;
      let xs = _.keys(this.highlights).map(k => Number(k));
      this.falseLine = xs.map(x => ({x: x, y: y}));
    }
  }

  componentWillMount() {
    this._setup(this.props);
  }

  componentWillReceiveProps(nextProps) {
    if (
      this.props.lines !== nextProps.lines ||
      this.props.disabled !== nextProps.disabled
    ) {
      this._setup(nextProps);
    }
  }

  render() {
    let {height, xAxis, highlightX, onMouseLeave, onHighlight} = this.props;
    let crosshairValues = null;
    if (highlightX && this.highlights[highlightX]) {
      crosshairValues = this.highlights[highlightX];
    }
    return (
      <FlexibleWidthXYPlot onMouseLeave={() => onMouseLeave()} height={height}>
        <LineSeries
          onNearestX={item => onHighlight(item.x)}
          color="black"
          opacity={0}
          data={this.falseLine}
        />
        {crosshairValues &&
          crosshairValues.length > 0 && (
            <Crosshair values={crosshairValues}>

                  {this.props.xAxis + ': ' + displayValue(crosshairValues[0].x)}

                {crosshairValues.sort((a, b) => b.y - a.y).map((point, i) => (

                        {point.mark === 'dashed'
                          ? '┅'
                          : point.mark === 'dotted' ? '┉' : '━'}
                      {' '}

                        {point.title + ': ' + displayValue(point.y)}

                ))}

            </Crosshair>
          )}
      </FlexibleWidthXYPlot>
    );
  }
}

export default class LinePlot extends React.PureComponent {
  state = {disabled: {}, highlightX: null};

  render() {
    let filteredLines = this.props.lines.filter(line => !line.aux);
    let lines = [];
    lines = filteredLines;
    return (
      <Segment attached="bottom" basic>

            {lines.map((line, i) => (
               {
                  this.setState({
                    ...this.state,
                    disabled: {
                      ...this.state.disabled,
                      [item.title]: !this.state.disabled[item.title],
                    },
                  });
                }}>

                    {line.mark === 'dashed'
                      ? '┅'
                      : line.mark === 'dotted' ? '┉' : '━'}

                {' '}

                  {line.title.toComponent
                    ? line.title.toComponent()
                    : line.title}

            ))}

          <LinePlotPlot
            height={this.props.currentHeight - 70 || 220}
            xAxis={this.props.xAxis}
            yAxis={this.props.yAxis}
            yScale={this.props.yScale}
            lines={this.props.lines}
            disabled={this.state.disabled}
          />

            <LinePlotCrosshair
              height={this.props.currentHeight - 70 || 220}
              xAxis={this.props.xAxis}
              lines={this.props.lines}
              disabled={this.state.disabled}
              highlightX={this.state.highlightX}
              onMouseLeave={() => this.setState({highlightX: null})}
              onHighlight={xValue => this.setState({highlightX: xValue})}
            />

      </Segment>
    );
  }
}
<commit_msg>Add missing xDomain param after merge<commit_after>import React from 'react';
import _ from 'lodash';
import {
  XAxis,
  YAxis,
  FlexibleWidthXYPlot,
  VerticalGridLines,
  HorizontalGridLines,
  LineSeries,
  AreaSeries,
  DiscreteColorLegend,
  Crosshair,
} from 'react-vis';
import {Segment} from 'semantic-ui-react';

import {truncateString, displayValue} from '../../util/runhelpers.js';
import {smartNames} from '../../util/plotHelpers.js';
import {format} from 'd3-format';
import Highlight from './highlight.js';
import {Button, Container} from 'semantic-ui-react';

class LinePlotPlot extends React.PureComponent {
  // Implements the actual plot and data as a PureComponent, so that we don't
  // re-render every time the crosshair (highlight) changes.
  state = {
    lastDrawLocation: null,
  };

  render() {
    const smallSizeThresh = 50;
    const {lastDrawLocation} = this.state;
    let {height, xAxis, yScale, lines, disabled, xScale, yAxis} = this.props;
    let xType = 'linear';
    if (xAxis == 'Absolute Time') {
      xType = 'time';
    } else if (xScale == 'log') {
      // this is not actually implemented
      xType = 'log';
    }

    if (!yAxis) {
      yAxis = '';
    }

    let nullGraph = false;
    let smallGraph = false;

    let maxDataLength = _.max(
      lines.filter(line => line.data.length).map((line, i) => line.data.length)
    );

    if (!maxDataLength) {
      nullGraph = true;
    } else if (
      maxDataLength < smallSizeThresh &&
      lines &&
      _.max(
        lines.map(
          (line, i) =>
            line ? _.max(line.data.map((points, i) => points.x)) : 0
        )
      ) < smallSizeThresh
    ) {
      if (maxDataLength < 2) {
        nullGraph = true;
      } else {
        smallGraph = true;
      }
    }

    return (
      // SML: I turned off animation, it was making stuff uncomfortably slow even
      // with the smallGraph detection.
      <FlexibleWidthXYPlot
        animation={false}
        xDomain={
          lastDrawLocation && [lastDrawLocation.left, lastDrawLocation.right]
        }
        yType={yScale}
        xType={xType}
        height={height}>
        <XAxis
          title={truncateString(xAxis)}
          tickTotal={5}
          tickValues={smallGraph ? _.range(1, smallSizeThresh) : null}
          tickFormat={xType != 'time' ? tick => format('.2s')(tick) : null}
          style={{
            line: {stroke: '999'},
            ticks: {stroke: '999'},
            text: {stroke: 'none', fill: 'aaa', fontWeight: 600},
          }}
        />
        <YAxis
          title={truncateString(yAxis)}
          tickValues={null}
          tickFormat={tick => format('.2r')(tick)}
          style={{
            line: {stroke: '999'},
            ticks: {stroke: '999'},
            text: {stroke: 'none', fill: 'aaa', fontWeight: 600},
          }}
        />
        {lines
          .map(
            (line, i) =>
              !disabled[line.title] ? (
                line.area ? (
                  <AreaSeries
                    key={i}
                    color={line.color}
                    data={line.data}
                    getNull={d => d.y !== null}
                    stroke={'#0000'}
                  />
                ) : (
                  <LineSeries
                    key={i}
                    color={line.color}
                    data={line.data}
                    nullAccessor={d => d.y !== null}
                    strokeDasharray={
                      line.mark === 'dashed'
                        ? '4,2'
                        : line.mark === 'dotted' ? '1,1' : undefined
                    }
                    strokeStyle={'solid'}
                  />
                )
              ) : null
          )
          .filter(o => o)
          .reverse() // revese so the top line is the first line
        }
        <Highlight
          onBrushEnd={area => {
            this.setState({
              lastDrawLocation: area,
            });
          }}
        />
      </FlexibleWidthXYPlot>
    );
  }
}

class LinePlotCrosshair extends React.PureComponent {
  // This doesn't contain the data, just the react-vis crosshair (the hover popup
  // that shows y-values at the current x-value).

  _setup(props) {
    // highlights is a map from x-value to list of y-information for each line at
    // that x-value
    this.highlights = {};

    let enabledLines = props.lines.filter(
      line => !props.disabled[line.title] && line.data.length > 0 && !line.aux
    );

    let longestLine = _.max(enabledLines.map(line => line.data.length));

    if (longestLine > 200) {
      // we're going to average points
      let maxX = _.max(
        enabledLines.map(line => {
          return line.data[line.data.length - 1].x;
        })
      );
      let minX = _.min(enabledLines.map(line => line.data[0].x));
      let steps = 50;
      let step = (maxX - minX) / 50;
      // we're gonna make an index for each line since they're sorted
      // and increment them until the x value is higher than our current slice
      let embededLinesIdx = enabledLines.map(line => 0);

      for (let i = 0; i < steps; i++) {
        let minSlice = i * step + minX;
        let maxSlice = (i + 1) * step + minX;
        let avgSlice = (i + 0.5) * step + minX;
        this.highlights[avgSlice] = [];

        for (let j = 0; j < embededLinesIdx.length; j++) {
          let data = [];
          let line = enabledLines[j];
          while (
            line.data[embededLinesIdx[j]] &&
            line.data[embededLinesIdx[j]].x < maxSlice
          ) {
            data.push(enabledLines[j].data[embededLinesIdx[j]].y);
            embededLinesIdx[j]++;
          }
          if (data.length > 0) {
            this.highlights[avgSlice].push({
              title: line.title.toString ? line.title.toString() : line.title,
              color: line.color,
              x: avgSlice,
              y: _.mean(data),
              mark: line.mark,
            });
          }
        }
      }
    } else {
      // we're going to calculate every point exactly
      for (var line of enabledLines) {
        for (var point of line.data) {
          if (_.isNil(this.highlights[point.x])) {
            this.highlights[point.x] = [];
          }
          this.highlights[point.x].push({
            title: line.title.toString ? line.title.toString() : line.title,
            color: line.color,
            x: point.x,
            y: point.y,
            mark: line.mark,
          });
        }
      }
    }

    // False line is a straight line that fits within the chart data. We render
    // it transparently and just use it for it's onNearestX callback.
    this.falseLine = [];
    if (enabledLines.length > 0) {
      let y = enabledLines[0].data[0].y;
      let xs = _.keys(this.highlights).map(k => Number(k));
      this.falseLine = xs.map(x => ({x: x, y: y}));
    }
  }

  componentWillMount() {
    this._setup(this.props);
  }

  componentWillReceiveProps(nextProps) {
    if (
      this.props.lines !== nextProps.lines ||
      this.props.disabled !== nextProps.disabled
    ) {
      this._setup(nextProps);
    }
  }

  render() {
    let {height, xAxis, highlightX, onMouseLeave, onHighlight} = this.props;
    let crosshairValues = null;
    if (highlightX && this.highlights[highlightX]) {
      crosshairValues = this.highlights[highlightX];
    }
    return (
      <FlexibleWidthXYPlot onMouseLeave={() => onMouseLeave()} height={height}>
        <LineSeries
          onNearestX={item => onHighlight(item.x)}
          color="black"
          opacity={0}
          data={this.falseLine}
        />
        {crosshairValues &&
          crosshairValues.length > 0 && (
            <Crosshair values={crosshairValues}>

                  {this.props.xAxis + ': ' + displayValue(crosshairValues[0].x)}

                {crosshairValues.sort((a, b) => b.y - a.y).map((point, i) => (

                        {point.mark === 'dashed'
                          ? '┅'
                          : point.mark === 'dotted' ? '┉' : '━'}
                      {' '}

                        {point.title + ': ' + displayValue(point.y)}

                ))}

            </Crosshair>
          )}
      </FlexibleWidthXYPlot>
    );
  }
}

export default class LinePlot extends React.PureComponent {
  state = {disabled: {}, highlightX: null};

  render() {
    let filteredLines = this.props.lines.filter(line => !line.aux);
    let lines = [];
    lines = filteredLines;
    return (
      <Segment attached="bottom" basic>

            {lines.map((line, i) => (
               {
                  this.setState({
                    ...this.state,
                    disabled: {
                      ...this.state.disabled,
                      [item.title]: !this.state.disabled[item.title],
                    },
                  });
                }}>

                    {line.mark === 'dashed'
                      ? '┅'
                      : line.mark === 'dotted' ? '┉' : '━'}

                {' '}

                  {line.title.toComponent
                    ? line.title.toComponent()
                    : line.title}

            ))}

          <LinePlotPlot
            height={this.props.currentHeight - 70 || 220}
            xAxis={this.props.xAxis}
            yAxis={this.props.yAxis}
            yScale={this.props.yScale}
            lines={this.props.lines}
            disabled={this.state.disabled}
          />

            <LinePlotCrosshair
              height={this.props.currentHeight - 70 || 220}
              xAxis={this.props.xAxis}
              lines={this.props.lines}
              disabled={this.state.disabled}
              highlightX={this.state.highlightX}
              onMouseLeave={() => this.setState({highlightX: null})}
              onHighlight={xValue => this.setState({highlightX: xValue})}
            />

      </Segment>
    );
  }
}
<|endoftext|>


<commit_before>Menubar.View = function ( editor ) {

	var menuConfig,
		optionsPanel,
		createOption,
		createDivider;

	function onLightThemeOptionClick () {

		editor.setTheme( 'css/light.css' );
		editor.config.setKey( 'theme', 'css/light.css' );

	}

	function onDarkThemeOptionClick () {

		editor.setTheme( 'css/dark.css' );
		editor.config.setKey( 'theme', 'css/dark.css' );

	}

	// configure menu contents

	createOption  = UI.MenubarHelper.createOption;
	createDivider = UI.MenubarHelper.createDivider;

	menuConfig    = [
		createOption( 'Light theme', onLightThemeOptionClick ),
		createOption( 'Dark theme', onDarkThemeOptionClick )
	];

	optionsPanel = UI.MenubarHelper.createOptionsPanel( menuConfig );

	return UI.MenubarHelper.createMenuContainer( 'Help', optionsPanel );

}
<commit_msg>Editor: Fixed View menu title.<commit_after>Menubar.View = function ( editor ) {

	var menuConfig,
		optionsPanel,
		createOption,
		createDivider;

	function onLightThemeOptionClick () {

		editor.setTheme( 'css/light.css' );
		editor.config.setKey( 'theme', 'css/light.css' );

	}

	function onDarkThemeOptionClick () {

		editor.setTheme( 'css/dark.css' );
		editor.config.setKey( 'theme', 'css/dark.css' );

	}

	// configure menu contents

	createOption  = UI.MenubarHelper.createOption;
	createDivider = UI.MenubarHelper.createDivider;

	menuConfig    = [
		createOption( 'Light theme', onLightThemeOptionClick ),
		createOption( 'Dark theme', onDarkThemeOptionClick )
	];

	optionsPanel = UI.MenubarHelper.createOptionsPanel( menuConfig );

	return UI.MenubarHelper.createMenuContainer( 'View', optionsPanel );

}
<|endoftext|>


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

    angular
        .module('crowdsource.task.controllers', [])
        .controller('TaskController', TaskController);

    TaskController.$inject = ['$scope', '$location', '$mdToast', '$log', '$http', '$routeParams',
        'Task', 'Authentication', 'Template', '$sce', '$filter'];

    function TaskController($scope, $location, $mdToast, $log, $http, $routeParams, Task, Authentication, Template, $sce, $filter) {
        var self = this;
        self.taskData = null;
        self.buildHtml = buildHtml;
        self.skip = skip;
        self.submitOrSave = submitOrSave;
        self.saveComment = saveComment;

        activate();

        function activate() {
            self.task_worker_id = $routeParams.task_worker_id;
            self.task_id = $routeParams.taskId;
            if (self.task_worker_id) {
                Task.getSavedTask(self.task_worker_id).then(function success(data, status) {
                    self.taskData = data[0];
                    self.taskData.id = self.taskData.task;
                    if (self.taskData.has_comments) {
                        Task.getTaskComments(self.taskData.id).then(
                            function success(data) {
                                angular.extend(self.taskData, {'comments': data[0].comments});
                            },
                            function error(errData) {
                                var err = errData[0];
                                $mdToast.showSimple('Error fetching comments - ' + JSON.stringify(err));
                            }
                        ).finally(function () {
                            });
                    }
                },
                function error(data, status) {
                    $mdToast.showSimple('Could not get task with data.');
                }).finally(function () {}
                );
            } else {

                Task.getTaskWithData(self.task_id).then(function success(data, status) {
                    self.taskData = data[0];
                    if (self.taskData.has_comments) {
                        Task.getTaskComments(self.taskData.id).then(
                            function success(data) {
                                angular.extend(self.taskData, {'comments': data[0].comments});
                            },
                            function error(errData) {
                                var err = errData[0];
                                $mdToast.showSimple('Error fetching comments - ' + JSON.stringify(err));
                            }
                        ).finally(function () {
                            });
                    }
                },
                function error(data, status) {
                    $mdToast.showSimple('Could not get task with data.');
                });
            }

        }

        function buildHtml(item) {
            var html = Template.buildHtml(item);
            return $sce.trustAsHtml(html);
        }

        function skip() {
            Task.skipTask(self.task_id).then(function success(data, status) {
                    $location.path('/task/' + data[0].task);
                },
                function error(data, status) {
                    $mdToast.showSimple('Could not skip task.');
                });
        }

        function submitOrSave(task_status) {

            var itemsToSubmit = $filter('filter')(self.taskData.task_template.template_items, {role: 'input'});
            var itemAnswers = [];
            angular.forEach(itemsToSubmit, function (obj) {
                itemAnswers.push(
                    {
                        template_item: obj.id,
                        result: obj.answer
                    }
                );
            });
            var requestData = {
                task: self.taskData.id,
                template_items: itemAnswers,
                task_status: task_status
            };

            if (self.task_worker_id) {
                Task.updateTask(self.task_worker_id, requestData).then(function success(data) {
                    $location.path('/dashboard');
                },
                function error(data) {
                    $mdToast.showSimple('Could not submit/save task.');
                });

                return;
            }

            Task.submitTask(requestData).then(function success(data, status) {
                    if (task_status == 1) $location.path('/');
                    else if (task_status == 2) $location.path('/task/' + data[0].task);
                },
                function error(data, status) {
                    $mdToast.showSimple('Could not submit/save task.');
                });
        }

        function saveComment() {
            Task.saveComment(self.taskData.id, self.comment.body).then(
                function success(data) {
                    if (self.taskData.comments == undefined) {
                        angular.extend(self.taskData, {'comments': []});
                    }
                    self.taskData.comments.push(data[0]);
                    self.comment.body = null;
                },
                function error(errData) {
                    var err = errData[0];
                    $mdToast.showSimple('Error saving comment - ' + JSON.stringify(err));
                });
        }
    }

})();

<commit_msg>add in condition<commit_after>(function () {
    'use strict';

    angular
        .module('crowdsource.task.controllers', [])
        .controller('TaskController', TaskController);

    TaskController.$inject = ['$scope', '$location', '$mdToast', '$log', '$http', '$routeParams',
        'Task', 'Authentication', 'Template', '$sce', '$filter'];

    function TaskController($scope, $location, $mdToast, $log, $http, $routeParams, Task, Authentication, Template, $sce, $filter) {
        var self = this;
        self.taskData = null;
        self.buildHtml = buildHtml;
        self.skip = skip;
        self.submitOrSave = submitOrSave;
        self.saveComment = saveComment;

        activate();

        function activate() {
            self.task_worker_id = $routeParams.task_worker_id;
            self.task_id = $routeParams.taskId;
            if (self.task_worker_id) {
                Task.getSavedTask(self.task_worker_id).then(function success(data, status) {
                    self.taskData = data[0];
                    self.taskData.id = self.taskData.task;
                    if (self.taskData.has_comments) {
                        Task.getTaskComments(self.taskData.id).then(
                            function success(data) {
                                angular.extend(self.taskData, {'comments': data[0].comments});
                            },
                            function error(errData) {
                                var err = errData[0];
                                $mdToast.showSimple('Error fetching comments - ' + JSON.stringify(err));
                            }
                        ).finally(function () {
                            });
                    }
                },
                function error(data, status) {
                    $mdToast.showSimple('Could not get task with data.');
                }).finally(function () {}
                );
            } else {

                Task.getTaskWithData(self.task_id).then(function success(data, status) {
                    self.taskData = data[0];
                    if (self.taskData.has_comments) {
                        Task.getTaskComments(self.taskData.id).then(
                            function success(data) {
                                angular.extend(self.taskData, {'comments': data[0].comments});
                            },
                            function error(errData) {
                                var err = errData[0];
                                $mdToast.showSimple('Error fetching comments - ' + JSON.stringify(err));
                            }
                        ).finally(function () {
                            });
                    }
                },
                function error(data, status) {
                    $mdToast.showSimple('Could not get task with data.');
                });
            }

        }

        function buildHtml(item) {
            var html = Template.buildHtml(item);
            return $sce.trustAsHtml(html);
        }

        function skip() {
            Task.skipTask(self.task_id).then(function success(data, status) {
                    if (data[1]==200){
                        $location.path('/task/' + data[0].task);
                    }
                    else {
                        $mdToast.showSimple('No tasks left.');
                    }
                },
                function error(data, status) {
                    $mdToast.showSimple('Could not skip task.');
                });
        }

        function submitOrSave(task_status) {

            var itemsToSubmit = $filter('filter')(self.taskData.task_template.template_items, {role: 'input'});
            var itemAnswers = [];
            angular.forEach(itemsToSubmit, function (obj) {
                itemAnswers.push(
                    {
                        template_item: obj.id,
                        result: obj.answer
                    }
                );
            });
            var requestData = {
                task: self.taskData.id,
                template_items: itemAnswers,
                task_status: task_status
            };

            if (self.task_worker_id) {
                Task.updateTask(self.task_worker_id, requestData).then(function success(data) {
                    $location.path('/dashboard');
                },
                function error(data) {
                    $mdToast.showSimple('Could not submit/save task.');
                });

                return;
            }

            Task.submitTask(requestData).then(function success(data, status) {
                    if (task_status == 1 || data[1]!=200) $location.path('/');
                    else if (task_status == 2)
                            $location.path('/task/' + data[0].task);                },
                function error(data, status) {
                    $mdToast.showSimple('Could not submit/save task.');
                });
        }

        function saveComment() {
            Task.saveComment(self.taskData.id, self.comment.body).then(
                function success(data) {
                    if (self.taskData.comments == undefined) {
                        angular.extend(self.taskData, {'comments': []});
                    }
                    self.taskData.comments.push(data[0]);
                    self.comment.body = null;
                },
                function error(errData) {
                    var err = errData[0];
                    $mdToast.showSimple('Error saving comment - ' + JSON.stringify(err));
                });
        }
    }

})();

<|endoftext|>


<commit_before>/*global defineSuite*/
defineSuite(['DynamicScene/KmlDataSource',
             'DynamicScene/DynamicObjectCollection',
             'Core/loadXML',
             'Core/Event'
            ], function(
                    KmlDataSource,
                    loadXML,
                    DynamicObjectCollection,
                    Event) {
    "use strict";
    /*global jasmine,describe,xdescribe,it,xit,expect,beforeEach,afterEach,beforeAll,afterAll,spyOn,runs,waits,waitsFor*/

    it('default constructor has expected values', function() {
        var dataSource = new KmlDataSource();
        expect(dataSource.getChangedEvent()).toBeInstanceOf(Event);
        expect(dataSource.getErrorEvent()).toBeInstanceOf(Event);
        expect(dataSource.getClock()).toBeUndefined();
        expect(dataSource.getDynamicObjectCollection()).toBeInstanceOf(DynamicObjectCollection);
        expect(dataSource.getDynamicObjectCollection().getObjects().length).toEqual(0);
        expect(dataSource.getIsTimeVarying()).toEqual(false);
    });

    it('Test loading Kml', function() {
        var dataSource = new KmlDataSource();
        var url = 'http://localhost:8080/Apps/CesiumViewer/Gallery/KML_Samples.kml';

        dataSource.loadUrl(url);
    });
});<commit_msg>Add a new spec to test the simpler placemark<commit_after>/*global defineSuite*/
defineSuite(['DynamicScene/KmlDataSource',
             'DynamicScene/DynamicObjectCollection',
             'Core/loadXML',
             'Core/Event'
            ], function(
                    KmlDataSource,
                    loadXML,
                    DynamicObjectCollection,
                    Event) {
    "use strict";
    /*global jasmine,describe,xdescribe,it,xit,expect,beforeEach,afterEach,beforeAll,afterAll,spyOn,runs,waits,waitsFor*/

    it('default constructor has expected values', function() {
        var dataSource = new KmlDataSource();
        expect(dataSource.getChangedEvent()).toBeInstanceOf(Event);
        expect(dataSource.getErrorEvent()).toBeInstanceOf(Event);
        expect(dataSource.getClock()).toBeUndefined();
        expect(dataSource.getDynamicObjectCollection()).toBeInstanceOf(DynamicObjectCollection);
        expect(dataSource.getDynamicObjectCollection().getObjects().length).toEqual(0);
        expect(dataSource.getIsTimeVarying()).toEqual(false);
    });

    it('Simple Test loading Kml', function() {
        var dataSource = new KmlDataSource();
        var url = 'http://localhost:8080/Apps/CesiumViewer/Gallery/simplePlacemark.kml';

        dataSource.loadUrl(url);
    });

    it('Test loading Kml', function() {
        var dataSource = new KmlDataSource();
        var url = 'http://localhost:8080/Apps/CesiumViewer/Gallery/KML_Samples.kml';

        dataSource.loadUrl(url);
    });
});<|endoftext|>


<commit_before>'use strict'; // eslint-disable-line

const webpack = require('webpack');
const qs = require('qs');
const autoprefixer = require('autoprefixer');
const mqpacker = require('css-mqpacker');
const CleanPlugin = require('clean-webpack-plugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');

const CopyGlobsPlugin = require('./webpack.plugin.copyglobs');
const mergeWithConcat = require('./util/mergeWithConcat');
const config = require('./config');

const assetsFilenames = (config.enabled.cacheBusting) ? config.cacheBusting : '[name]';
const sourceMapQueryStr = (config.enabled.sourceMaps) ? '+sourceMap' : '-sourceMap';

const jsLoader = {
  test: /\.js$/,
  exclude: [/(node_modules|bower_components)(?![/|\\](bootstrap|foundation-sites))/],
  use: [{
    loader: 'buble',
    options: { objectAssign: 'Object.assign' },
  }],
};

if (config.enabled.watcher) {
  jsLoader.use.unshift('monkey-hot?sourceType=module');
}

let webpackConfig = {
  context: config.paths.assets,
  entry: config.entry,
  devtool: (config.enabled.sourceMaps ? '#source-map' : undefined),
  output: {
    path: config.paths.dist,
    publicPath: config.publicPath,
    filename: `scripts/${assetsFilenames}.js`,
  },
  module: {
    rules: [
      jsLoader,
      {
        enforce: 'pre',
        test: /\.js?$/,
        include: config.paths.assets,
        loader: 'babel',
      },
      {
        test: /\.css$/,
        include: config.paths.assets,
        loader: ExtractTextPlugin.extract({
          fallbackLoader: 'style',
          loader: [
            `css?${sourceMapQueryStr}`,
            'postcss',
            'csscomb',
          ],
        }),
      },
      {
        test: /\.scss$/,
        include: config.paths.assets,
        loader: ExtractTextPlugin.extract({
          fallbackLoader: 'style',
          loader: [
            `css?${sourceMapQueryStr}`,
            'postcss',
            'csscomb',
            `resolve-url?${sourceMapQueryStr}`,
            `sass?${sourceMapQueryStr}`,
          ],
        }),
      },
      {
        test: /\.(png|jpe?g|gif|svg|ico)$/,
        include: config.paths.assets,
        use: [
          `file?${qs.stringify({
            name: `[path]${assetsFilenames}.[ext]`,
          })}`,
        ],
      },
      {
        test: /\.(ttf|eot)$/,
        include: config.paths.assets,
        loader: `file?${qs.stringify({
          name: `[path]${assetsFilenames}.[ext]`,
        })}`,
      },
      {
        test: /\.woff2?$/,
        include: config.paths.assets,
        loader: `url?${qs.stringify({
          limit: 10000,
          mimetype: 'application/font-woff',
          name: `[path]${assetsFilenames}.[ext]`,
        })}`,
      },
      {
        test: /\.(ttf|eot|woff2?|png|jpe?g|gif|svg)$/,
        include: /node_modules|bower_components/,
        loader: 'file',
        options: {
          name: `vendor/${config.cacheBusting}.[ext]`,
        },
      },
    ],
  },
  resolve: {
    modules: [
      config.paths.assets,
      'node_modules',
      'bower_components',
    ],
    enforceExtension: false,
  },
  resolveLoader: {
    moduleExtensions: ['-loader'],
  },
  // externals: {
    // jquery: 'jQuery',
  // },
  plugins: [
    new CleanPlugin([config.paths.dist], {
      root: config.paths.root,
      verbose: false,
    }),
    new CopyGlobsPlugin({
      // It would be nice to switch to copy-webpack-plugin, but unfortunately it doesn't
      // provide a reliable way of tracking the before/after file names
      pattern: config.copy,
      output: `[path]${assetsFilenames}.[ext]`,
      manifest: config.manifest,
    }),
    new ExtractTextPlugin({
      filename: `styles/${assetsFilenames}.css`,
      allChunks: true,
      disable: (config.enabled.watcher),
    }),
    // new webpack.ProvidePlugin({
    // $: 'jquery',
    // jQuery: 'jquery',
    // 'window.jQuery': 'jquery',
    // Tether: 'tether',
    // 'window.Tether': 'tether',
    // }),
    new webpack.DefinePlugin({
      WEBPACK_PUBLIC_PATH: (config.enabled.watcher)
        ? JSON.stringify(config.publicPath)
        : false,
    }),
    new webpack.LoaderOptionsPlugin({
      minimize: config.enabled.optimize,
      debug: config.enabled.watcher,
      stats: { colors: true },
    }),
    new webpack.LoaderOptionsPlugin({
      test: /\.s?css$/,
      options: {
        output: { path: config.paths.dist },
        context: config.paths.assets,
        postcss: [
          mqpacker({ sort: true }),
          autoprefixer({ browsers: ['last 2 versions'] }),
        ],
      },
    }),
    new webpack.LoaderOptionsPlugin({
      test: /\.js$/,
      options: {
        eslint: { failOnWarning: false, failOnError: true },
      },
    }),
  ],
};

/* eslint-disable global-require */ /** Let's only load dependencies as needed */

if (config.enabled.optimize) {
  webpackConfig = mergeWithConcat(webpackConfig, require('./webpack.config.optimize'));
}

if (config.env.production) {
  webpackConfig.plugins.push(new webpack.NoErrorsPlugin());
}

if (config.enabled.cacheBusting) {
  const WebpackAssetsManifest = require('webpack-assets-manifest');

  webpackConfig.plugins.push(
    new WebpackAssetsManifest({
      output: 'assets.json',
      space: 2,
      writeToDisk: false,
      assets: config.manifest,
      replacer: require('./util/assetManifestsFormatter'),
    })
  );
}

if (config.enabled.watcher) {
  webpackConfig.entry = require('./util/addHotMiddleware')(webpackConfig.entry);
  webpackConfig = mergeWithConcat(webpackConfig, require('./webpack.config.watch'));
}

module.exports = webpackConfig;
<commit_msg>fix: remove usage of fallbackLoader and loader<commit_after>'use strict'; // eslint-disable-line

const webpack = require('webpack');
const qs = require('qs');
const autoprefixer = require('autoprefixer');
const mqpacker = require('css-mqpacker');
const CleanPlugin = require('clean-webpack-plugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');

const CopyGlobsPlugin = require('./webpack.plugin.copyglobs');
const mergeWithConcat = require('./util/mergeWithConcat');
const config = require('./config');

const assetsFilenames = (config.enabled.cacheBusting) ? config.cacheBusting : '[name]';
const sourceMapQueryStr = (config.enabled.sourceMaps) ? '+sourceMap' : '-sourceMap';

const jsLoader = {
  test: /\.js$/,
  exclude: [/(node_modules|bower_components)(?![/|\\](bootstrap|foundation-sites))/],
  use: [{
    loader: 'buble',
    options: { objectAssign: 'Object.assign' },
  }],
};

if (config.enabled.watcher) {
  jsLoader.use.unshift('monkey-hot?sourceType=module');
}

let webpackConfig = {
  context: config.paths.assets,
  entry: config.entry,
  devtool: (config.enabled.sourceMaps ? '#source-map' : undefined),
  output: {
    path: config.paths.dist,
    publicPath: config.publicPath,
    filename: `scripts/${assetsFilenames}.js`,
  },
  module: {
    rules: [
      jsLoader,
      {
        enforce: 'pre',
        test: /\.js?$/,
        include: config.paths.assets,
        loader: 'babel',
      },
      {
        test: /\.css$/,
        include: config.paths.assets,
        loader: ExtractTextPlugin.extract({
          fallback: 'style',
          use: [
            `css?${sourceMapQueryStr}`,
            'postcss',
            'csscomb',
          ],
        }),
      },
      {
        test: /\.scss$/,
        include: config.paths.assets,
        loader: ExtractTextPlugin.extract({
          fallback: 'style',
          use: [
            `css?${sourceMapQueryStr}`,
            'postcss',
            'csscomb',
            `resolve-url?${sourceMapQueryStr}`,
            `sass?${sourceMapQueryStr}`,
          ],
        }),
      },
      {
        test: /\.(png|jpe?g|gif|svg|ico)$/,
        include: config.paths.assets,
        use: [
          `file?${qs.stringify({
            name: `[path]${assetsFilenames}.[ext]`,
          })}`,
        ],
      },
      {
        test: /\.(ttf|eot)$/,
        include: config.paths.assets,
        loader: `file?${qs.stringify({
          name: `[path]${assetsFilenames}.[ext]`,
        })}`,
      },
      {
        test: /\.woff2?$/,
        include: config.paths.assets,
        loader: `url?${qs.stringify({
          limit: 10000,
          mimetype: 'application/font-woff',
          name: `[path]${assetsFilenames}.[ext]`,
        })}`,
      },
      {
        test: /\.(ttf|eot|woff2?|png|jpe?g|gif|svg)$/,
        include: /node_modules|bower_components/,
        loader: 'file',
        options: {
          name: `vendor/${config.cacheBusting}.[ext]`,
        },
      },
    ],
  },
  resolve: {
    modules: [
      config.paths.assets,
      'node_modules',
      'bower_components',
    ],
    enforceExtension: false,
  },
  resolveLoader: {
    moduleExtensions: ['-loader'],
  },
  // externals: {
    // jquery: 'jQuery',
  // },
  plugins: [
    new CleanPlugin([config.paths.dist], {
      root: config.paths.root,
      verbose: false,
    }),
    new CopyGlobsPlugin({
      // It would be nice to switch to copy-webpack-plugin, but unfortunately it doesn't
      // provide a reliable way of tracking the before/after file names
      pattern: config.copy,
      output: `[path]${assetsFilenames}.[ext]`,
      manifest: config.manifest,
    }),
    new ExtractTextPlugin({
      filename: `styles/${assetsFilenames}.css`,
      allChunks: true,
      disable: (config.enabled.watcher),
    }),
    // new webpack.ProvidePlugin({
    // $: 'jquery',
    // jQuery: 'jquery',
    // 'window.jQuery': 'jquery',
    // Tether: 'tether',
    // 'window.Tether': 'tether',
    // }),
    new webpack.DefinePlugin({
      WEBPACK_PUBLIC_PATH: (config.enabled.watcher)
        ? JSON.stringify(config.publicPath)
        : false,
    }),
    new webpack.LoaderOptionsPlugin({
      minimize: config.enabled.optimize,
      debug: config.enabled.watcher,
      stats: { colors: true },
    }),
    new webpack.LoaderOptionsPlugin({
      test: /\.s?css$/,
      options: {
        output: { path: config.paths.dist },
        context: config.paths.assets,
        postcss: [
          mqpacker({ sort: true }),
          autoprefixer({ browsers: ['last 2 versions'] }),
        ],
      },
    }),
    new webpack.LoaderOptionsPlugin({
      test: /\.js$/,
      options: {
        eslint: { failOnWarning: false, failOnError: true },
      },
    }),
  ],
};

/* eslint-disable global-require */ /** Let's only load dependencies as needed */

if (config.enabled.optimize) {
  webpackConfig = mergeWithConcat(webpackConfig, require('./webpack.config.optimize'));
}

if (config.env.production) {
  webpackConfig.plugins.push(new webpack.NoErrorsPlugin());
}

if (config.enabled.cacheBusting) {
  const WebpackAssetsManifest = require('webpack-assets-manifest');

  webpackConfig.plugins.push(
    new WebpackAssetsManifest({
      output: 'assets.json',
      space: 2,
      writeToDisk: false,
      assets: config.manifest,
      replacer: require('./util/assetManifestsFormatter'),
    })
  );
}

if (config.enabled.watcher) {
  webpackConfig.entry = require('./util/addHotMiddleware')(webpackConfig.entry);
  webpackConfig = mergeWithConcat(webpackConfig, require('./webpack.config.watch'));
}

module.exports = webpackConfig;
<|endoftext|>


<commit_before>/**
 * Copyright 2017 IBM Corp.
 *
 * 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.
 **/

module.exports = function(RED) {
  var fs = require('fs'),
    temp = require('temp');

  var hummus = require('hummus');
  var _ = require('lodash');
  var extractText = require('./lib/text-extraction');

  temp.track();

  function verifyPayload(msg) {
    if (!msg.payload) {
      return Promise.reject('Missing property: msg.payload');
    } else if (msg.payload instanceof Buffer) {
            return Promise.resolve();
    } else {
      return Promise.reject('msg.payload should be pdf buffer');
    }
  }

  function openTheFile() {
    var p = new Promise(function resolver(resolve, reject){
      temp.open({
        suffix: '.pdf'
      }, function(err, info) {
        if (err) {
          reject('Error receiving the data buffer');
        } else {
          resolve(info);
        }
      });
    });
    return p;
  }

  function syncTheFile(info, msg) {
    var p = new Promise(function resolver(resolve, reject){
      fs.writeFile(info.path, msg.payload, function(err) {
        if (err) {
          reject('Error processing pdf buffer');
        }
        resolve();
      });
    });
    return p;
  }

  function createStream(info) {
    var theStream = hummus.createReader(info.path);
    return Promise.resolve(theStream);
  }

  function processPDF(theStream) {
    var p = new Promise(function resolver(resolve, reject) {
      var pagesPlacements = extractText(theStream);
      resolve(pagesPlacements);
    });
    return p;
  }

  function createResponse(msg, pages) {
    var p = new Promise(function resolver(resolve, reject) {
      msg.payload = pages;
      resolve();
    });
    return p;
  }

  function doSomething() {
    var p = new Promise(function resolver(resolve, reject) {
      reject('nothing yet implemented');
    });
    return p;
  }

  function reportError(node, msg, err) {
    var messageTxt = err;
    //if (err.code && 'ENOENT' === err.code) {
    //  messageTxt = 'Invalid File Path';
    //}
    if (err.error) {
      messageTxt = err.error;
    } else if (err.description) {
      messageTxt = err.description;
    } else if (err.message) {
      messageTxt = err.message;
    }
    node.status({
      fill: 'red',
      shape: 'dot',
      text: messageTxt
    });

    msg.result = {};
    msg.result['error'] = err;
    node.error(messageTxt, msg);
  }

  function Node(config) {
    var node = this;
    RED.nodes.createNode(this, config);

    this.on('input', function(msg) {
      //var message = '';
      node.status({
        fill: 'blue',
        shape: 'dot',
        text: 'loading file'
      });

      var fileInfo = null;

      verifyPayload(msg)
        .then(function() {
          return openTheFile();
        })
        .then(function(info){
          fileInfo = info;
          return syncTheFile(fileInfo, msg);
        })
        .then(function(){
          return createStream(fileInfo);
        })
        .then(function(theStream){
          return processPDF(theStream);
        })
        .then(function(pages){
          return createResponse(msg, pages);
        })
        .then(function() {
          temp.cleanup();
          node.status({});
          node.send(msg);
        })
        .catch(function(err) {
          temp.cleanup();
          reportError(node,msg,err);
          node.send(msg);
        });

    });
  }

  RED.nodes.registerType('pdf-hummus', Node, {
    credentials: {
      token: {
        type: 'text'
      }
    }
  });
};
<commit_msg>Raw working version<commit_after>/**
 * Copyright 2017 IBM Corp.
 *
 * 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.
 **/

module.exports = function(RED) {
  var fs = require('fs'),
    temp = require('temp');

  var hummus = require('hummus');
  var _ = require('lodash');
  var extractText = require('./lib/text-extraction');

  temp.track();

  function verifyPayload(msg) {
    if (!msg.payload) {
      return Promise.reject('Missing property: msg.payload');
    } else if (msg.payload instanceof Buffer) {
            return Promise.resolve();
    } else {
      return Promise.reject('msg.payload should be pdf buffer');
    }
  }

  function openTheFile() {
    var p = new Promise(function resolver(resolve, reject){
      temp.open({
        suffix: '.pdf'
      }, function(err, info) {
        if (err) {
          reject('Error receiving the data buffer');
        } else {
          resolve(info);
        }
      });
    });
    return p;
  }

  function syncTheFile(info, msg) {
    var p = new Promise(function resolver(resolve, reject){
      fs.writeFile(info.path, msg.payload, function(err) {
        if (err) {
          reject('Error processing pdf buffer');
        }
        resolve();
      });
    });
    return p;
  }

  function createStream(info) {
    var theStream = hummus.createReader(info.path);
    return Promise.resolve(theStream);
  }

  function processPDF(theStream) {
    var p = new Promise(function resolver(resolve, reject) {
      var pagesPlacements = extractText(theStream);
      resolve(pagesPlacements);
    });
    return p;
  }

  function createResponse(msg, pages) {
    var p = new Promise(function resolver(resolve, reject) {
      msg.payload = pages;
      resolve();
    });
    return p;
  }

  function doSomething() {
    var p = new Promise(function resolver(resolve, reject) {
      reject('nothing yet implemented');
    });
    return p;
  }

  function reportError(node, msg, err) {
    var messageTxt = err;
    //if (err.code && 'ENOENT' === err.code) {
    //  messageTxt = 'Invalid File Path';
    //}
    if (err.error) {
      messageTxt = err.error;
    } else if (err.description) {
      messageTxt = err.description;
    } else if (err.message) {
      messageTxt = err.message;
    }
    node.status({
      fill: 'red',
      shape: 'dot',
      text: messageTxt
    });

    msg.result = {};
    msg.result['error'] = err;
    node.error(messageTxt, msg);
  }

  function Node(config) {
    var node = this;
    RED.nodes.createNode(this, config);

    this.on('input', function(msg) {
      //var message = '';
      node.status({
        fill: 'blue',
        shape: 'dot',
        text: 'loading file'
      });

      var fileInfo = null;

      verifyPayload(msg)
        .then(function() {
          return openTheFile();
        })
        .then(function(info){
          fileInfo = info;
          return syncTheFile(fileInfo, msg);
        })
        .then(function(){
          return createStream(fileInfo);
        })
        .then(function(theStream){
          node.status({
            fill: 'blue',
            shape: 'dot',
            text: 'processing file'
          });
          return processPDF(theStream);
        })
        .then(function(pages){
          return createResponse(msg, pages);
        })
        .then(function() {
          temp.cleanup();
          node.status({});
          node.send(msg);
        })
        .catch(function(err) {
          temp.cleanup();
          reportError(node,msg,err);
          node.send(msg);
        });

    });
  }

  RED.nodes.registerType('pdf-hummus', Node, {
    credentials: {
      token: {
        type: 'text'
      }
    }
  });
};
<|endoftext|>