<commit_before>'use strict'
const path = require('path')
const utils = require('./utils')
const webpack = require('webpack')
const config = require('../config')
const merge = require('webpack-merge')
const baseWebpackConfig = require('./webpack.base.conf')
const CopyWebpackPlugin = require('copy-webpack-plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const ExtractTextPlugin = require('extract-text-webpack-plugin')
const OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin')
const UglifyJsPlugin = require('uglifyjs-webpack-plugin')

// https://www.npmjs.com/package/webapp-manifest-plugin
const WebappManifest = require('webapp-manifest-plugin')
const WebappManifestPlugin = WebappManifest.default
const compileAppIcons = false
const FAVICON_PLUGIN = WebappManifest.FAVICON_PLUGIN

const env = process.env.NODE_ENV === 'testing'
  ? require('../config/test.env')
  : require('../config/prod.env')

const manifestConfig = require('../src/config/config.manifest.js')
const metaConfig = require('../src/config/config.meta.js')

const webpackConfig = merge(baseWebpackConfig, {
  module: {
    rules: utils.styleLoaders({
      sourceMap: config.build.productionSourceMap,
      extract: true,
      usePostCSS: true
    })
  },
  devtool: config.build.productionSourceMap ? config.build.devtool : false,
  output: {
    path: config.build.assetsRoot,
    filename: utils.assetsPath('js/[name].[chunkhash].js'),
    chunkFilename: utils.assetsPath('js/[id].[chunkhash].js')
  },
  plugins: [
    // http://vuejs.github.io/vue-loader/en/workflow/production.html
    new webpack.DefinePlugin({
      'process.env': env
    }),
    new UglifyJsPlugin({
      uglifyOptions: {
        compress: {
          warnings: false
        }
      },
      sourceMap: config.build.productionSourceMap,
      parallel: true
    }),
    // extract css into its own file
    new ExtractTextPlugin({
      filename: utils.assetsPath('css/[name].[contenthash].css'),
      // Setting the following option to `false` will not extract CSS from codesplit chunks.
      // Their CSS will instead be inserted dynamically with style-loader when the codesplit chunk has been loaded by webpack.
      // It's currently set to `true` because we are seeing that sourcemaps are included in the codesplit bundle as well when it's `false`,
      // increasing file size: https://github.com/vuejs-templates/webpack/issues/1110
      allChunks: true,
    }),
    // Compress extracted CSS. We are using this plugin so that possible
    // duplicated CSS from different components can be deduped.
    new OptimizeCSSPlugin({
      cssProcessorOptions: config.build.productionSourceMap
        ? { safe: true, map: { inline: false } }
        : { safe: true }
    }),
    // generate dist index.html with correct asset hash for caching.
    // you can customize output by editing /index.html
    // see https://github.com/ampedandwired/html-webpack-plugin
    new HtmlWebpackPlugin({
      filename: process.env.NODE_ENV === 'testing'
        ? 'index.html'
        : config.build.index,
      template: 'src/index.html.ejs',
      favicon: 'src/app-icon/favicon.png',
      config: metaConfig,
      inject: true,
      minify: {
        removeComments: true,
        collapseWhitespace: true,
        removeAttributeQuotes: true
        // more options:
        // https://github.com/kangax/html-minifier#options-quick-reference
      },
      // necessary to consistently work with multiple chunks via CommonsChunkPlugin
      chunksSortMode: 'dependency'
    }),
    // keep module.id stable when vender modules does not change
    new webpack.HashedModuleIdsPlugin(),
    // enable scope hoisting
    new webpack.optimize.ModuleConcatenationPlugin(),
    // split vendor js into its own file
    new webpack.optimize.CommonsChunkPlugin({
      name: 'vendor',
      minChunks (module) {
        // any required modules inside node_modules are extracted to vendor
        return (
          module.resource &&
          /\.js$/.test(module.resource) &&
          module.resource.indexOf(
            path.join(__dirname, '../node_modules')
          ) === 0
        )
      }
    }),
    // extract webpack runtime and module manifest to its own file in order to
    // prevent vendor hash from being updated whenever app bundle is updated
    new webpack.optimize.CommonsChunkPlugin({
      name: 'manifest',
      minChunks: Infinity
    }),
    // This instance extracts shared chunks from code splitted chunks and bundles them
    // in a separate chunk, similar to the vendor chunk
    // see: https://webpack.js.org/plugins/commons-chunk-plugin/#extra-async-commons-chunk
    new webpack.optimize.CommonsChunkPlugin({
      name: 'app',
      async: 'vendor-async',
      children: true,
      minChunks: 3
    }),

    // copy custom static assets
    new CopyWebpackPlugin([
      {
        from: path.resolve(__dirname, '../static'),
        to: config.build.assetsSubDirectory,
        ignore: ['.*']
      }
    ])
  ]
})

// Generate manifest.json if set in config
if (manifestConfig) {
  var webAppManifestOptions = manifestConfig;
  if (compileAppIcons) {
    webAppManifestOptions.icons = FAVICON_PLUGIN;
  }
  webpackConfig.plugins.push(new WebappManifestPlugin(manifestConfig))
}

if (config.build.productionGzip) {
  const CompressionWebpackPlugin = require('compression-webpack-plugin')

  webpackConfig.plugins.push(
    new CompressionWebpackPlugin({
      asset: '[path].gz[query]',
      algorithm: 'gzip',
      test: new RegExp(
        '\\.(' +
        config.build.productionGzipExtensions.join('|') +
        ')$'
      ),
      threshold: 10240,
      minRatio: 0.8
    })
  )
}

if (config.build.bundleAnalyzerReport) {
  const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
  webpackConfig.plugins.push(new BundleAnalyzerPlugin())
}

module.exports = webpackConfig
<commit_msg>Removed unused if check<commit_after>'use strict'
const path = require('path')
const utils = require('./utils')
const webpack = require('webpack')
const config = require('../config')
const merge = require('webpack-merge')
const baseWebpackConfig = require('./webpack.base.conf')
const CopyWebpackPlugin = require('copy-webpack-plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const ExtractTextPlugin = require('extract-text-webpack-plugin')
const OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin')
const UglifyJsPlugin = require('uglifyjs-webpack-plugin')

// https://www.npmjs.com/package/webapp-manifest-plugin
const WebappManifest = require('webapp-manifest-plugin')
const WebappManifestPlugin = WebappManifest.default
const FAVICON_PLUGIN = WebappManifest.FAVICON_PLUGIN

const env = process.env.NODE_ENV === 'testing'
  ? require('../config/test.env')
  : require('../config/prod.env')

const manifestConfig = require('../src/config/config.manifest.js')
const metaConfig = require('../src/config/config.meta.js')

const webpackConfig = merge(baseWebpackConfig, {
  module: {
    rules: utils.styleLoaders({
      sourceMap: config.build.productionSourceMap,
      extract: true,
      usePostCSS: true
    })
  },
  devtool: config.build.productionSourceMap ? config.build.devtool : false,
  output: {
    path: config.build.assetsRoot,
    filename: utils.assetsPath('js/[name].[chunkhash].js'),
    chunkFilename: utils.assetsPath('js/[id].[chunkhash].js')
  },
  plugins: [
    // http://vuejs.github.io/vue-loader/en/workflow/production.html
    new webpack.DefinePlugin({
      'process.env': env
    }),
    new UglifyJsPlugin({
      uglifyOptions: {
        compress: {
          warnings: false
        }
      },
      sourceMap: config.build.productionSourceMap,
      parallel: true
    }),
    // extract css into its own file
    new ExtractTextPlugin({
      filename: utils.assetsPath('css/[name].[contenthash].css'),
      // Setting the following option to `false` will not extract CSS from codesplit chunks.
      // Their CSS will instead be inserted dynamically with style-loader when the codesplit chunk has been loaded by webpack.
      // It's currently set to `true` because we are seeing that sourcemaps are included in the codesplit bundle as well when it's `false`,
      // increasing file size: https://github.com/vuejs-templates/webpack/issues/1110
      allChunks: true,
    }),
    // Compress extracted CSS. We are using this plugin so that possible
    // duplicated CSS from different components can be deduped.
    new OptimizeCSSPlugin({
      cssProcessorOptions: config.build.productionSourceMap
        ? { safe: true, map: { inline: false } }
        : { safe: true }
    }),
    // generate dist index.html with correct asset hash for caching.
    // you can customize output by editing /index.html
    // see https://github.com/ampedandwired/html-webpack-plugin
    new HtmlWebpackPlugin({
      filename: process.env.NODE_ENV === 'testing'
        ? 'index.html'
        : config.build.index,
      template: 'src/index.html.ejs',
      favicon: 'src/app-icon/favicon.png',
      config: metaConfig,
      inject: true,
      minify: {
        removeComments: true,
        collapseWhitespace: true,
        removeAttributeQuotes: true
        // more options:
        // https://github.com/kangax/html-minifier#options-quick-reference
      },
      // necessary to consistently work with multiple chunks via CommonsChunkPlugin
      chunksSortMode: 'dependency'
    }),
    // keep module.id stable when vender modules does not change
    new webpack.HashedModuleIdsPlugin(),
    // enable scope hoisting
    new webpack.optimize.ModuleConcatenationPlugin(),
    // split vendor js into its own file
    new webpack.optimize.CommonsChunkPlugin({
      name: 'vendor',
      minChunks (module) {
        // any required modules inside node_modules are extracted to vendor
        return (
          module.resource &&
          /\.js$/.test(module.resource) &&
          module.resource.indexOf(
            path.join(__dirname, '../node_modules')
          ) === 0
        )
      }
    }),
    // extract webpack runtime and module manifest to its own file in order to
    // prevent vendor hash from being updated whenever app bundle is updated
    new webpack.optimize.CommonsChunkPlugin({
      name: 'manifest',
      minChunks: Infinity
    }),
    // This instance extracts shared chunks from code splitted chunks and bundles them
    // in a separate chunk, similar to the vendor chunk
    // see: https://webpack.js.org/plugins/commons-chunk-plugin/#extra-async-commons-chunk
    new webpack.optimize.CommonsChunkPlugin({
      name: 'app',
      async: 'vendor-async',
      children: true,
      minChunks: 3
    }),

    // copy custom static assets
    new CopyWebpackPlugin([
      {
        from: path.resolve(__dirname, '../static'),
        to: config.build.assetsSubDirectory,
        ignore: ['.*']
      }
    ])
  ]
})

// Generate manifest.json if set in config
if (manifestConfig) {
  webpackConfig.plugins.push(new WebappManifestPlugin(manifestConfig))
}

if (config.build.productionGzip) {
  const CompressionWebpackPlugin = require('compression-webpack-plugin')

  webpackConfig.plugins.push(
    new CompressionWebpackPlugin({
      asset: '[path].gz[query]',
      algorithm: 'gzip',
      test: new RegExp(
        '\\.(' +
        config.build.productionGzipExtensions.join('|') +
        ')$'
      ),
      threshold: 10240,
      minRatio: 0.8
    })
  )
}

if (config.build.bundleAnalyzerReport) {
  const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
  webpackConfig.plugins.push(new BundleAnalyzerPlugin())
}

module.exports = webpackConfig
<|endoftext|>


<commit_before>var path = require('path')
var config = require('../config')
var utils = require('./utils')
var webpack = require('webpack')
var merge = require('webpack-merge')
var baseWebpackConfig = require('./webpack.base.conf')
var ExtractTextPlugin = require('extract-text-webpack-plugin')
var HtmlWebpackPlugin = require('html-webpack-plugin')
var OfflinePlugin = require('offline-plugin')
var env = process.env.NODE_ENV === 'testing'
  ? require('../config/test.env')
  : config.build.env

var webpackConfig = merge(baseWebpackConfig, {
  module: {
    loaders: utils.styleLoaders({ sourceMap: config.build.productionSourceMap, extract: true })
  },
  devtool: config.build.productionSourceMap ? '#source-map' : false,
  output: {
    path: config.build.assetsRoot,
    filename: utils.assetsPath('js/[name].[chunkhash].js'),
    chunkFilename: utils.assetsPath('js/[id].[chunkhash].js')
  },
  vue: {
    loaders: utils.cssLoaders({
      sourceMap: config.build.productionSourceMap,
      extract: true
    })
  },
  plugins: [
    // http://vuejs.github.io/vue-loader/en/workflow/production.html
    new webpack.DefinePlugin({
      'process.env': env
    }),
    new webpack.optimize.UglifyJsPlugin({
      compress: {
        warnings: false
      }
    }),
    new webpack.optimize.OccurrenceOrderPlugin(),
    // extract css into its own file
    new ExtractTextPlugin(utils.assetsPath('css/[name].[contenthash].css')),
    // generate dist index.html with correct asset hash for caching.
    // you can customize output by editing /index.html
    // see https://github.com/ampedandwired/html-webpack-plugin
    new HtmlWebpackPlugin({
      filename: process.env.NODE_ENV === 'testing'
        ? 'index.html'
        : config.build.index,
      template: 'index.html',
      inject: true,
      minify: {
        removeComments: true,
        collapseWhitespace: true,
        removeAttributeQuotes: true
        // more options:
        // https://github.com/kangax/html-minifier#options-quick-reference
      },
      // necessary to consistently work with multiple chunks via CommonsChunkPlugin
      chunksSortMode: 'dependency'
    }),
    // split vendor js into its own file
    new webpack.optimize.CommonsChunkPlugin({
      name: 'vendor',
      minChunks: function (module, count) {
        // any required modules inside node_modules are extracted to vendor
        return (
          module.resource &&
          /\.js$/.test(module.resource) &&
          module.resource.indexOf(
            path.join(__dirname, '../node_modules')
          ) === 0
        )
      }
    }),
    // extract webpack runtime and module manifest to its own file in order to
    // prevent vendor hash from being updated whenever app bundle is updated
    new webpack.optimize.CommonsChunkPlugin({
      name: 'manifest',
      chunks: ['vendor']
    }),
    new OfflinePlugin()
  ]
})

if (config.build.productionGzip) {
  var CompressionWebpackPlugin = require('compression-webpack-plugin')

  webpackConfig.plugins.push(
    new CompressionWebpackPlugin({
      asset: '[path].gz[query]',
      algorithm: 'gzip',
      test: new RegExp(
        '\\.(' +
        config.build.productionGzipExtensions.join('|') +
        ')$'
      ),
      threshold: 10240,
      minRatio: 0.8
    })
  )
}

module.exports = webpackConfig
<commit_msg>disabled network access in the installed mode<commit_after>var path = require('path')
var config = require('../config')
var utils = require('./utils')
var webpack = require('webpack')
var merge = require('webpack-merge')
var baseWebpackConfig = require('./webpack.base.conf')
var ExtractTextPlugin = require('extract-text-webpack-plugin')
var HtmlWebpackPlugin = require('html-webpack-plugin')
var OfflinePlugin = require('offline-plugin')
var env = process.env.NODE_ENV === 'testing'
  ? require('../config/test.env')
  : config.build.env

var webpackConfig = merge(baseWebpackConfig, {
  module: {
    loaders: utils.styleLoaders({ sourceMap: config.build.productionSourceMap, extract: true })
  },
  devtool: config.build.productionSourceMap ? '#source-map' : false,
  output: {
    path: config.build.assetsRoot,
    filename: utils.assetsPath('js/[name].[chunkhash].js'),
    chunkFilename: utils.assetsPath('js/[id].[chunkhash].js')
  },
  vue: {
    loaders: utils.cssLoaders({
      sourceMap: config.build.productionSourceMap,
      extract: true
    })
  },
  plugins: [
    // http://vuejs.github.io/vue-loader/en/workflow/production.html
    new webpack.DefinePlugin({
      'process.env': env
    }),
    new webpack.optimize.UglifyJsPlugin({
      compress: {
        warnings: false
      }
    }),
    new webpack.optimize.OccurrenceOrderPlugin(),
    // extract css into its own file
    new ExtractTextPlugin(utils.assetsPath('css/[name].[contenthash].css')),
    // generate dist index.html with correct asset hash for caching.
    // you can customize output by editing /index.html
    // see https://github.com/ampedandwired/html-webpack-plugin
    new HtmlWebpackPlugin({
      filename: process.env.NODE_ENV === 'testing'
        ? 'index.html'
        : config.build.index,
      template: 'index.html',
      inject: true,
      minify: {
        removeComments: true,
        collapseWhitespace: true,
        removeAttributeQuotes: true
        // more options:
        // https://github.com/kangax/html-minifier#options-quick-reference
      },
      // necessary to consistently work with multiple chunks via CommonsChunkPlugin
      chunksSortMode: 'dependency'
    }),
    // split vendor js into its own file
    new webpack.optimize.CommonsChunkPlugin({
      name: 'vendor',
      minChunks: function (module, count) {
        // any required modules inside node_modules are extracted to vendor
        return (
          module.resource &&
          /\.js$/.test(module.resource) &&
          module.resource.indexOf(
            path.join(__dirname, '../node_modules')
          ) === 0
        )
      }
    }),
    // extract webpack runtime and module manifest to its own file in order to
    // prevent vendor hash from being updated whenever app bundle is updated
    new webpack.optimize.CommonsChunkPlugin({
      name: 'manifest',
      chunks: ['vendor']
    }),
    new OfflinePlugin({
      AppCache: {
        NETWORK: null
      }
    })
  ]
})

if (config.build.productionGzip) {
  var CompressionWebpackPlugin = require('compression-webpack-plugin')

  webpackConfig.plugins.push(
    new CompressionWebpackPlugin({
      asset: '[path].gz[query]',
      algorithm: 'gzip',
      test: new RegExp(
        '\\.(' +
        config.build.productionGzipExtensions.join('|') +
        ')$'
      ),
      threshold: 10240,
      minRatio: 0.8
    })
  )
}

module.exports = webpackConfig
<|endoftext|>


<commit_before>'use strict';

const fs = require('fs');
const path = require('path');
const config = require('../config');
const utils = require('./utils');
const webpack = require('webpack');
const merge = require('webpack-merge');
const baseWebpackConfig = require('./webpack.base.conf');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ImageminPlugin = require('imagemin-webpack-plugin').default;
const ScriptExtHtmlWebpackPlugin = require('script-ext-html-webpack-plugin');
const FaviconsWebpackPlugin = require('favicons-webpack-plugin');
const PrerenderSpaPlugin = require('prerender-spa-plugin');

const routesToPrerender = require('../config/prerendered-routes');

const currentBranchName = require('../branchname');

const env = config.build.env;

const webpackConfig = merge(baseWebpackConfig, {
  module: {
    loaders: utils.styleLoaders({ sourceMap: config.build.productionSourceMap, extract: true })
  },
  devtool: config.build.productionSourceMap ? '#source-map' : false,
  output: {
    path: config.build.distDirectory,
    filename: utils.assetsPath('js/[name].[chunkhash].js'),
    chunkFilename: utils.assetsPath('js/[id].[chunkhash].js')
  },
  vue: {
    loaders: utils.cssLoaders({
      sourceMap: config.build.productionSourceMap,
      extract: true
    })
  },
  plugins: [
    // http://vuejs.github.io/vue-loader/en/workflow/production.html
    new webpack.DefinePlugin({
      'process.env': env
    }),
    new webpack.optimize.UglifyJsPlugin({
      compress: {
        warnings: false
      }
    }),
    new webpack.optimize.OccurrenceOrderPlugin(),
    // extract css into its own file
    new ExtractTextPlugin(utils.assetsPath('css/[name].[contenthash].css')),
    // generate dist index.html with correct asset hash for caching.
    // you can customize output by editing /index.html
    // see https://github.com/ampedandwired/html-webpack-plugin
    new HtmlWebpackPlugin({
      filename: path.join(config.build.distDirectory, 'index.html'),
      template: 'index.html',
      inject: 'head',
      minify: {
        removeComments: true,
        collapseWhitespace: true,
        removeAttributeQuotes: true
        // more options:
        // https://github.com/kangax/html-minifier#options-quick-reference
      },
      // necessary to consistently work with multiple chunks via CommonsChunkPlugin
      chunksSortMode: 'dependency'
    }),
    new FaviconsWebpackPlugin({
      // Your source logo
      logo: 'src/main/assets/images/favicon/favicon.png',
      // The prefix for all image files (might be a folder or a name)
      prefix: 'icons-[hash]/',
      // Emit all stats of the generated icons
      emitStats: true,
      // The name of the json containing all favicon information
      statsFilename: 'iconstats-[hash].json',
      // Generate a cache file with control hashes and
      // don't rebuild the favicons until those hashes change
      persistentCache: true,
      // Inject the html into the html-webpack-plugin
      inject: true,
      // favicon background color (see https://github.com/haydenbleasel/favicons#usage)
      background: '#ff6444',
      // favicon app title (see https://github.com/haydenbleasel/favicons#usage)
      title: 'Vis ma vie'
    }),
    // new ScriptExtHtmlWebpackPlugin({
    //   defaultAttribute: 'defer'
    // }),
    // split vendor js into its own file
    new webpack.optimize.CommonsChunkPlugin({
      name: 'vendor',
      minChunks: function (module) {
        // any required modules inside node_modules are extracted to vendor
        return (
          module.resource &&
          /\.js$/.test(module.resource) &&
          module.resource.indexOf('xebia-web-common') < 0 &&
          module.resource.indexOf(
            path.join(__dirname, '../node_modules')
          ) === 0
        );
      }
    }),
    // extract webpack runtime and module manifest to its own file in order to
    // prevent vendor hash from being updated whenever app bundle is updated
    new webpack.optimize.CommonsChunkPlugin({
      name: 'manifest',
      chunks: ['vendor']
    }),
    new PrerenderSpaPlugin(
      config.build.distDirectory,
      routesToPrerender,
      {
        //captureAfterDocumentEvent: 'prerender-page',
        captureAfterTime: 5000,
        maxAttempts: 10,

        postProcessHtml: function (context) {
          return context.html.replace('class="js', 'class="no-js').replace(
            /http(s?):\/\/localhost:([0-9]*)\//g,
            config.host[currentBranchName]+'/'
          )
          .replace('touchevents', '')
          .replace('no-touchevents', '')
          .replace('

', '')
          .replace('', fs.readFileSync(path.join(__dirname, '../tracking.html'), {encoding:"utf-8"}))
        }
      }
    ),
    new ImageminPlugin({
      jpegtran: {
        progressive: true
      },
      pngquant: {
        quality: '65-90',
        speed: 4
      }
    })
  ]
});

if (config.build.productionGzip) {
  const CompressionWebpackPlugin = require('compression-webpack-plugin');

  webpackConfig.plugins.push(
    new CompressionWebpackPlugin({
      asset: '[path][query].gz',
      algorithm: 'gzip',
      test: new RegExp(
        '\\.(' +
        config.build.productionGzipExtensions.join('|') +
        ')$'
      ),
      threshold: 10240,
      minRatio: 0.8
    })
  );
}

module.exports = webpackConfig;
<commit_msg>update dependencies<commit_after>'use strict';

const fs = require('fs');
const path = require('path');
const config = require('../config');
const utils = require('./utils');
const webpack = require('webpack');
const merge = require('webpack-merge');
const baseWebpackConfig = require('./webpack.base.conf');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ImageminPlugin = require('imagemin-webpack-plugin').default;
const ScriptExtHtmlWebpackPlugin = require('script-ext-html-webpack-plugin');
const FaviconsWebpackPlugin = require('favicons-webpack-plugin');
const PrerenderSpaPlugin = require('prerender-spa-plugin');

const routesToPrerender = require('../config/prerendered-routes');

const currentBranchName = require('../branchname');

const env = config.build.env;

const webpackConfig = merge(baseWebpackConfig, {
  module: {
    loaders: utils.styleLoaders({ sourceMap: config.build.productionSourceMap, extract: true })
  },
  devtool: config.build.productionSourceMap ? '#source-map' : false,
  output: {
    path: config.build.distDirectory,
    filename: utils.assetsPath('js/[name].[chunkhash].js'),
    chunkFilename: utils.assetsPath('js/[id].[chunkhash].js')
  },
  vue: {
    loaders: utils.cssLoaders({
      sourceMap: config.build.productionSourceMap,
      extract: true
    })
  },
  plugins: [
    // http://vuejs.github.io/vue-loader/en/workflow/production.html
    new webpack.DefinePlugin({
      'process.env': env
    }),
    new webpack.optimize.UglifyJsPlugin({
      compress: {
        warnings: false
      }
    }),
    new webpack.optimize.OccurrenceOrderPlugin(),
    // extract css into its own file
    new ExtractTextPlugin(utils.assetsPath('css/[name].[contenthash].css')),
    // generate dist index.html with correct asset hash for caching.
    // you can customize output by editing /index.html
    // see https://github.com/ampedandwired/html-webpack-plugin
    new HtmlWebpackPlugin({
      filename: 'index.html',
      template: 'index.html',
      inject: 'head',
      minify: {
        removeComments: true,
        collapseWhitespace: true,
        removeAttributeQuotes: true
        // more options:
        // https://github.com/kangax/html-minifier#options-quick-reference
      },
      // necessary to consistently work with multiple chunks via CommonsChunkPlugin
      chunksSortMode: 'dependency'
    }),
    new FaviconsWebpackPlugin({
      // Your source logo
      logo: 'src/main/assets/images/favicon/favicon.png',
      // The prefix for all image files (might be a folder or a name)
      prefix: 'icons-[hash]/',
      // Emit all stats of the generated icons
      emitStats: true,
      // The name of the json containing all favicon information
      statsFilename: 'iconstats-[hash].json',
      // Generate a cache file with control hashes and
      // don't rebuild the favicons until those hashes change
      persistentCache: true,
      // Inject the html into the html-webpack-plugin
      inject: true,
      // favicon background color (see https://github.com/haydenbleasel/favicons#usage)
      background: '#ff6444',
      // favicon app title (see https://github.com/haydenbleasel/favicons#usage)
      title: 'Vis ma vie'
    }),
    // new ScriptExtHtmlWebpackPlugin({
    //   defaultAttribute: 'defer'
    // }),
    // split vendor js into its own file
    new webpack.optimize.CommonsChunkPlugin({
      name: 'vendor',
      minChunks: function (module) {
        // any required modules inside node_modules are extracted to vendor
        return (
          module.resource &&
          /\.js$/.test(module.resource) &&
          module.resource.indexOf('xebia-web-common') < 0 &&
          module.resource.indexOf(
            path.join(__dirname, '../node_modules')
          ) === 0
        );
      }
    }),
    // extract webpack runtime and module manifest to its own file in order to
    // prevent vendor hash from being updated whenever app bundle is updated
    new webpack.optimize.CommonsChunkPlugin({
      name: 'manifest',
      chunks: ['vendor']
    }),
    new ImageminPlugin({
      jpegtran: {
        progressive: true
      },
      pngquant: {
        quality: '65-90',
        speed: 4
      }
    }),
    new PrerenderSpaPlugin(
      config.build.distDirectory,
      routesToPrerender,
      {
        //captureAfterDocumentEvent: 'prerender-page',
        captureAfterTime: 5000,
        maxAttempts: 10,

        postProcessHtml: function (context) {
          return context.html.replace('class="js', 'class="no-js').replace(
            /http(s?):\/\/localhost:([0-9]*)\//g,
            config.host[currentBranchName]+'/'
          )
          .replace('touchevents', '')
          .replace('no-touchevents', '')
          .replace('

', '')
          .replace('', fs.readFileSync(path.join(__dirname, '../tracking.html'), {encoding:"utf-8"}))
        }
      }
    )
  ]
});

if (config.build.productionGzip) {
  const CompressionWebpackPlugin = require('compression-webpack-plugin');

  webpackConfig.plugins.push(
    new CompressionWebpackPlugin({
      asset: '[path][query].gz',
      algorithm: 'gzip',
      test: new RegExp(
        '\\.(' +
        config.build.productionGzipExtensions.join('|') +
        ')$'
      ),
      threshold: 10240,
      minRatio: 0.8
    })
  );
}

module.exports = webpackConfig;
<|endoftext|>


<commit_before>/**
 * Copyright (c) 2014 "Fronteer LTD"
 * Grasshopper Event Engine
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

/**
 * @RESTModel Config
 *
 * @Required  [allowLocalAccountCreation,allowUserEventCreation,allowUserSerieCreation,enableLocalAuth,enableShibbolethAuth]
 * @Property  {Boolean}      allowLocalAccountCreation           Whether or not local accounts can be created
 * @Property  {Boolean}      allowUserEventCreation              Whether or not regular users can create events
 * @Property  {Boolean}      allowUserSerieCreation              Whether or not regular users can create series
 * @Property  {Boolean}      enableLocalAuth                     Whether or not local authentication is enabled
 * @Property  {Boolean}      enableShibbolethAuth                Whether or not shibboleth authenticated is enabled
 * @Property  {String}       shibIdpEntityId                     The entity ID of the Shibboleth Identity Provider that should be used
 * @Property  {String}       shibExternalIdAttributes            The attribute that uniquely identifies the user. This should be a prioritised space seperated list
 * @Property  {String}       shibMapDisplayname                  The attibute(s) that should be used to construct the displayname. This should be a prioritised space seperated list
 * @Property  {String}       shibMapEmail                        The attibute(s) that should be used to construct the email. This should be a prioritised space seperated list
 */

/**
 * @RESTModel ConfigValues
 *
 * @Required  [{configField}]
 * @Property  {string}                    {configField}               The configuration value for the named configuration element
 */
<commit_msg>Aligned field names in config restmodel<commit_after>/**
 * Copyright (c) 2014 "Fronteer LTD"
 * Grasshopper Event Engine
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

/**
 * @RESTModel Config
 *
 * @Required  [allowLocalAccountCreation,allowUserEventCreation,allowUserSerieCreation,enableLocalAuth,enableShibbolethAuth]
 * @Property  {Boolean}                 allowLocalAccountCreation           Whether or not local accounts can be created
 * @Property  {Boolean}                 allowUserEventCreation              Whether or not regular users can create events
 * @Property  {Boolean}                 allowUserSerieCreation              Whether or not regular users can create series
 * @Property  {Boolean}                 enableLocalAuth                     Whether or not local authentication is enabled
 * @Property  {Boolean}                 enableShibbolethAuth                Whether or not shibboleth authenticated is enabled
 * @Property  {String}                  shibIdpEntityId                     The entity ID of the Shibboleth Identity Provider that should be used
 * @Property  {String}                  shibExternalIdAttributes            The attribute that uniquely identifies the user. This should be a prioritised space seperated list
 * @Property  {String}                  shibMapDisplayname                  The attibute(s) that should be used to construct the displayname. This should be a prioritised space seperated list
 * @Property  {String}                  shibMapEmail                        The attibute(s) that should be used to construct the email. This should be a prioritised space seperated list
 */

/**
 * @RESTModel ConfigValues
 *
 * @Required  [{configField}]
 * @Property  {string}                  {configField}                       The configuration value for the named configuration element
 */
<|endoftext|>


<commit_before>'use strict';

const path        = require('path');
const fs          = require('fs');
const spawnSync   = require('child_process').spawnSync;

const rollup      = require('rollup');
const babel       = require('rollup-plugin-babel');
const nodeResolve = require('rollup-plugin-node-resolve');
const commonjs    = require('rollup-plugin-commonjs');
const json        = require('rollup-plugin-json');
const analyzer    = require('rollup-analyzer');
const builtins    = require('builtin-modules');

const rimraf      = require('rimraf');

const createHandler = require('../lib/handler.js');

let cache;

exports.command = 'build';
exports.desc    = 'Compiles and transpiles source into a lambda-ready build';
exports.builder = {
  analyze: {
    boolean:        true,
    describe:       'Analyze the bundle and print the results',
  },
  verbose: {
    boolean:        true,
    alias:          'v',
    describe:       'Verbose output',
  }
};

function writePackageJson(target) {
  let packageJson = path.join(target, 'package.json');
  global.log.debug({ packageJson }, 'writing package.json');
  fs.writeFileSync(packageJson, JSON.stringify({
    description:    'This file is automatically generated by betty for unbundled dependencies.',
    dependencies:   global.betty.build.unbundled,
  }, null, 2));
}

function npmInstall(target) {
  let node_modules = path.join(target, 'node_modules');
  global.log.debug({ node_modules }, 'removing existing node_modules');
  rimraf.sync(node_modules);
  global.log.debug({ cwd: target }, 'running npm install');
  let res = spawnSync('npm', [ 'install', '--production' ], {
    stdio:      'inherit',
    cwd:        target + '/',
  });
  if (res.status !== 0) {
    global.log.warn({ code: res.status }, 'npm exited with non-zero');
    global.log.trace(res, 'spawn sync response');
  }
  else {
    global.log.debug('npm install success');
  }
}

function removeExternal(target, externals) {
  let node_modules = path.join(target, 'node_modules');
  global.log.debug({ node_modules, externals }, 'removing existing node_modules');
  externals.forEach(external => {
    let extDep = path.join(node_modules, external);
    rimraf.sync(extDep);
  });
  global.log.debug('removed external dependencies');
}

exports.handler = createHandler((argv, done) => {
  global.log.info('build started');
  global.log.debug({ argv }, 'arguments');
  let unbundledKeys = Object.keys(global.betty.build.unbundled || {});
  let defaultRollupOptions = {
    entry:              path.join(process.cwd(), argv.source || 'src/main.js'),
    cache:              cache,
    plugins: [
      json(),
      nodeResolve({
        jsnext:         true,
        main:           true,
        skip:           [ 'aws-sdk' ].concat(builtins, unbundledKeys),
      }),
      commonjs({
        include:        'node_modules/**',
      }),
      babel({
        exclude:        'node_modules/**',
        babelrc:        false,
        presets:        [ [ 'es2015', { modules: false } ] ],
        plugins:        [ 'external-helpers' ],
      }),
    ],
    external:           [ 'aws-sdk' ].concat(builtins, unbundledKeys),
  };
  let buildConfig = argv.rollup || defaultRollupOptions;
  global.log.debug({ rollup: buildConfig }, 'build config');
  global.log.info('starting rollup');
  rollup.rollup(buildConfig).then(bundle => {
    cache = bundle; // build doesn't watch so this isn't used
    global.log.info('build complete');
    let outputConfig = {
      format:       'cjs',
      sourceMap:    true,
      dest:         argv.main || 'dist/index.js',
    };
    bundle.write(outputConfig);
    global.log.debug({ config: outputConfig }, 'output written');
    if (argv.analyze) {
      console.log('\n\n');
      analyzer.formatted(bundle).then(console.log).catch(console.error);
    }
    if (unbundledKeys.length) {
      global.log.debug({ keys: unbundledKeys }, 'processing unbundled');
      let target = path.dirname(path.resolve(argv.main || 'dist/index.js'));
      writePackageJson(target);
      npmInstall(target);
      removeExternal(target, [ 'aws-sdk' ]);
    }
    done(null);
  }, done);
});
<commit_msg>limit unbundled to deps that exist<commit_after>'use strict';

const path        = require('path');
const fs          = require('fs');
const spawnSync   = require('child_process').spawnSync;

const rollup      = require('rollup');
const babel       = require('rollup-plugin-babel');
const nodeResolve = require('rollup-plugin-node-resolve');
const commonjs    = require('rollup-plugin-commonjs');
const json        = require('rollup-plugin-json');
const analyzer    = require('rollup-analyzer');
const builtins    = require('builtin-modules');

const rimraf      = require('rimraf');

const tryLoad     = require('../../common/try-load.js');
const createHandler = require('../lib/handler.js');

let cache;

exports.command = 'build';
exports.desc    = 'Compiles and transpiles source into a lambda-ready build';
exports.builder = {
  analyze: {
    boolean:        true,
    describe:       'Analyze the bundle and print the results',
  },
  verbose: {
    boolean:        true,
    alias:          'v',
    describe:       'Verbose output',
  }
};

function writePackageJson(target) {
  let packageJson = path.join(target, 'package.json');
  global.log.debug({ packageJson }, 'writing package.json');
  fs.writeFileSync(packageJson, JSON.stringify({
    description:    'This file is automatically generated by betty for unbundled dependencies.',
    dependencies:   global.betty.build.unbundled,
  }, null, 2));
}

function npmInstall(target) {
  let node_modules = path.join(target, 'node_modules');
  global.log.debug({ node_modules }, 'removing existing node_modules');
  rimraf.sync(node_modules);
  global.log.debug({ cwd: target }, 'running npm install');
  let res = spawnSync('npm', [ 'install', '--production' ], {
    stdio:      'inherit',
    cwd:        target + '/',
  });
  if (res.status !== 0) {
    global.log.warn({ code: res.status }, 'npm exited with non-zero');
    global.log.trace(res, 'spawn sync response');
  }
  else {
    global.log.debug('npm install success');
  }
}

function removeExternal(target, externals) {
  let node_modules = path.join(target, 'node_modules');
  global.log.debug({ node_modules, externals }, 'removing existing node_modules');
  externals.forEach(external => {
    let extDep = path.join(node_modules, external);
    rimraf.sync(extDep);
  });
  global.log.debug('removed external dependencies');
}

exports.handler = createHandler((argv, done) => {
  global.log.info('build started');
  global.log.debug({ argv }, 'arguments');
  let pkgJson = tryLoad.json(path.join(process.cwd(), 'package.json')) || {};
  let pkgJsonDependencies = Object.keys(pkgJson.dependencies || {});
  let unbundledKeys = Object.keys(global.betty.build.unbundled || {}).filter(unbundledKey => {
    return pkgJsonDependencies.indexOf(unbundledKey) > -1;
  });
  let defaultRollupOptions = {
    entry:              path.join(process.cwd(), argv.source || 'src/main.js'),
    cache:              cache,
    plugins: [
      json(),
      nodeResolve({
        jsnext:         true,
        main:           true,
        skip:           [ 'aws-sdk' ].concat(builtins, unbundledKeys),
      }),
      commonjs({
        include:        'node_modules/**',
      }),
      babel({
        exclude:        'node_modules/**',
        babelrc:        false,
        presets:        [ [ 'es2015', { modules: false } ] ],
        plugins:        [ 'external-helpers' ],
      }),
    ],
    external:           [ 'aws-sdk' ].concat(builtins, unbundledKeys),
  };
  let buildConfig = argv.rollup || defaultRollupOptions;
  global.log.debug({ rollup: buildConfig }, 'build config');
  global.log.info('starting rollup');
  rollup.rollup(buildConfig).then(bundle => {
    cache = bundle; // build doesn't watch so this isn't used
    global.log.info('build complete');
    let outputConfig = {
      format:       'cjs',
      sourceMap:    true,
      dest:         argv.main || 'dist/index.js',
    };
    bundle.write(outputConfig);
    global.log.debug({ config: outputConfig }, 'output written');
    if (argv.analyze) {
      console.log('\n\n');
      analyzer.formatted(bundle).then(console.log).catch(console.error);
    }
    if (unbundledKeys.length) {
      global.log.debug({ keys: unbundledKeys }, 'processing unbundled');
      let target = path.dirname(path.resolve(argv.main || 'dist/index.js'));
      writePackageJson(target);
      npmInstall(target);
      removeExternal(target, [ 'aws-sdk' ]);
    }
    done(null);
  }, done);
});
<|endoftext|>


<commit_before>import Webpack from 'webpack';
import ServerManager from '../ServerManager';
import HapiWebpackPlugin from 'hapi-webpack-plugin';
import notifier from 'node-notifier';

class HapiWebpackHotPlugin {

    constructor(server) {
        const compiler = new Webpack(require('../../../webpack.config.js')); // eslint-disable-line global-require

        compiler.plugin('done', (stats) => this._onDone(stats));

        const options = {
            assets: {
                // webpack-dev-middleware options - https://github.com/webpack/webpack-dev-middleware
                index: '/public/index.html',
            },
            hot: {
                // webpack-hot-middleware options - https://github.com/glenjamin/webpack-hot-middleware
            },
            compiler,
        };

        server.register({
            register: HapiWebpackPlugin,
            options,
        }, (error) => {
            if (error) {
                console.error(error);
            }
        });
    }

    _onDone(stats) {
        const pkg = require('../../../package.json'); // eslint-disable-line global-require
        const time = ((stats.endTime - stats.startTime) / 1000).toFixed(2);

        setTimeout(() => {
            ServerManager.log();
        }, 0);

        notifier.notify({
            title: pkg.name,
            message: `WebPack is done!\n${stats.compilation.errors.length} errors in ${time}s`,
            timeout: 1,
        });
    }

}

export default HapiWebpackHotPlugin;
<commit_msg>remove new from Webpack<commit_after>import Webpack from 'webpack';
import ServerManager from '../ServerManager';
import HapiWebpackPlugin from 'hapi-webpack-plugin';
import notifier from 'node-notifier';

class HapiWebpackHotPlugin {

    constructor(server) {
        const config = require('../../../webpack.config.js'); // eslint-disable-line global-require
        const compiler = Webpack(config);

        compiler.plugin('done', (stats) => this._onDone(stats));

        const options = {
            assets: {
                // webpack-dev-middleware options - https://github.com/webpack/webpack-dev-middleware
                index: '/public/index.html',
            },
            hot: {
                // webpack-hot-middleware options - https://github.com/glenjamin/webpack-hot-middleware
            },
            compiler,
        };

        server.register({
            register: HapiWebpackPlugin,
            options,
        }, (error) => {
            if (error) {
                console.error(error);
            }
        });
    }

    _onDone(stats) {
        const pkg = require('../../../package.json'); // eslint-disable-line global-require
        const time = ((stats.endTime - stats.startTime) / 1000).toFixed(2);

        setTimeout(() => {
            ServerManager.log();
        }, 0);

        notifier.notify({
            title: pkg.name,
            message: `WebPack is done!\n${stats.compilation.errors.length} errors in ${time}s`,
            timeout: 1,
        });
    }

}

export default HapiWebpackHotPlugin;
<|endoftext|>


<commit_before>export const USER_LOGIN = 'plato/USER_LOGIN';
export const INVALIDATE_NOTES = 'plato/INVALIDATE_NOTES';
export const REQUEST_NOTES = 'plato/REQUEST_NOTES';
export const RECEIVE_NOTES = 'plato/RECEIVE_NOTES';
export const TEXT_EDITOR_CHANGE = 'text/TEXT_EDITOR_CHANGE';
export const SPEECH_EDITOR_CHANGE = 'speech/SPEECH_EDITOR_CHANGE';
export const CREATE_SESSION_TITLE = 'session/CREATE_SESSION_TITLE';
export const SEND_CHAT_MESSAGE = 'chat/SEND_CHAT_MESSAGE';
export const LOAD_ARCHIVED_CHAT_MESSAGES = 'chat/LOAD_CHAT_MESSAGES';
export const LOAD_NEW_CHAT_MESSAGE = 'chat/LOAD_NEW_CHAT_MESSAGE';
<commit_msg>Add action type<commit_after>export const USER_LOGIN = 'plato/USER_LOGIN';
export const SIGNED_IN = 'plato/SIGNED_IN';
export const INVALIDATE_NOTES = 'plato/INVALIDATE_NOTES';
export const REQUEST_NOTES = 'plato/REQUEST_NOTES';
export const RECEIVE_NOTES = 'plato/RECEIVE_NOTES';
export const TEXT_EDITOR_CHANGE = 'text/TEXT_EDITOR_CHANGE';
export const SPEECH_EDITOR_CHANGE = 'speech/SPEECH_EDITOR_CHANGE';
export const CREATE_SESSION_TITLE = 'session/CREATE_SESSION_TITLE';
export const SEND_CHAT_MESSAGE = 'chat/SEND_CHAT_MESSAGE';
export const LOAD_ARCHIVED_CHAT_MESSAGES = 'chat/LOAD_CHAT_MESSAGES';
export const LOAD_NEW_CHAT_MESSAGE = 'chat/LOAD_NEW_CHAT_MESSAGE';
<|endoftext|>


<commit_before>var showPatch = (function () {

    function isEmpty(obj) {
        return Object.keys(obj).length === 0;
    }

    function isPointerToArray(path, data) {
        return (new jsonpatch.JSONPointer(path)).get(data) instanceof Array;
    }

    // takes a JSON patch and an original object, and produces a new patch
    // tailored for producing output
    function formatPatch(patch, orig) {

        // First go through the patch and find any array operations.
        // If there are consecutive removes on the same array, the indices
        // must be adjusted since we won't remove anything.
        var new_patch = [], paths = {}, index, p2, splitpath, path, parent;
        patch.forEach(function (p, i) {
            switch (p.op) {
            case "add":
                splitpath = p.path.split("/");
                path = splitpath.slice(0, -1).join("/") || "/";
                p2 = {op: p.op, path: p.path, value: p.value};
                if (isPointerToArray(path, orig)) {
                    index = parseInt(splitpath.slice(-1));
                    if (!paths[path])
                        paths[path] = [];
                    paths[path].push(p2);
                }
                new_patch.push(p2);
                break;
            case "remove":
                splitpath = p.path.split("/");
                path = splitpath.slice(0, -1).join("/") || "/";
                p2 = {op: p.op, path: p.path};
                if (isPointerToArray(path, orig)) {
                    index = parseInt(splitpath.slice(-1));
                    if (!paths[path])
                        paths[path] = [];
                    paths[path].push(p2);
                }
                new_patch.push(p2);
                break;
            case "move":
                // cheat by replacing move by remove+add :(
                var remove = {op: "remove", path: p.from},
                    ptr = new jsonpatch.JSONPointer(p.from),
                    value = ptr.get(orig),
                    add = {op: "add", path: p.path, value: value};
                new_patch.push(remove, add);
                break;
            case "replace":
                p2 = {op: p.op, path: p.path, value: p.value};
                new_patch.push(p2);
                break;
            }
            // TODO: cover "copy" operation too
        });

        // Then go through the array patches found and adjust indices
        // Not sure this is really correct for all cases...
        Object.keys(paths).forEach(function (path) {
            var count = 0;
            paths[path].forEach(function (p) {
                var splitpath = p.path.split("/"),
                    index = splitpath.slice(-1)[0],
                    i = parseInt(index);
                p.path = splitpath.slice(0, -1).join("/") + "/" + (i + count);
                if (p.op == "remove")
                    count++;
            });
        });

        // Now go throuch the patch again and make a new one where the operations
        // are replaced with ones that produce nice output instead
        var new_patch2 = [];
        new_patch.forEach(function (p) {
            var newp = {}, ptr, value, old_value;
            switch (p.op) {
            case "add":
                newp = {
                    op: "add", path: p.path,
                    value: ('' +
                            prettyPrint(null, p.value).innerHTML + '')
                };
                break;
            case "remove":
                ptr = new jsonpatch.JSONPointer(p.path);
                value = ptr.get(orig);
                newp = {
                    op: "replace",
                    path: p.path,
                    value: ('' +
                            prettyPrint(null, value).innerHTML + '')
                };
                break;
            case "replace":
                ptr = new jsonpatch.JSONPointer(p.path);
                old_value = ptr.get(orig);
                newp = {
                    op: "replace",
                    path: p.path,
                    value: ('' +
                            '' +
                            prettyPrint(null, old_value).innerHTML +
                            ' → ' +
                            prettyPrint(null, p.value).innerHTML + '')
                };
            }
            if (!isEmpty(newp)) {
                new_patch2.push(newp);
                // need to update the original each time so that later
                // pointers are correct
                orig = jsonpatch.apply_patch(orig, [newp]);
            }
        });
        return new_patch2;
    }

    // output DOM representation of patched object
    function prettyPrint(element, obj) {
        element = element || document.createElement("span");
        if (obj instanceof Array) {
            var key_el = document.createElement("span");
            key_el.classList.add("open");
            key_el.innerHTML = "[";
            element.appendChild(key_el);
            obj.forEach(function (o) {
                var value_el = document.createElement("div");
                value_el.classList.add("item");
                key_el.appendChild(value_el);
                prettyPrint(value_el, o);
            });
            key_el = document.createElement("span");
            key_el.innerHTML = "]";
            element.appendChild(key_el);
        } else if (obj instanceof Object) {
            var open_el = document.createElement("span");
            open_el.classList.add("open");
            open_el.innerHTML = "{";
            element.appendChild(open_el);

            var item_el = document.createElement("div");
            item_el.classList.add("item");
            open_el.appendChild(item_el);

            Object.keys(obj).forEach(function (key) {
                var wrap_el = document.createElement("div");
                var key_el = document.createElement("span");
                key_el.classList.add("key");
                key_el.innerHTML = key + ": ";
                item_el.appendChild(wrap_el);
                wrap_el.appendChild(key_el);
                var res = prettyPrint(wrap_el, obj[key]);
                if (res.classList) {
                    if(res.classList.contains("add"))
                        key_el.classList.add("add");
                    if(res.classList.contains("remove"))
                        key_el.classList.add("remove");
                    if(res.classList.contains("replace"))
                        key_el.classList.add("replace");
                }
            });
            var close_el = document.createElement("span");
            close_el.classList.add("close");
            close_el.innerHTML = "}";
            element.appendChild(close_el);
        } else {
            var tmp = document.createElement("span");
            tmp.innerHTML = obj;
            if (tmp.firstChild.classList)
                tmp = tmp.firstChild;
            element.appendChild(tmp);
            return tmp;
        }
        return element;
    }

    function showPatch(element, patch, original) {
        var newpatch = formatPatch(patch, original),
            result = jsonpatch.apply_patch(original, newpatch);
        prettyPrint(element, result);
    };

    return showPatch;

})();
<commit_msg>more cleanup<commit_after>var showPatch = (function () {

    function isEmpty(obj) {
        return Object.keys(obj).length === 0;
    }

    function isPointerToArray(path, data) {
        return (new jsonpatch.JSONPointer(path)).get(data) instanceof Array;
    }

    // takes a JSON patch and an original object, and produces a new patch
    // tailored for producing output
    function formatPatch(patch, orig) {

        // First go through the patch and find any array operations.
        // If there are consecutive removes on the same array, the indices
        // must be adjusted since we won't remove anything.
        var new_patch = [], paths = {}, index, p2, splitpath, path, parent;
        patch.forEach(function (p, i) {
            switch (p.op) {
            case "add":
                splitpath = p.path.split("/");
                path = splitpath.slice(0, -1).join("/") || "/";
                p2 = {op: p.op, path: p.path, value: p.value};
                if (isPointerToArray(path, orig)) {
                    index = parseInt(splitpath.slice(-1));
                    if (!paths[path])
                        paths[path] = [];
                    paths[path].push(p2);
                }
                new_patch.push(p2);
                break;
            case "remove":
                splitpath = p.path.split("/");
                path = splitpath.slice(0, -1).join("/") || "/";
                p2 = {op: p.op, path: p.path};
                if (isPointerToArray(path, orig)) {
                    index = parseInt(splitpath.slice(-1));
                    if (!paths[path])
                        paths[path] = [];
                    paths[path].push(p2);
                }
                new_patch.push(p2);
                break;
            case "move":
                // cheat by replacing move by remove+add :(
                var remove = {op: "remove", path: p.from},
                    ptr = new jsonpatch.JSONPointer(p.from),
                    value = ptr.get(orig),
                    add = {op: "add", path: p.path, value: value};
                new_patch.push(remove, add);
                break;
            case "replace":
                p2 = {op: p.op, path: p.path, value: p.value};
                new_patch.push(p2);
                break;
            }
            // TODO: cover "copy" operation too
        });

        // Then go through the array patches found and adjust indices
        // Not sure this is really correct for all cases...
        Object.keys(paths).forEach(function (path) {
            var count = 0;
            paths[path].forEach(function (p) {
                var splitpath = p.path.split("/"),
                    index = splitpath.slice(-1)[0],
                    i = parseInt(index);
                p.path = splitpath.slice(0, -1).join("/") + "/" + (i + count);
                if (p.op == "remove")
                    count++;
            });
        });

        // Now go throuch the patch again and make a new one where the operations
        // are replaced with ones that produce nice output instead
        var new_patch2 = [];
        new_patch.forEach(function (p) {
            var newp = {}, ptr, value, old_value;
            switch (p.op) {
            case "add":
                newp = {
                    op: "add", path: p.path,
                    value: ('' +
                            prettyPrint(null, p.value).innerHTML + '')
                };
                break;
            case "remove":
                ptr = new jsonpatch.JSONPointer(p.path);
                value = ptr.get(orig);
                newp = {
                    op: "replace",
                    path: p.path,
                    value: ('' +
                            prettyPrint(null, value).innerHTML + '')
                };
                break;
            case "replace":
                ptr = new jsonpatch.JSONPointer(p.path);
                old_value = ptr.get(orig);
                newp = {
                    op: "replace",
                    path: p.path,
                    value: ('' +
                            '' +
                            prettyPrint(null, old_value).innerHTML +
                            ' → ' +
                            prettyPrint(null, p.value).innerHTML + '')
                };
            }
            if (!isEmpty(newp)) {
                new_patch2.push(newp);
                // need to update the original each time so that later
                // pointers are correct
                orig = jsonpatch.apply_patch(orig, [newp]);
            }
        });
        return new_patch2;
    }

    // output DOM representation of patched object
    function prettyPrint(element, obj) {
        element = element || document.createElement("span");
        if (obj instanceof Array) {
            var key_el = document.createElement("span");
            key_el.classList.add("open");
            key_el.innerHTML = "[";
            element.appendChild(key_el);
            obj.forEach(function (o) {
                var value_el = document.createElement("div");
                value_el.classList.add("item");
                key_el.appendChild(value_el);
                prettyPrint(value_el, o);
            });
            key_el = document.createElement("span");
            key_el.innerHTML = "]";
            element.appendChild(key_el);
        } else if (obj instanceof Object) {
            var open_el = document.createElement("span");
            open_el.classList.add("open");
            open_el.innerHTML = "{";
            element.appendChild(open_el);

            var item_el = document.createElement("div");
            item_el.classList.add("item");
            open_el.appendChild(item_el);

            Object.keys(obj).forEach(function (key) {
                var wrap_el = document.createElement("div");
                var key_el = document.createElement("span");
                key_el.classList.add("key");
                key_el.innerHTML = key + ": ";
                item_el.appendChild(wrap_el);
                wrap_el.appendChild(key_el);

                var res = prettyPrint(wrap_el, obj[key]);
                if (res.classList) {
                    if(res.classList.contains("add"))
                        key_el.classList.add("add");
                    if(res.classList.contains("remove"))
                        key_el.classList.add("remove");
                    if(res.classList.contains("replace"))
                        key_el.classList.add("replace");
                }
            });
            var close_el = document.createElement("span");
            close_el.classList.add("close");
            close_el.innerHTML = "}";
            element.appendChild(close_el);
        } else {
            var tmp = document.createElement("span");
            tmp.innerHTML = obj;
            if (tmp.firstChild.classList)
                tmp = tmp.firstChild;
            element.appendChild(tmp);
            return tmp;
        }
        return element;
    }

    return function (element, patch, original) {
        var formatted_patch = formatPatch(patch, original),
            result = jsonpatch.apply_patch(original, formatted_patch);
        prettyPrint(element, result);
    };

})();
<|endoftext|>


<commit_before>/**
 * @file PopoverProvider component
 */

import React, {Component, cloneElement, Fragment, createRef} from 'react';
import PropTypes from 'prop-types';

// components
import Popover from '../Popover';

// statics
import Theme from '../Theme';
import Position from '../_statics/Position';

// vendors
import {findDOMNode} from 'react-dom';
import Util from '../_vendors/Util';
import ComponentUtil from '../_vendors/ComponentUtil';

class PopoverProvider extends Component {

    static Position = Position;
    static Theme = Theme;

    static getDerivedStateFromProps(props, state) {
        return {
            prevProps: props,
            visible: ComponentUtil.getDerivedState(props, state, 'visible')
        };
    }

    constructor(props, ...restArgs) {

        super(props, ...restArgs);

        this.trigger = createRef();
        this.triggerEl = null;

        this.state = {
            visible: props.visible
        };

    }

    componentDidMount() {
        this.triggerEl = findDOMNode(this.trigger?.current);
    }

    /**
     * public
     */
    show = () => {

        if (this.state.visible) {
            return;
        }

        this.setState({
            visible: true
        }, () => {
            const {onRequestOpen} = this.props;
            onRequestOpen?.();
        });

    };

    /**
     * public
     */
    hide = () => {

        if (!this.state.visible) {
            return;
        }

        this.setState({
            visible: false
        }, () => {
            const {onRequestClose} = this.props;
            onRequestClose?.();
        });

    };

    /**
     * public
     */
    toggle = () => {
        this.setState({
            visible: !this.state.visible
        }, () => {
            if (!this.state.visible) {
                const {onRequestClose} = this.props;
                onRequestClose?.();
            } else {
                const {onRequestOpen} = this.props;
                onRequestOpen?.();
            }
        });
    };

    handleMouseOver = e => {
        this.props?.children?.props?.onMouseOver?.(e);
        this.show();
    };

    render() {

        const {

                children, popoverContent,

                // not passing down these props
                // eslint-disable-next-line no-unused-vars
                onRequestOpen, onRequestClose,

                ...restProps

            } = this.props,
            {visible} = this.state;

        if (!popoverContent) {
            return children;
        }

        return (
            <Fragment>

                {
                    cloneElement(children, {
                        ref: this.trigger,
                        onMouseOver: this.handleMouseOver
                    })
                }

                <Popover {...restProps}
                         triggerEl={this.triggerEl}
                         visible={visible}
                         onRequestClose={this.hide}>
                    {popoverContent}
                </Popover>

            </Fragment>
        );
    }

}

PopoverProvider.propTypes = {

    children: PropTypes.any,

    /**
     * The CSS class name of the root element.
     */
    className: PropTypes.string,

    /**
     * The CSS class name of the content element.
     */
    contentClassName: PropTypes.string,

    modalClassName: PropTypes.string,

    /**
     * Override the styles of the root element.
     */
    style: PropTypes.object,

    parentEl: PropTypes.object,

    /**
     * This is the DOM element that will be used to set the position of the popover.
     */
    triggerEl: PropTypes.object,

    /**
     * If true,the popover is visible.
     */
    visible: PropTypes.bool,

    /**
     * If true,the popover will have a triangle on the top of the DOM element.
     */
    hasTriangle: PropTypes.bool,

    triangle: PropTypes.element,

    /**
     * The popover theme.Can be primary,highlight,success,warning,error.
     */
    theme: PropTypes.oneOf(Util.enumerateValue(Theme)),

    /**
     * The popover alignment.The value can be Popover.Position.LEFT or Popover.Position.RIGHT.
     */
    position: PropTypes.oneOf(Util.enumerateValue(Position)),

    /**
     * If true, popover will have animation effects.
     */
    isAnimated: PropTypes.bool,

    /**
     * The depth of Paper component.
     */
    depth: PropTypes.number,

    isBlurClose: PropTypes.bool,

    shouldFollowScroll: PropTypes.bool,
    scrollEl: PropTypes.object,

    resetPositionWait: PropTypes.number,
    showModal: PropTypes.bool,

    /**
     * The function of popover render.
     */
    onRender: PropTypes.func,

    /**
     * The function of popover rendered.
     */
    onRendered: PropTypes.func,

    /**
     * The function of popover destroy.
     */
    onDestroy: PropTypes.func,

    /**
     * The function of popover destroyed.
     */
    onDestroyed: PropTypes.func,

    /**
     * Callback function fired when the popover is requested to be opened.
     */
    onRequestOpen: PropTypes.func,

    /**
     * Callback function fired when the popover is requested to be closed.
     */
    onRequestClose: PropTypes.func,

    /**
     * Callback function fired when wrapper wheeled.
     */
    onWheel: PropTypes.func,

    popoverContent: PropTypes.any

};

PopoverProvider.defaultProps = {

    parentEl: document.body,

    visible: false,
    hasTriangle: true,
    theme: Theme.DEFAULT,
    position: Position.BOTTOM,
    isAnimated: true,

    isBlurClose: true,
    shouldFollowScroll: false,
    resetPositionWait: 250,
    showModal: false

};

export default PopoverProvider;
<commit_msg>update PopoverProvider<commit_after>/**
 * @file PopoverProvider component
 */

import React, {Component, cloneElement, createRef} from 'react';
import PropTypes from 'prop-types';

// components
import Popover from '../Popover';

// statics
import Theme from '../Theme';
import Position from '../_statics/Position';

// vendors
import {findDOMNode} from 'react-dom';
import Util from '../_vendors/Util';
import ComponentUtil from '../_vendors/ComponentUtil';

class PopoverProvider extends Component {

    static Position = Position;
    static Theme = Theme;

    static getDerivedStateFromProps(props, state) {
        return {
            prevProps: props,
            visible: ComponentUtil.getDerivedState(props, state, 'visible')
        };
    }

    constructor(props, ...restArgs) {

        super(props, ...restArgs);

        this.trigger = createRef();
        this.triggerEl = null;

        this.state = {
            visible: props.visible
        };

    }

    componentDidMount() {
        this.triggerEl = findDOMNode(this.trigger?.current);
    }

    /**
     * public
     */
    show = () => {

        if (this.state.visible) {
            return;
        }

        this.setState({
            visible: true
        }, () => {
            const {onRequestOpen} = this.props;
            onRequestOpen?.();
        });

    };

    /**
     * public
     */
    hide = () => {

        if (!this.state.visible) {
            return;
        }

        this.setState({
            visible: false
        }, () => {
            const {onRequestClose} = this.props;
            onRequestClose?.();
        });

    };

    /**
     * public
     */
    toggle = () => {
        this.setState({
            visible: !this.state.visible
        }, () => {
            if (!this.state.visible) {
                const {onRequestClose} = this.props;
                onRequestClose?.();
            } else {
                const {onRequestOpen} = this.props;
                onRequestOpen?.();
            }
        });
    };

    handleMouseOver = e => {
        this.props?.children?.props?.onMouseOver?.(e);
        this.show();
    };

    render() {

        const {

                children, popoverContent,

                // not passing down these props
                // eslint-disable-next-line no-unused-vars
                onRequestOpen, onRequestClose,

                ...restProps

            } = this.props,
            {visible} = this.state;

        if (!popoverContent) {
            return children;
        }

        return (
            <>

                {
                    cloneElement(children, {
                        ref: this.trigger,
                        onMouseOver: this.handleMouseOver
                    })
                }

                <Popover {...restProps}
                         triggerEl={this.triggerEl}
                         visible={visible}
                         onRequestClose={this.hide}>
                    {popoverContent}
                </Popover>

            </>
        );
    }

}

PopoverProvider.propTypes = {

    children: PropTypes.any,

    /**
     * The CSS class name of the root element.
     */
    className: PropTypes.string,

    /**
     * The CSS class name of the content element.
     */
    contentClassName: PropTypes.string,

    modalClassName: PropTypes.string,

    /**
     * Override the styles of the root element.
     */
    style: PropTypes.object,

    parentEl: PropTypes.object,

    /**
     * This is the DOM element that will be used to set the position of the popover.
     */
    triggerEl: PropTypes.object,

    /**
     * If true,the popover is visible.
     */
    visible: PropTypes.bool,

    /**
     * If true,the popover will have a triangle on the top of the DOM element.
     */
    hasTriangle: PropTypes.bool,

    triangle: PropTypes.element,

    /**
     * The popover theme.Can be primary,highlight,success,warning,error.
     */
    theme: PropTypes.oneOf(Util.enumerateValue(Theme)),

    /**
     * The popover alignment.The value can be Popover.Position.LEFT or Popover.Position.RIGHT.
     */
    position: PropTypes.oneOf(Util.enumerateValue(Position)),

    /**
     * If true, popover will have animation effects.
     */
    isAnimated: PropTypes.bool,

    /**
     * The depth of Paper component.
     */
    depth: PropTypes.number,

    isBlurClose: PropTypes.bool,

    shouldFollowScroll: PropTypes.bool,
    scrollEl: PropTypes.object,

    resetPositionWait: PropTypes.number,
    showModal: PropTypes.bool,

    /**
     * The function of popover render.
     */
    onRender: PropTypes.func,

    /**
     * The function of popover rendered.
     */
    onRendered: PropTypes.func,

    /**
     * The function of popover destroy.
     */
    onDestroy: PropTypes.func,

    /**
     * The function of popover destroyed.
     */
    onDestroyed: PropTypes.func,

    /**
     * Callback function fired when the popover is requested to be opened.
     */
    onRequestOpen: PropTypes.func,

    /**
     * Callback function fired when the popover is requested to be closed.
     */
    onRequestClose: PropTypes.func,

    /**
     * Callback function fired when wrapper wheeled.
     */
    onWheel: PropTypes.func,

    popoverContent: PropTypes.any

};

PopoverProvider.defaultProps = {

    parentEl: document.body,

    visible: false,
    hasTriangle: true,
    theme: Theme.DEFAULT,
    position: Position.BOTTOM,
    isAnimated: true,

    isBlurClose: true,
    shouldFollowScroll: false,
    resetPositionWait: 250,
    showModal: false

};

export default PopoverProvider;
<|endoftext|>


<commit_before>Template.registerHelper('getSession',function(key){
  return Session.get(key) || null;
});

Tracker.autorun(function () {
  Meteor.call('isAdmin', Meteor.userId(), function(error, result){
    Session.set('isAdmin', result);
  });
});

<commit_msg>Fixes #22 Fixes #24<commit_after>Template.registerHelper('getSession',function(key){
  return Session.get(key) || null;
});

Tracker.autorun(function () {
  Meteor.call('isAdmin', Meteor.userId(), function(error, result){
    Session.set('isAdmin', result);
  });
});

if (!('contains' in String.prototype)) String.prototype.contains = function (str, startIndex) {
  return -1 !== String.prototype.indexOf.call(this, str, startIndex);
};

<|endoftext|>


<commit_before>const commander = require('commander')
const Web3 = require('web3')
const RemixTests = require('./index.js')
const fs = require('fs')
const Provider = require('remix-simulator').Provider
const { Log } = require('./logger.js')
const logger = new Log()
const log = logger.logger
require('colors')

// parse verbosity
function mapVerbosity (v) {
  const levels = {
    0: 'error',
    1: 'warn',
    2: 'info',
    3: 'verbose',
    4: 'debug',
    5: 'silly'
  }
  return levels[v]
}
// get current version
const pjson = require('../package.json')
commander
  .version(pjson.version)
  .option('-v, --verbose <level>', 'run with verbosity', mapVerbosity)
  .action(function (filename) {
    // Console message
    console.log(('\n\t👁 :: Running remix-tests - Unit testing for solidity :: 👁\t\n').white)
    // set logger verbosity
    if (commander.verbose) {
      logger.setVerbosity(commander.verbose)
      log.info('verbosity level set to ' + commander.verbose.blue)
    }
    let web3 = new Web3()
    // web3.setProvider(new web3.providers.HttpProvider('http://localhost:8545'))
    web3.setProvider(new Provider())
    // web3.setProvider(new web3.providers.WebsocketProvider('ws://localhost:8546'))

    let isDirectory = fs.lstatSync(filename).isDirectory()
    RemixTests.runTestFiles(filename, isDirectory, web3)
  })

if (!process.argv.slice(2).length) {
  log.error('Please specify a filename')
  process.exit()
}

commander.parse(process.argv)
<commit_msg>add version & help options<commit_after>const commander = require('commander')
const Web3 = require('web3')
const RemixTests = require('./index.js')
const fs = require('fs')
const Provider = require('remix-simulator').Provider
const { Log } = require('./logger.js')
const logger = new Log()
const log = logger.logger
require('colors')

// parse verbosity
function mapVerbosity (v) {
  const levels = {
    0: 'error',
    1: 'warn',
    2: 'info',
    3: 'verbose',
    4: 'debug',
    5: 'silly'
  }
  return levels[v]
}
const version = require('../package.json').version

commander.version(version)

commander.command('version').description('output the version number').action(function () {
  console.log(version)
})

commander.command('help').description('output usage information').action(function () {
  commander.help()
})

// get current version
commander
  .option('-v, --verbose <level>', 'run with verbosity', mapVerbosity)
  .action(function (filename) {
    // Console message
    console.log(('\n\t👁 :: Running remix-tests - Unit testing for solidity :: 👁\t\n').white)
    // set logger verbosity
    if (commander.verbose) {
      logger.setVerbosity(commander.verbose)
      log.info('verbosity level set to ' + commander.verbose.blue)
    }
    let web3 = new Web3()
    // web3.setProvider(new web3.providers.HttpProvider('http://localhost:8545'))
    web3.setProvider(new Provider())
    // web3.setProvider(new web3.providers.WebsocketProvider('ws://localhost:8546'))

    let isDirectory = fs.lstatSync(filename).isDirectory()
    RemixTests.runTestFiles(filename, isDirectory, web3)
  })

if (!process.argv.slice(2).length) {
  log.error('Please specify a filename')
  process.exit()
}

commander.parse(process.argv)
<|endoftext|>


<commit_before>var _eval = Npm.require('eval');
var cheerio = Npm.require('cheerio');

var handler = function (compileStep) {
  var source = compileStep.read().toString('utf8');
  var jsx = "var Template = Template || {};";
  var eventMaps = {};

  // Split out event maps.
  var _eventMaps = source.split(/Template\.([^\.]+)\.events\(\{/i);
  for(var i = 1; i <= _eventMaps.length-1; i+=2) {
    var className = _eventMaps[i];
    // Split out the trailing end after the Template.Name.events.
    var _eventMap = (_eventMaps[i+1] + '').split(/\n\}\)/i);
    _eventMap = (_eventMap[0] || '').trim();
    if (_eventMap) {
      try {
        var jsxEventMap = Babel.transformMeteor('module.exports = {' + _eventMap + '};', {
          sourceMap: false,
          extraWhitelist: ["react"]
        });
      } catch(e) {
        if (e.loc) {
          // Babel error
          compileStep.error({
            message: e.message,
            sourcePath: compileStep.inputPath,
            line: e.loc.line,
            column: e.loc.column
          });
          return;
        } else {
          throw e;
        }
      }
      var mapContent = jsxEventMap.code;
      if (mapContent) {
        var res = _eval(mapContent);
        if (typeof res == 'object') {
          eventMaps[className] = eventMaps[className] || {};
          _.extend(eventMaps[className], res);
          eventMaps[className].string = _eventMap;
        }
      }
    }
  }

  // Find and start parsing and compiling each templates.
  var parts = source.split(/<template name="(\w+)">/i);
  var extras = parts[0];
  for(var i=1; i <= parts.length-1; i+=2) {
    var className = parts[i];
    jsx += "Template." + className + " = {\n";
    jsx += "  _extend: {},\n";
    jsx += "  _instance: {},\n";
    jsx += "  onCreated: function(f) {return this._onCreated = f || (this._onCreated || function(){})},\n";
    jsx += "  helpers: function(o) {return this._helpers = o || (this._helpers || {})},\n";
    jsx += "  extend: function(o) {return _.extend(this._extend, o || {})},\n";
    jsx += "  events: function() {}\n"; // Ignore, injected below.
    jsx += "};\n";
  }
  for(var i=1; i <= parts.length-1; i+=2) {
    var className = parts[i];

    // Split out the trailing end after the template.
    var code = parts[i+1].split(/<\/template>/i);
    var markup = (code[0] || '');

    /* INJECT EVENTS */
    if (eventMaps[className]) {
      markup = markup.replace(/<([^\>]+)\/>/g, '<$1></$1>');
      for(var key in _.omit(eventMaps[className], 'string')) {
        var selectors = key.split(',');
        for(var j=0; j < selectors.length; j++) {
          var selector = selectors[j].trim().split(/\s(.+)?/);
          var event = selector[0];
          var select = selector[1];
          var $ = cheerio.load(markup);
          if (ReactEvents[event]) {
            $(select).removeAttr(ReactEvents[event]);
            $(select).attr(ReactEvents[event], "{__component.events['" + key + "'].bind(__component, typeof context != 'undefined' ? context : (this.data ? this.data : this))}");
            markup = $.html();
          }
        }
      }
      // Cheerio adds qoutes on all attributes, React don't want that so we have to remove those quotes.
      markup = markup.replace(/"({[^"}]+})"/g, '$1');
    }

    /* START SPACEBARS */

    // Add return and key={index} inside {{#each}}.
    markup = markup.replace(/({{#each [^}]+}}[^<]*)(<\w+)/g, '$1let context=arguments[0];return ($2 key={index}');
    // {{#each}} in
    markup = markup.replace(/{{#each ([^\s]+) in ([^}]+)}}/g, "{(typeof $2 != 'undefined' ? $2 : (this.data && this.data.$2 ? this.data.$2 : [])).map(function($1, index){");
    // {{/each}}
    markup = markup.replace(/{{\/each}}/g, ");})}");

    // {{helper}} raw HTML
    markup = markup.replace(/{{{([^}]*)}}}/g, "{typeof $1 != 'undefined' ? new Sideburns.SafeString($1) : (this.data && this.data.$1 ? this.data.$1 : '')}");

    // {{helper}} SafeString – Dynamic Attribute (class)
    markup = markup.replace(/\sclass={{([^}]*)}}/g, " className={typeof $1 != 'undefined' ? new Sideburns.SafeString($1) : (this.data && this.data.$1? new Sideburns.classNames(this.data.$1) : '')}");

    // {{helper}} SafeString – Dynamic Attribute (other)
    markup = markup.replace(/={{([^}]*)}}/g, "={typeof $1 != 'undefined' ? new Sideburns.SafeString($1) : (this.data && this.data.$1? new Sideburns.SafeString(this.data.$1) : '')}");

    // {{helper}} SafeString – In Attribute Values (class)
    markup = markup.replace(/\sclass="([^\"{]*){{([^}]*)}}([^\"{]*)\"/g, " className={typeof $2 != 'undefined' ? new Sideburns.SafeString($2) : (this.data && this.data.$2? '$1' + new Sideburns.classNames(this.data.$2) + '$3' : '')}");

    // {{helper}} SafeString – In Attribute Values (other)
    markup = markup.replace(/="([^\"{]*){{([^}]*)}}([^\"{]*)\"/g, "={typeof $2 != 'undefined' ? new Sideburns.SafeString($2) : (this.data && this.data.$2? '$1' + new Sideburns.classNames(this.data.$2) + '$3' : '')}");

    // {{helper}} SafeString
    markup = markup.replace(/{{([^}]*)}}/g, "{typeof $1 != 'undefined' ? new Sideburns.SafeString($1) : (this.data && this.data.$1 ? new Sideburns.SafeString(this.data.$1) : '')}");

    /* END SPACEBARS */

    // Fix that annoying issue with React, and allow usage of class.
    markup = markup.replace(/\sclass=/g, ' className=');

    // Fix that annoying issue with React, and allow usage of for.
    markup = markup.replace(/\sfor=/g, ' htmlFor=');

    // ES2015 Template for React components.
    jsx += "Template." + className + "._instance = {displayName: \"" + className + "\",\n";
    jsx += "  _created: false,\n";
    jsx += "  mixins: [ReactMeteorData],\n";
    if (eventMaps[className]) {
      jsx += "  events: {" + eventMaps[className].string + "},\n";
    }
    jsx += "  getInitialState: function() {_.extend(this, _.omit(Template." + className + "._extend, 'getInitialState')); return Template." + className + "._extend.getInitialState ? Template." + className + "._extend.getInitialState.call(this) : null;},\n";
    jsx += "  getMeteorData() {\n";
    jsx += "    let self = this;\n";
    jsx += "    if (!self._created) {\n";
    jsx += "      Tracker.nonreactive(function(){Template." + className + ".onCreated().call(self)});\n";
    jsx += "      self._created = true;\n";
    jsx += "    }\n";
    jsx += "    let _helpers = {};\n";
    jsx += "    let helpers = Template." + className + ".helpers();\n";
    jsx += "    for (let key in helpers) {\n";
    jsx += "      _helpers[key] = helpers[key].call(self);\n";
    jsx += "    };\n";
    jsx += "    return _helpers;\n";
    jsx += "  },\n";
    jsx += "  render: function() {\n";
    jsx += "    let __component = this;";
    jsx += "    return (" + markup + ");";
    jsx += "  }\n";
    jsx += "};\n";
    jsx += className + " = React.createClass(Template." + className + "._instance);";
    extras += (code[1] || '');
  }

  // if (eventMaps[className]) {
  //   console.log(jsx + extras);
  // }

  var outputFile = compileStep.inputPath + ".js";

  try {
    var result = Babel.transformMeteor(jsx + extras, {
      sourceMap: true,
      filename: compileStep.pathForSourceMap,
      sourceMapName: compileStep.pathForSourceMap,
      extraWhitelist: ["react"]
    });
  } catch (e) {
    if (e.loc) {
      // Babel error
      compileStep.error({
        message: e.message,
        sourcePath: compileStep.inputPath,
        line: e.loc.line,
        column: e.loc.column
      });

      console.log(jsx + extras);

      return;
    } else {
      throw e;
    }
  }

  compileStep.addJavaScript({
    path: outputFile,
    sourcePath: compileStep.inputPath,
    data: result.code,
    sourceMap: JSON.stringify(result.map)
  });
};

Plugin.registerSourceHandler('html.jsx', handler);
<commit_msg>Added possibility for custom events.<commit_after>var _eval = Npm.require('eval');
var cheerio = Npm.require('cheerio');

var handler = function (compileStep) {
  var source = compileStep.read().toString('utf8');
  var jsx = "var Template = Template || {};";
  var eventMaps = {};

  // Split out event maps.
  var _eventMaps = source.split(/Template\.([^\.]+)\.events\(\{/i);
  for(var i = 1; i <= _eventMaps.length-1; i+=2) {
    var className = _eventMaps[i];
    // Split out the trailing end after the Template.Name.events.
    var _eventMap = (_eventMaps[i+1] + '').split(/\n\}\)/i);
    _eventMap = (_eventMap[0] || '').trim();
    if (_eventMap) {
      try {
        var jsxEventMap = Babel.transformMeteor('module.exports = {' + _eventMap + '};', {
          sourceMap: false,
          extraWhitelist: ["react"]
        });
      } catch(e) {
        if (e.loc) {
          // Babel error
          compileStep.error({
            message: e.message,
            sourcePath: compileStep.inputPath,
            line: e.loc.line,
            column: e.loc.column
          });
          return;
        } else {
          throw e;
        }
      }
      var mapContent = jsxEventMap.code;
      if (mapContent) {
        var res = _eval(mapContent);
        if (typeof res == 'object') {
          eventMaps[className] = eventMaps[className] || {};
          _.extend(eventMaps[className], res);
          eventMaps[className].string = _eventMap;
        }
      }
    }
  }

  // Find and start parsing and compiling each templates.
  var parts = source.split(/<template name="(\w+)">/i);
  var extras = parts[0];
  for(var i=1; i <= parts.length-1; i+=2) {
    var className = parts[i];
    jsx += "Template." + className + " = {\n";
    jsx += "  _extend: {},\n";
    jsx += "  _instance: {},\n";
    jsx += "  onCreated: function(f) {return this._onCreated = f || (this._onCreated || function(){})},\n";
    jsx += "  helpers: function(o) {return this._helpers = o || (this._helpers || {})},\n";
    jsx += "  extend: function(o) {return _.extend(this._extend, o || {})},\n";
    jsx += "  events: function() {}\n"; // Ignore, injected below.
    jsx += "};\n";
  }
  for(var i=1; i <= parts.length-1; i+=2) {
    var className = parts[i];

    // Split out the trailing end after the template.
    var code = parts[i+1].split(/<\/template>/i);
    var markup = (code[0] || '');

    /* INJECT EVENTS */
    if (eventMaps[className]) {
      markup = markup.replace(/<([^\>]+)\/>/g, '<$1></$1>');
      for(var key in _.omit(eventMaps[className], 'string')) {
        var selectors = key.split(',');
        for(var j=0; j < selectors.length; j++) {
          var selector = selectors[j].trim().split(/\s(.+)?/);
          var event = selector[0];
          var select = selector[1];
          var $ = cheerio.load(markup);
          // Get the react event name or use custom name.
          var eventName = ReactEvents[event] ? ReactEvents[event] : event;
          // Remove duplicate listeners.
          $(select).removeAttr(eventName);
          // Append new listener.
          $(select).attr(eventName, "{__component.events['" + key + "'].bind(__component, typeof context != 'undefined' ? context : (this.data ? this.data : this))}");
          markup = $.html();
        }
      }
      // Cheerio adds qoutes on all attributes, React don't want that so we have to remove those quotes.
      markup = markup.replace(/"({[^"}]+})"/g, '$1');
    }

    /* START SPACEBARS */

    // Add return and key={index} inside {{#each}}.
    markup = markup.replace(/({{#each [^}]+}}[^<]*)(<\w+)/g, '$1let context=arguments[0];return ($2 key={index}');
    // {{#each}} in
    markup = markup.replace(/{{#each ([^\s]+) in ([^}]+)}}/g, "{(typeof $2 != 'undefined' ? $2 : (this.data && this.data.$2 ? this.data.$2 : [])).map(function($1, index){");
    // {{/each}}
    markup = markup.replace(/{{\/each}}/g, ");})}");

    // {{helper}} raw HTML
    markup = markup.replace(/{{{([^}]*)}}}/g, "{typeof $1 != 'undefined' ? new Sideburns.SafeString($1) : (this.data && this.data.$1 ? this.data.$1 : '')}");

    // {{helper}} SafeString – Dynamic Attribute (class)
    markup = markup.replace(/\sclass={{([^}]*)}}/g, " className={typeof $1 != 'undefined' ? new Sideburns.SafeString($1) : (this.data && this.data.$1? new Sideburns.classNames(this.data.$1) : '')}");

    // {{helper}} SafeString – Dynamic Attribute (other)
    markup = markup.replace(/={{([^}]*)}}/g, "={typeof $1 != 'undefined' ? new Sideburns.SafeString($1) : (this.data && this.data.$1? new Sideburns.SafeString(this.data.$1) : '')}");

    // {{helper}} SafeString – In Attribute Values (class)
    markup = markup.replace(/\sclass="([^\"{]*){{([^}]*)}}([^\"{]*)\"/g, " className={typeof $2 != 'undefined' ? new Sideburns.SafeString($2) : (this.data && this.data.$2? '$1' + new Sideburns.classNames(this.data.$2) + '$3' : '')}");

    // {{helper}} SafeString – In Attribute Values (other)
    markup = markup.replace(/="([^\"{]*){{([^}]*)}}([^\"{]*)\"/g, "={typeof $2 != 'undefined' ? new Sideburns.SafeString($2) : (this.data && this.data.$2? '$1' + new Sideburns.classNames(this.data.$2) + '$3' : '')}");

    // {{helper}} SafeString
    markup = markup.replace(/{{([^}]*)}}/g, "{typeof $1 != 'undefined' ? new Sideburns.SafeString($1) : (this.data && this.data.$1 ? new Sideburns.SafeString(this.data.$1) : '')}");

    /* END SPACEBARS */

    // Fix that annoying issue with React, and allow usage of class.
    markup = markup.replace(/\sclass=/g, ' className=');

    // Fix that annoying issue with React, and allow usage of for.
    markup = markup.replace(/\sfor=/g, ' htmlFor=');

    // ES2015 Template for React components.
    jsx += "Template." + className + "._instance = {displayName: \"" + className + "\",\n";
    jsx += "  _created: false,\n";
    jsx += "  mixins: [ReactMeteorData],\n";
    if (eventMaps[className]) {
      jsx += "  events: {" + eventMaps[className].string + "},\n";
    }
    jsx += "  getInitialState: function() {_.extend(this, _.omit(Template." + className + "._extend, 'getInitialState')); return Template." + className + "._extend.getInitialState ? Template." + className + "._extend.getInitialState.call(this) : null;},\n";
    jsx += "  getMeteorData() {\n";
    jsx += "    let self = this;\n";
    jsx += "    if (!self._created) {\n";
    jsx += "      Tracker.nonreactive(function(){Template." + className + ".onCreated().call(self)});\n";
    jsx += "      self._created = true;\n";
    jsx += "    }\n";
    jsx += "    let _helpers = {};\n";
    jsx += "    let helpers = Template." + className + ".helpers();\n";
    jsx += "    for (let key in helpers) {\n";
    jsx += "      _helpers[key] = helpers[key].call(self);\n";
    jsx += "    };\n";
    jsx += "    return _helpers;\n";
    jsx += "  },\n";
    jsx += "  render: function() {\n";
    jsx += "    let __component = this;";
    jsx += "    return (" + markup + ");";
    jsx += "  }\n";
    jsx += "};\n";
    jsx += className + " = React.createClass(Template." + className + "._instance);";
    extras += (code[1] || '');
  }

  // if (eventMaps[className]) {
  //   console.log(jsx + extras);
  // }

  var outputFile = compileStep.inputPath + ".js";

  try {
    var result = Babel.transformMeteor(jsx + extras, {
      sourceMap: true,
      filename: compileStep.pathForSourceMap,
      sourceMapName: compileStep.pathForSourceMap,
      extraWhitelist: ["react"]
    });
  } catch (e) {
    if (e.loc) {
      // Babel error
      compileStep.error({
        message: e.message,
        sourcePath: compileStep.inputPath,
        line: e.loc.line,
        column: e.loc.column
      });

      console.log(jsx + extras);

      return;
    } else {
      throw e;
    }
  }

  compileStep.addJavaScript({
    path: outputFile,
    sourcePath: compileStep.inputPath,
    data: result.code,
    sourceMap: JSON.stringify(result.map)
  });
};

Plugin.registerSourceHandler('html.jsx', handler);
<|endoftext|>


<commit_before>'use strict';

/*
 * Map controller
 */

exports.MapActionsCtrl = [
	'$rootScope',
	'$scope',
	'$q',
	'$location',
	'MessageService',
	'SessionService',
	'Map',
	'MapShare',
	function($rootScope, $scope, $q, $location, Message, Session, Map, MapShare) {

		$scope.getUrl = function(map) {

			var url = window.location.protocol + '//' + window.location.host + '/maps/' + map._id;

			return url;

		};

		/*
		 * Permission control
		 */
		$scope.canEdit = function(map) {

			if(!map || !Session.user)
				return false;

			if(typeof map.creator == 'string' && map.creator == Session.user._id) {
				return true;
			} else if(typeof map.creator == 'object' && map.creator._id == Session.user._id) {
				return true;
			}

			return false;

		};

		$scope.edit = function(map) {

			$location.path('/maps/' + map._id + '/edit');

		};

		$scope.save = function(map) {

			if(map.bounds) {
				map.southWest = map.bounds[0];
				map.northEast = map.bounds[1];
			}

			map.isDraft = false;

			var deferred = $q.defer();

			Map.resource.update({mapId: map._id}, map, function(map) {
				// Send back formatted map bounds
				if(map.southWest && map.northEast) {
					map.bounds = [map.southWest, map.northEast];
				}
				Message.message({
					status: 'ok',
					text: 'Mapa atualizado'
				});
				$rootScope.$broadcast('map.save.success', map);
				deferred.resolve(map);
			}, function(err){
				Message.message({
					status: 'error',
					text: 'Ocorreu um erro.'
				});
				$rootScope.$broadcast('map.save.error', err);
				deferred.resolve(err);
			});

			return deferred.promise;

		};

		$scope.delete = function(map, callback) {

			if(confirm('Você tem certeza que deseja remover este mapa?')) {
				Map.resource.delete({mapId: map._id}, function(res) {
					Message.message({
						status: 'ok',
						text: 'Mapa removido.'
					});
					$rootScope.$broadcast('map.delete.success', map);
				}, function(err) {
					Message.message({
						status: 'error',
						text: 'Ocorreu um erro.'
					});
					$rootScope.$broadcast('map.delete.error', err);
				});
			}

		};

		$scope.share = function(map) {
			MapShare.activate({
				map: map,
				social: {
					facebook: 'http://facebook.com/share.php?u=' + $scope.getUrl(map),
					twitter: 'http://twitter.com/share?url=' + $scope.getUrl(map)
				},
				socialWindow: function(url, type) {
					window.open(url, type, "width=550,height=300,resizable=1");
				},
				close: function() {
					MapShare.deactivate();
				}
			});

			$scope.$on('$destroy', function() {
				MapShare.deactivate();
			});
		};

		$scope.templates = {
			list: '/views/map/list-item.html'
		};

	}
];<commit_msg>remove duplicate message from map removing<commit_after>'use strict';

/*
 * Map controller
 */

exports.MapActionsCtrl = [
	'$rootScope',
	'$scope',
	'$q',
	'$location',
	'MessageService',
	'SessionService',
	'Map',
	'MapShare',
	function($rootScope, $scope, $q, $location, Message, Session, Map, MapShare) {

		$scope.getUrl = function(map) {

			var url = window.location.protocol + '//' + window.location.host + '/maps/' + map._id;

			return url;

		};

		/*
		 * Permission control
		 */
		$scope.canEdit = function(map) {

			if(!map || !Session.user)
				return false;

			if(typeof map.creator == 'string' && map.creator == Session.user._id) {
				return true;
			} else if(typeof map.creator == 'object' && map.creator._id == Session.user._id) {
				return true;
			}

			return false;

		};

		$scope.edit = function(map) {

			$location.path('/maps/' + map._id + '/edit');

		};

		$scope.save = function(map) {

			if(map.bounds) {
				map.southWest = map.bounds[0];
				map.northEast = map.bounds[1];
			}

			map.isDraft = false;

			var deferred = $q.defer();

			Map.resource.update({mapId: map._id}, map, function(map) {
				// Send back formatted map bounds
				if(map.southWest && map.northEast) {
					map.bounds = [map.southWest, map.northEast];
				}
				Message.message({
					status: 'ok',
					text: 'Mapa atualizado'
				});
				$rootScope.$broadcast('map.save.success', map);
				deferred.resolve(map);
			}, function(err){
				Message.message({
					status: 'error',
					text: 'Ocorreu um erro.'
				});
				$rootScope.$broadcast('map.save.error', err);
				deferred.resolve(err);
			});

			return deferred.promise;

		};

		$scope.delete = function(map, callback) {

			if(confirm('Você tem certeza que deseja remover este mapa?')) {
				Map.resource.delete({mapId: map._id}, function(res) {
					$rootScope.$broadcast('map.delete.success', map);
				});
			}

		};

		$scope.share = function(map) {
			MapShare.activate({
				map: map,
				social: {
					facebook: 'http://facebook.com/share.php?u=' + $scope.getUrl(map),
					twitter: 'http://twitter.com/share?url=' + $scope.getUrl(map)
				},
				socialWindow: function(url, type) {
					window.open(url, type, "width=550,height=300,resizable=1");
				},
				close: function() {
					MapShare.deactivate();
				}
			});

			$scope.$on('$destroy', function() {
				MapShare.deactivate();
			});
		};

		$scope.templates = {
			list: '/views/map/list-item.html'
		};

	}
];<|endoftext|>