<commit_before>const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const HtmlTagsPlugin = require('html-webpack-tags-plugin');
const path = require('path');
const zipObject = require('lodash/zipObject');

const highchartsExamples = [
  { name: 'AddSeries' },
  { name: 'AreaWithAnnotations', additional: ['highcharts-annotations'] },
  { name: 'Combo', additional: ['highcharts-more'] },
  { name: 'Events' },
  { name: 'UpdateWithEvents' },
  { name: 'Funnel', additional: ['highcharts-funnel'] },
  { name: 'Treemap', additional: ['highcharts-heatmap', 'highcharts-treemap' ] },
  { name: 'TreemapDrilldown', additional: ['fetch-polyfill', 'highcharts-heatmap', 'highcharts-treemap' ] },
  { name: 'LiveUpdate' },
  { name: 'SimpleLine' },
  { name: 'SplineWithPlotBands' },
  { name: 'SynchronisedCharts', additional: ['fetch-polyfill'] },
  { name: 'Sparkline', additional: ['fetch-polyfill'] },
  { name: 'Loading', additional: ['fetch-polyfill'] },
  { name: 'InvertedChart' },
  { name: '3DChart', additional: ['highcharts-3d', 'highcharts-boost'] },
  { name: 'Reflow', additional: ['re-resizable'] },
  { name: 'ToggleAxis' },
  { name: 'UpdateChart' },
  { name: 'Sankey', additional: ['highcharts-sankey'] },
  { name: 'DependencyWheel', additional: ['highcharts-sankey', 'highcharts-dependency-wheel'] },
  { name: 'StreamGraph', additional: ['highcharts-streamgraph', 'highcharts-series-label'] },
  { name: 'Responsive' },
  { name: 'Gauge', additional: ['highcharts-more', 'highcharts-solid-gauge'] },
  { name: 'Polar', additional: ['highcharts-more'] },
  { name: 'StyleByCSS' }
];

const highstockExamples = [
  { name: 'CustomComponent', additional: ['moment', 'react-day-picker'] },
  { name: 'Highstocks' },
  { name: 'HighstockPlotBands' }
];

const highmapsExamples = [
  { name: 'Map', additional: ['fetch-polyfill', 'react-request'] },
  { name: 'MapBubble', additional: ['fetch-polyfill', 'react-request', 'proj4js'] }
];

const examples = [].concat(
  highchartsExamples.map(({ name, additional = [] }) => ({ name, additional: ['highcharts', 'react-jsx-highcharts'].concat(additional) })),
  highstockExamples.map(({ name, additional = [] }) => ({ name, additional: ['highcharts/highstock', 'react-jsx-highstock'].concat(additional) })),
  highmapsExamples.map(({ name, additional = [] }) => ({ name, additional: ['highcharts/highmaps', 'react-jsx-highmaps'].concat(additional) }))
);

const exampleNames = examples.map(e => e.name);

const externals = {
  // 'react-jsx-highcharts': '../../packages/react-jsx-highcharts/dist/react-jsx-highcharts.min.js',
  // 'react-jsx-highstock':  '../../packages/react-jsx-highstock/dist/react-jsx-highstock.min.js',
  // 'react-jsx-highmaps':  '../../packages/react-jsx-highmaps/dist/react-jsx-highmaps.min.js',
  'react-jsx-highcharts': 'https://cdn.jsdelivr.net/npm/react-jsx-highcharts@^3/dist/react-jsx-highcharts.min.js',
  'react-jsx-highstock':  'https://cdn.jsdelivr.net/npm/react-jsx-highstock@^3/dist/react-jsx-highstock.min.js',
  'react-jsx-highmaps':   'https://cdn.jsdelivr.net/npm/react-jsx-highmaps@^1/dist/react-jsx-highmaps.min.js',
  'react':                'https://cdn.jsdelivr.net/npm/react@^16/umd/react.production.min.js',
  'react-dom':            'https://cdn.jsdelivr.net/npm/react-dom@^16/umd/react-dom.production.min.js',
  'highcharts':           'https://code.highcharts.com/7.2.0/highcharts.js',
  'highcharts/highstock': 'https://code.highcharts.com/stock/7.2.0/highstock.js',
  'highcharts/highmaps':  'https://code.highcharts.com/maps/7.2.0/highmaps.js',
  'highcharts-more':      'https://code.highcharts.com/7.2.0/highcharts-more.js',
  'highcharts-funnel':    'https://code.highcharts.com/7.2.0/modules/funnel.js',
  'highcharts-treemap':   'https://code.highcharts.com/7.2.0/modules/treemap.js',
  'highcharts-heatmap':   'https://code.highcharts.com/7.2.0/modules/heatmap.js',
  'highcharts-3d':        'https://code.highcharts.com/7.2.0/highcharts-3d.js',
  'highcharts-annotations':  'https://code.highcharts.com/7.2.0/modules/annotations.js',
  'highcharts-boost':     'https://code.highcharts.com/7.2.0/modules/boost.js',
  'highcharts-sankey':    'https://code.highcharts.com/7.2.0/modules/sankey.js',
  'highcharts-dependency-wheel': 'https://code.highcharts.com/7.2.0/modules/dependency-wheel.js',
  'highcharts-streamgraph': 'https://code.highcharts.com/7.2.0/modules/streamgraph.js',
  'highcharts-series-label': 'https://code.highcharts.com/7.2.0/modules/series-label.js',
  'highcharts-solid-gauge': 'https://code.highcharts.com/7.2.0/modules/solid-gauge.js',
  'prism':                'https://cdnjs.cloudflare.com/ajax/libs/prism/1.6.0/prism.min.js',
  'prism-jsx':            'https://cdnjs.cloudflare.com/ajax/libs/prism/1.6.0/components/prism-jsx.min.js',
  'moment':               'https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment.min.js',
  'react-day-picker':     'https://cdn.jsdelivr.net/npm/react-day-picker@6.0.5/lib/daypicker.js',
  're-resizable':         'https://cdn.jsdelivr.net/npm/re-resizable@~4.3/lib/re-resizable.umd.js',
  'core-js-polyfill':     'https://cdn.jsdelivr.net/npm/core-js-bundle@3.2.1/index.min.js',
  'fetch-polyfill':       'https://cdnjs.cloudflare.com/ajax/libs/fetch/2.0.3/fetch.min.js',
  'react-request':        'https://cdn.jsdelivr.net/npm/react-request@^3/dist/react-request.min.js',
  'proj4js':              'https://cdnjs.cloudflare.com/ajax/libs/proj4js/2.5.0/proj4.js'
};

module.exports = {
  entry: zipObject(exampleNames, exampleNames.map(name => path.resolve(__dirname, name))),

  output: {
    filename: '[name]/bundle.js',
    path: __dirname,
    library: 'example',
    libraryTarget: 'var'
  },

  externals: {
    'react': 'React',
    'react-dom': 'ReactDOM',
    'highcharts': 'Highcharts',
    'highcharts/js/highcharts': 'Highcharts',
    'highcharts/highstock': 'Highcharts',
    'highcharts/highmaps': 'Highcharts',
    'moment': 'moment',
    'react-day-picker': 'DayPicker',
    're-resizable': 'window[\'re-resizable\']',
    'react-request': 'ReactRequest',
    'proj4js': 'proj4',
    'react-jsx-highcharts': 'ReactHighcharts',
    'react-jsx-highstock': 'ReactHighcharts',
    'react-jsx-highmaps': 'ReactHighcharts'
  },

  module: {
    rules: [
      {
        test: /\.js$/,
        loader: 'babel-loader',
        exclude: /node_modules/,
        query: {
          cacheDirectory: true,
          plugins: [
            "@babel/plugin-proposal-class-properties",
            ["@babel/transform-runtime", { "useESModules": true }]
          ],
          presets: [["@babel/env", { "modules": false }], '@babel/react']
        }
      },
      {
        test: /\.css$/,
        use: ['style-loader', 'css-loader']
      }
    ]
  },

  plugins: [
    new webpack.DefinePlugin({
      'process.env': {
        'NODE_ENV': JSON.stringify('production')
      }
    })
  ].concat(
    // Example code
    examples.map(({ name }) => {
      return new HtmlWebpackPlugin({
        template: path.resolve(__dirname, 'template.html'),
        filename: `${name}/index.html`,
        chunks: [name],
        inject: 'body'
      });
    })
  ).concat(
    // Additional dependencies
    examples.map(({ name, additional = [] }) => {
      return new HtmlTagsPlugin({
        files: `${name}/index.html`,
        scripts: additional.map(d => externals[d]),
        publicPath: false,
        append: false
      });
    })
  ).concat(
    // Default dependencies
    new HtmlTagsPlugin({
      files: '**/index.html',
      scripts: ['prism', 'prism-jsx'].map(d => externals[d]),
      publicPath: false,
      append: false
    })
  ).concat(
    // Default dependencies
    new HtmlTagsPlugin({
      files: '**/index.html',
      scripts: ['core-js-polyfill', 'react', 'react-dom'].map(d => ({
        path: externals[d],
        attributes: { crossorigin: 'true' }
      })),
      publicPath: false,
      append: false
    })
  )
};
<commit_msg>Use highcharts 7.2.1 in examples<commit_after>const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const HtmlTagsPlugin = require('html-webpack-tags-plugin');
const path = require('path');
const zipObject = require('lodash/zipObject');

const highchartsExamples = [
  { name: 'AddSeries' },
  { name: 'AreaWithAnnotations', additional: ['highcharts-annotations'] },
  { name: 'Combo', additional: ['highcharts-more'] },
  { name: 'Events' },
  { name: 'UpdateWithEvents' },
  { name: 'Funnel', additional: ['highcharts-funnel'] },
  { name: 'Treemap', additional: ['highcharts-heatmap', 'highcharts-treemap' ] },
  { name: 'TreemapDrilldown', additional: ['fetch-polyfill', 'highcharts-heatmap', 'highcharts-treemap' ] },
  { name: 'LiveUpdate' },
  { name: 'SimpleLine' },
  { name: 'SplineWithPlotBands' },
  { name: 'SynchronisedCharts', additional: ['fetch-polyfill'] },
  { name: 'Sparkline', additional: ['fetch-polyfill'] },
  { name: 'Loading', additional: ['fetch-polyfill'] },
  { name: 'InvertedChart' },
  { name: '3DChart', additional: ['highcharts-3d', 'highcharts-boost'] },
  { name: 'Reflow', additional: ['re-resizable'] },
  { name: 'ToggleAxis' },
  { name: 'UpdateChart' },
  { name: 'Sankey', additional: ['highcharts-sankey'] },
  { name: 'DependencyWheel', additional: ['highcharts-sankey', 'highcharts-dependency-wheel'] },
  { name: 'StreamGraph', additional: ['highcharts-streamgraph', 'highcharts-series-label'] },
  { name: 'Responsive' },
  { name: 'Gauge', additional: ['highcharts-more', 'highcharts-solid-gauge'] },
  { name: 'Polar', additional: ['highcharts-more'] },
  { name: 'StyleByCSS' }
];

const highstockExamples = [
  { name: 'CustomComponent', additional: ['moment', 'react-day-picker'] },
  { name: 'Highstocks' },
  { name: 'HighstockPlotBands' }
];

const highmapsExamples = [
  { name: 'Map', additional: ['fetch-polyfill', 'react-request'] },
  { name: 'MapBubble', additional: ['fetch-polyfill', 'react-request', 'proj4js'] }
];

const examples = [].concat(
  highchartsExamples.map(({ name, additional = [] }) => ({ name, additional: ['highcharts', 'react-jsx-highcharts'].concat(additional) })),
  highstockExamples.map(({ name, additional = [] }) => ({ name, additional: ['highcharts/highstock', 'react-jsx-highstock'].concat(additional) })),
  highmapsExamples.map(({ name, additional = [] }) => ({ name, additional: ['highcharts/highmaps', 'react-jsx-highmaps'].concat(additional) }))
);

const exampleNames = examples.map(e => e.name);

const externals = {
  // 'react-jsx-highcharts': '../../packages/react-jsx-highcharts/dist/react-jsx-highcharts.min.js',
  // 'react-jsx-highstock':  '../../packages/react-jsx-highstock/dist/react-jsx-highstock.min.js',
  // 'react-jsx-highmaps':  '../../packages/react-jsx-highmaps/dist/react-jsx-highmaps.min.js',
  'react-jsx-highcharts': 'https://cdn.jsdelivr.net/npm/react-jsx-highcharts@^3/dist/react-jsx-highcharts.min.js',
  'react-jsx-highstock':  'https://cdn.jsdelivr.net/npm/react-jsx-highstock@^3/dist/react-jsx-highstock.min.js',
  'react-jsx-highmaps':   'https://cdn.jsdelivr.net/npm/react-jsx-highmaps@^1/dist/react-jsx-highmaps.min.js',
  'react':                'https://cdn.jsdelivr.net/npm/react@^16/umd/react.production.min.js',
  'react-dom':            'https://cdn.jsdelivr.net/npm/react-dom@^16/umd/react-dom.production.min.js',
  'highcharts':           'https://code.highcharts.com/7.2.1/highcharts.js',
  'highcharts/highstock': 'https://code.highcharts.com/stock/7.2.1/highstock.js',
  'highcharts/highmaps':  'https://code.highcharts.com/maps/7.2.1/highmaps.js',
  'highcharts-more':      'https://code.highcharts.com/7.2.1/highcharts-more.js',
  'highcharts-funnel':    'https://code.highcharts.com/7.2.1/modules/funnel.js',
  'highcharts-treemap':   'https://code.highcharts.com/7.2.1/modules/treemap.js',
  'highcharts-heatmap':   'https://code.highcharts.com/7.2.1/modules/heatmap.js',
  'highcharts-3d':        'https://code.highcharts.com/7.2.1/highcharts-3d.js',
  'highcharts-annotations':  'https://code.highcharts.com/7.2.1/modules/annotations.js',
  'highcharts-boost':     'https://code.highcharts.com/7.2.1/modules/boost.js',
  'highcharts-sankey':    'https://code.highcharts.com/7.2.1/modules/sankey.js',
  'highcharts-dependency-wheel': 'https://code.highcharts.com/7.2.1/modules/dependency-wheel.js',
  'highcharts-streamgraph': 'https://code.highcharts.com/7.2.1/modules/streamgraph.js',
  'highcharts-series-label': 'https://code.highcharts.com/7.2.1/modules/series-label.js',
  'highcharts-solid-gauge': 'https://code.highcharts.com/7.2.1/modules/solid-gauge.js',
  'prism':                'https://cdnjs.cloudflare.com/ajax/libs/prism/1.6.0/prism.min.js',
  'prism-jsx':            'https://cdnjs.cloudflare.com/ajax/libs/prism/1.6.0/components/prism-jsx.min.js',
  'moment':               'https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment.min.js',
  'react-day-picker':     'https://cdn.jsdelivr.net/npm/react-day-picker@6.0.5/lib/daypicker.js',
  're-resizable':         'https://cdn.jsdelivr.net/npm/re-resizable@~4.3/lib/re-resizable.umd.js',
  'core-js-polyfill':     'https://cdn.jsdelivr.net/npm/core-js-bundle@3.2.1/index.min.js',
  'fetch-polyfill':       'https://cdnjs.cloudflare.com/ajax/libs/fetch/2.0.3/fetch.min.js',
  'react-request':        'https://cdn.jsdelivr.net/npm/react-request@^3/dist/react-request.min.js',
  'proj4js':              'https://cdnjs.cloudflare.com/ajax/libs/proj4js/2.5.0/proj4.js'
};

module.exports = {
  entry: zipObject(exampleNames, exampleNames.map(name => path.resolve(__dirname, name))),

  output: {
    filename: '[name]/bundle.js',
    path: __dirname,
    library: 'example',
    libraryTarget: 'var'
  },

  externals: {
    'react': 'React',
    'react-dom': 'ReactDOM',
    'highcharts': 'Highcharts',
    'highcharts/js/highcharts': 'Highcharts',
    'highcharts/highstock': 'Highcharts',
    'highcharts/highmaps': 'Highcharts',
    'moment': 'moment',
    'react-day-picker': 'DayPicker',
    're-resizable': 'window[\'re-resizable\']',
    'react-request': 'ReactRequest',
    'proj4js': 'proj4',
    'react-jsx-highcharts': 'ReactHighcharts',
    'react-jsx-highstock': 'ReactHighcharts',
    'react-jsx-highmaps': 'ReactHighcharts'
  },

  module: {
    rules: [
      {
        test: /\.js$/,
        loader: 'babel-loader',
        exclude: /node_modules/,
        query: {
          cacheDirectory: true,
          plugins: [
            "@babel/plugin-proposal-class-properties",
            ["@babel/transform-runtime", { "useESModules": true }]
          ],
          presets: [["@babel/env", { "modules": false }], '@babel/react']
        }
      },
      {
        test: /\.css$/,
        use: ['style-loader', 'css-loader']
      }
    ]
  },

  plugins: [
    new webpack.DefinePlugin({
      'process.env': {
        'NODE_ENV': JSON.stringify('production')
      }
    })
  ].concat(
    // Example code
    examples.map(({ name }) => {
      return new HtmlWebpackPlugin({
        template: path.resolve(__dirname, 'template.html'),
        filename: `${name}/index.html`,
        chunks: [name],
        inject: 'body'
      });
    })
  ).concat(
    // Additional dependencies
    examples.map(({ name, additional = [] }) => {
      return new HtmlTagsPlugin({
        files: `${name}/index.html`,
        scripts: additional.map(d => externals[d]),
        publicPath: false,
        append: false
      });
    })
  ).concat(
    // Default dependencies
    new HtmlTagsPlugin({
      files: '**/index.html',
      scripts: ['prism', 'prism-jsx'].map(d => externals[d]),
      publicPath: false,
      append: false
    })
  ).concat(
    // Default dependencies
    new HtmlTagsPlugin({
      files: '**/index.html',
      scripts: ['core-js-polyfill', 'react', 'react-dom'].map(d => ({
        path: externals[d],
        attributes: { crossorigin: 'true' }
      })),
      publicPath: false,
      append: false
    })
  )
};
<|endoftext|>


<commit_before>var _ = require('underscore');
var gulp = require('gulp');
var s3 = require('gulp-s3');
var browserify = require('gulp-browserify');
var concat = require('gulp-concat');
var uglify = require('gulp-uglify')
var rename = require('gulp-rename');
var connect = require('gulp-connect');
var less = require('gulp-less');
var clean = require('gulp-clean');
var jshint = require('gulp-jshint');
var gzip = require('gulp-gzip');
var template = require('gulp-template');
var watch = require('gulp-watch');
var path = require('path');
var combineCSS = require('combine-css');
var gulpif = require('gulp-if');
var gutil = require('gulp-util');
var handlebars = require('gulp-handlebars');
// var styl = require('gulp-styl');
// var refresh = require('gulp-livereload');
// var lr = require('tiny-lr');
// var server = lr();
var header = require('gulp-header');
var hbsfy = require("hbsfy").configure({
  extensions: ["handlebars"]
});
var fs = require('fs');

var useJsHint = false;
var destRoot = __dirname + "/devel";
var devMode = true;

gulp.task('connect', connect.server({
  root: destRoot,
  port: 8000,
  // livereload: true,
  // open: {
  //   browser: 'chrome' // if not working OS X browser: 'Google Chrome'
  // }
}));

gulp.task('cleancss', function(){
  gulp.src(destRoot + '/css', {read: false})
      .pipe(clean())
})

gulp.task('less', function(){
  gulp.src([
    devMode ? "css/polis_main_devel.less" : "css/polis_main_dist.less",
    ])
      .pipe(less())
      .pipe(concat("polis.css"))
      .pipe(gulp.dest(destRoot + '/css'))
});

gulp.task('fontawesome', function() {
  gulp.src('bower_components/font-awesome/font/**/*')
    .pipe(gulp.dest(destRoot + "/font"));
});
// TODO remove
gulp.task('sparklines', function() {
  var s = gulp.src('sparklines.svg')
    .pipe(gulp.dest(destRoot));
});
gulp.task('index', [
  'sparklines',
], function() {
  var s = gulp.src('index.html');
  if (devMode) {
    s = s.pipe(template({
      basepath: '',
      d3Filename: 'd3.js',
      r2d3Filename: 'r2d3.js',
    }))
  } else {
    s = s.pipe(template({
      //basepath: 'https://s3.amazonaws.com/pol.is',
      basepath: '', // proxy through server (cached by cloudflare, and easier than choosing a bucket for preprod, etc)
      d3Filename: 'd3.min.js',
      r2d3Filename: 'r2d3.min.js',
    }));
  }
  return s.pipe(gulp.dest(destRoot));
});

gulp.task('templates', function(){
  gulp.src(['js/templates/*.hbs', 'js/templates/*.handlebars'])
    .pipe(handlebars({
      outputType: 'node',
      wrapped: true,
    }))
    .pipe(gulp.dest('js/tmpl'));
});

gulp.task('jshint', function(){
  gulp.src('js/**/*.js')
      .pipe(gulpif(useJsHint, jshint(

      {
         // reporter: 'jslint',
          curly: true, // require if,else blocks to have {}
          eqeqeq: true,
          trailing: true, // no trailing whitespace allowed
          // immed: true,
          // latedef: true,
          // newcap: true,
          // noarg: true,
          // sub: true,
          // undef: true,
        //  unused: true,
          quotmark: "double",
         // plusplus: true, // no ++ or --
        //  nonew: true,
          noarg: true, // no arguments.caller and arguments.callee (allow for optimizations)
          newcap: true, // constructors must be capitalized
        //  latedef: "nofunc",
         // indent: 2,
          immed: true,
//          forin: true, require hasOwnProperty checks
          boss: true,
//          debug: true, // uncomment temporarily when you want to allow debugger; statements.
          // browser: true,
          es3: true,
          globals: {
            d3: true,
            jQuery: true,
            console: true,
            require: true,
            define: true,
            requirejs: true,
            describe: true,
            expect: true,
            module: true,
            // it: true
          },
          // relax: eventually we should get rid of these
            //expr: true,
           // loopfunc: true,
            //shadow: true,
        }
        )))
      .pipe(jshint.reporter('default'))
})

gulp.task('scripts', ['templates', 'jshint'], function() {
  // Single entry point to browserify
  var s = gulp.src('js/main.js')
      .pipe(browserify({
        insertGlobals : true,
        debug : false, //!gulp.env.production
        // transform: ['hbsfy'],
        shim : {
          jquery: {
            path : devMode ? 'js/lib/jquery.js' : 'js/lib/jquery.min.js',
            exports: '$',
          },
          //TODO 'handlebars': 'templates/helpers/handlebarsWithHelpers', //this one has polis custom template helpers
          handlebars: {
            path : 'bower_components/handlebars/handlebars.runtime.js', //original handlebars
            exports: 'Handlebars',
          },
          originalbackbone: {
            path: 'bower_components/backbone/backbone', // backbone before modifications
            depends: { jquery: '$', underscore: '_' },
            exports: 'Backbone',
          },
          backbone: {
            path: 'js/net/backbonePolis', // polis-specific backbone modifications
            depends: { originalbackbone: "Backbone" },
            exports: "Backbone",
          },
          underscore: {
            path: 'bower_components/underscore/underscore',
            exports: '_',
          },
          thorax: {
            path: 'bower_components/thorax/thorax',
            depends: { handlebars: 'Handlebars', backbone: 'Backbone' },
            exports: 'Thorax',
          },
          bootstrap_alert: {  //all bootstrap files need to be added to the dependency array of js/main.js
            path: 'bower_components/bootstrap/js/alert',
            depends: { jquery: "jQuery" },
            exports: null,
          },
          bootstrap_tab: {
            path : 'bower_components/bootstrap/js/tab',
            depends: { jquery: "jQuery" },
            exports: null,
          },
          bootstrap_popover: {
            path: 'bower_components/bootstrap/js/popover',
            depends: { jquery: "jQuery" },
            exports: null,
          },
          bootstrap_collapse: {
            path: 'bower_components/bootstrap/js/collapse',
            depends: { jquery: "jQuery" },
            exports: null,
          },
          bootstrap_dropdown: {
            path: 'bower_components/bootstrap/js/dropdown',
            depends: { jquery: "jQuery" },
            exports: null,
          },
          bootstrap_affix: {
            path: 'bower_components/bootstrap/js/affix',
            depends: { jquery: "jQuery" },
            exports: null,
          },
          d3tooltips: {
            path: 'bower_components/d3-tip/index',
            depends: { jquery: "jQuery" },
            exports: null,
          },
          bootstrap_tooltip: {
            path: 'bower_components/bootstrap/js/tooltip',
            depends: { jquery: "jQuery" },
            exports: null,
          },
          bootstrap_button: {
            path: 'bower_components/bootstrap/js/button',
            depends: { jquery: "jQuery" },
            exports: null,
          },
          bootstrap_transition: {
            path: 'bower_components/bootstrap/js/transition',
            depends: { jquery: "jQuery" },
            exports: null,
          },
          owl: {
            path: 'bower_components/owlcarousel/owl-carousel/owl.carousel.min.js',
            depends: { jquery: "jQuery" },
            exports: null,
          },
          VisView: {
            path: 'js/lib/VisView',
            depends: { d3tooltips: 'foo' }, // added to d3 object as d3.tip
            exports: 'VisView',
          },
        },
      }))
      .pipe(concat('polis.js'))
  // TODO      .pipe(header("copyright Polis... (except that libs are mixed in)
      if (!devMode) {
        s = s
          .pipe(uglify())
          .pipe(gzip())
      }
      s = s.pipe(rename('polis.js'));
      return s.pipe(gulp.dest(destRoot + "/js"));
});

// for big infrequently changing scripts that we don't want to concatenate
// on each dev build.
gulp.task("scriptsOther", function() {

  var files = [];
  if (devMode) {
    files.push('bower_components/d3/d3.js');
    files.push('bower_components/r2d3/r2d3.js');
  } else {
    files.push('bower_components/d3/d3.min.js');
    files.push('bower_components/r2d3/r2d3.min.js');
  }
  var s = gulp.src(files);
  if (!devMode) {
    s = s
      .pipe(uglify())
      .pipe(gzip())
      .pipe(rename(function (path) {
        // path.dirname += "/ciao";
        // path.basename += "-goodbye";
        // path.extname = ".md"

        // remove .gz extension
        var ext = path.extname;
        path.extname = ext.substr(0, ext.length- ".gz".length);
      }));
  }
  return s.pipe(gulp.dest(destRoot + "/js"));
});

gulp.task("configureForProduction", function() {
  destRoot = "./dist";
  devMode = false;
});

gulp.task('common', [
  "scriptsOther",
  "scripts",
  "less",
  "fontawesome",
  "index",
  ], function() {
    // if (devMode) {
    //   connect.reload();
    // }
});

gulp.task('dev', [
  "common",
  ], function(){
});

gulp.task('dist', [
  "configureForProduction",
  "common",
  ], function(){
});

gulp.task("watchForDev", [
  "connect",
  ], function() {
    gulp.watch([
      "js/**",
      "!js/tmpl/**", // These are genterated, so don't watch!
      "css/**",
      "*.html",
    ], function(e) {
      console.log("watch saw: " + e.path + " " + e.type);
      gulp.run("dev");
    });
});

gulp.task('deploy', [
  // "dist"
  "configureForProduction",
], function() {
  return deploy({
      bucket: "pol.is"
  });
});

gulp.task('preprod', [
  // "dist"
  "configureForProduction",
], function() {
  return deploy({
      bucket: "preprod.pol.is"
  });
});

function deploy(params) {
    var creds = JSON.parse(fs.readFileSync('.polis_s3_creds_client.json'));
    creds = _.extend(creds, params);

    // Files without Gzip
    gulp.src([
      destRoot + '/**',
      '!' + destRoot + '/js/**',
      ], {read: false}).pipe(s3(creds, {
        delay: 1000,
        headers: {
          'x-amz-acl': 'public-read',
        }
      }));

    // Gzipped Files
    gulp.src([
      destRoot + '/**/js/**', // simply saying "/js/**" causes the 'js' prefix to be stripped, and the files end up in the root of the bucket.
      ], {read: false}).pipe(s3(creds, {
        delay: 1000,
        headers: {
          'x-amz-acl': 'public-read',
          'Content-Encoding': 'gzip',
        }
      }));

}

// For now, you'll have to copy the assets from the other repo into the "about" directory
gulp.task('deployAboutPage', [
  ], function() {

    var creds = JSON.parse(fs.readFileSync('.polis_s3_creds_client.json'));
    creds.bucket = "about.polis.io";

    var root = "../about-polis";
    gulp.src([
      root + "/index.html",
      root + "/**/bower_components/bootstrap/dist/css/bootstrap.css", // ** to preserve path
      root + "/**/node_modules/underscore/underscore-min.js", // ** to preserve path
      root + "/snowcity*.jpg",
      ], {read: false}).pipe(s3(creds, {
        delay: 1000,
        headers: {
          'x-amz-acl': 'public-read',
        }
      }));
});

gulp.task('default', [
  "dev",
  "watchForDev",
  ], function() {
});

<commit_msg>gulp updates<commit_after>var _ = require('underscore');
var gulp = require('gulp');
var s3 = require('gulp-s3');
var browserify = require('gulp-browserify');
var concat = require('gulp-concat');
var uglify = require('gulp-uglify')
var rename = require('gulp-rename');
var connect = require('gulp-connect');
var less = require('gulp-less');
var clean = require('gulp-clean');
var jshint = require('gulp-jshint');
var gzip = require('gulp-gzip');
var template = require('gulp-template');
var watch = require('gulp-watch');
var path = require('path');
var combineCSS = require('combine-css');
var gulpif = require('gulp-if');
var gutil = require('gulp-util');
var handlebars = require('gulp-handlebars');
// var styl = require('gulp-styl');
// var refresh = require('gulp-livereload');
// var lr = require('tiny-lr');
// var server = lr();
var header = require('gulp-header');
var hbsfy = require("hbsfy").configure({
  extensions: ["handlebars"]
});
var fs = require('fs');

var useJsHint = false;
var destRoot = __dirname + "/devel";
var devMode = true;

gulp.task('connect', connect.server({
  root: destRoot,
  port: 8000,
  // livereload: true,
  // open: {
  //   browser: 'chrome' // if not working OS X browser: 'Google Chrome'
  // }
}));

gulp.task('cleancss', function(){
  gulp.src(destRoot + '/css', {read: false})
      .pipe(clean())
})

gulp.task('less', function(){
  gulp.src([
    devMode ? "css/polis_main_devel.less" : "css/polis_main_dist.less",
    ])
      .pipe(less())
      .pipe(concat("polis.css"))
      .pipe(gulp.dest(destRoot + '/css'))
});

gulp.task('fontawesome', function() {
  gulp.src('bower_components/font-awesome/font/**/*')
    .pipe(gulp.dest(destRoot + "/font"));
});
// TODO remove
gulp.task('sparklines', function() {
  var s = gulp.src('sparklines.svg')
    .pipe(gulp.dest(destRoot));
});
gulp.task('index', [
  'sparklines',
], function() {
  var s = gulp.src('index.html');
  if (devMode) {
    s = s.pipe(template({
      basepath: '',
      d3Filename: 'd3.js',
      r2d3Filename: 'r2d3.js',
    }))
  } else {
    s = s.pipe(template({
      //basepath: 'https://s3.amazonaws.com/pol.is',
      basepath: '', // proxy through server (cached by cloudflare, and easier than choosing a bucket for preprod, etc)
      d3Filename: 'd3.min.js',
      r2d3Filename: 'r2d3.min.js',
    }));
  }
  return s.pipe(gulp.dest(destRoot));
});

gulp.task('templates', function(){
  gulp.src(['js/templates/*.hbs', 'js/templates/*.handlebars'])
    .pipe(handlebars({
      outputType: 'node',
      wrapped: true,
    }))
    .pipe(gulp.dest('js/tmpl'));
});

gulp.task('jshint', function(){
  gulp.src('js/**/*.js')
      .pipe(gulpif(useJsHint, jshint(

      {
         // reporter: 'jslint',
          curly: true, // require if,else blocks to have {}
          eqeqeq: true,
          trailing: true, // no trailing whitespace allowed
          // immed: true,
          // latedef: true,
          // newcap: true,
          // noarg: true,
          // sub: true,
          // undef: true,
        //  unused: true,
          quotmark: "double",
         // plusplus: true, // no ++ or --
        //  nonew: true,
          noarg: true, // no arguments.caller and arguments.callee (allow for optimizations)
          newcap: true, // constructors must be capitalized
        //  latedef: "nofunc",
         // indent: 2,
          immed: true,
//          forin: true, require hasOwnProperty checks
          boss: true,
//          debug: true, // uncomment temporarily when you want to allow debugger; statements.
          // browser: true,
          es3: true,
          globals: {
            d3: true,
            jQuery: true,
            console: true,
            require: true,
            define: true,
            requirejs: true,
            describe: true,
            expect: true,
            module: true,
            // it: true
          },
          // relax: eventually we should get rid of these
            //expr: true,
           // loopfunc: true,
            //shadow: true,
        }
        )))
      .pipe(jshint.reporter('default'))
})

gulp.task('scripts', ['templates', 'jshint'], function() {
  // Single entry point to browserify
  var s = gulp.src('js/main.js')
      .pipe(browserify({
        insertGlobals : true,
        debug : false, //!gulp.env.production
        // transform: ['hbsfy'],
        shim : {
          jquery: {
            path : devMode ? 'js/lib/jquery.js' : 'js/lib/jquery.min.js',
            exports: '$',
          },
          //TODO 'handlebars': 'templates/helpers/handlebarsWithHelpers', //this one has polis custom template helpers
          handlebars: {
            path : 'bower_components/handlebars/handlebars.runtime.js', //original handlebars
            exports: 'Handlebars',
          },
          originalbackbone: {
            path: 'bower_components/backbone/backbone', // backbone before modifications
            depends: { jquery: '$', underscore: '_' },
            exports: 'Backbone',
          },
          backbone: {
            path: 'js/net/backbonePolis', // polis-specific backbone modifications
            depends: { originalbackbone: "Backbone" },
            exports: "Backbone",
          },
          underscore: {
            path: 'bower_components/underscore/underscore',
            exports: '_',
          },
          thorax: {
            path: 'bower_components/thorax/thorax',
            depends: { handlebars: 'Handlebars', backbone: 'Backbone' },
            exports: 'Thorax',
          },
          bootstrap_alert: {  //all bootstrap files need to be added to the dependency array of js/main.js
            path: 'bower_components/bootstrap/js/alert',
            depends: { jquery: "jQuery" },
            exports: null,
          },
          bootstrap_tab: {
            path : 'bower_components/bootstrap/js/tab',
            depends: { jquery: "jQuery" },
            exports: null,
          },
          bootstrap_popover: {
            path: 'bower_components/bootstrap/js/popover',
            depends: { jquery: "jQuery" },
            exports: null,
          },
          bootstrap_collapse: {
            path: 'bower_components/bootstrap/js/collapse',
            depends: { jquery: "jQuery" },
            exports: null,
          },
          bootstrap_dropdown: {
            path: 'bower_components/bootstrap/js/dropdown',
            depends: { jquery: "jQuery" },
            exports: null,
          },
          bootstrap_affix: {
            path: 'bower_components/bootstrap/js/affix',
            depends: { jquery: "jQuery" },
            exports: null,
          },
          d3tooltips: {
            path: 'bower_components/d3-tip/index',
            depends: { jquery: "jQuery" },
            exports: null,
          },
          bootstrap_tooltip: {
            path: 'bower_components/bootstrap/js/tooltip',
            depends: { jquery: "jQuery" },
            exports: null,
          },
          bootstrap_button: {
            path: 'bower_components/bootstrap/js/button',
            depends: { jquery: "jQuery" },
            exports: null,
          },
          bootstrap_transition: {
            path: 'bower_components/bootstrap/js/transition',
            depends: { jquery: "jQuery" },
            exports: null,
          },
          owl: {
            path: 'bower_components/owlcarousel/owl-carousel/owl.carousel.min.js',
            depends: { jquery: "jQuery" },
            exports: null,
          },
          VisView: {
            path: 'js/lib/VisView',
            depends: { d3tooltips: 'foo' }, // added to d3 object as d3.tip
            exports: 'VisView',
          },
        },
      }))
      .pipe(concat('polis.js'))
  // TODO      .pipe(header("copyright Polis... (except that libs are mixed in)
      if (!devMode) {
        s = s
          .pipe(uglify())
          .pipe(gzip())
      }
      s = s.pipe(rename('polis.js'));
      return s.pipe(gulp.dest(destRoot + "/js"));
});

// for big infrequently changing scripts that we don't want to concatenate
// on each dev build.
gulp.task("scriptsOther", function() {

  var files = [];
  if (devMode) {
    files.push('bower_components/d3/d3.js');
    files.push('bower_components/r2d3/r2d3.js');
  } else {
    files.push('bower_components/d3/d3.min.js');
    files.push('bower_components/r2d3/r2d3.min.js');
  }
  var s = gulp.src(files);
  if (!devMode) {
    s = s
      .pipe(uglify())
      .pipe(gzip())
      .pipe(rename(function (path) {
        // path.dirname += "/ciao";
        // path.basename += "-goodbye";
        // path.extname = ".md"

        // remove .gz extension
        var ext = path.extname;
        path.extname = ext.substr(0, ext.length- ".gz".length);
      }));
  }
  return s.pipe(gulp.dest(destRoot + "/js"));
});

gulp.task("configureForProduction", function() {
  destRoot = "./dist";
  devMode = false;
});

gulp.task('common', [
  "scriptsOther",
  "scripts",
  "less",
  "fontawesome",
  "index",
  ], function() {
    // if (devMode) {
    //   connect.reload();
    // }
});

gulp.task('dev', [
  "common",
  ], function(){
});

gulp.task('dist', [
  "configureForProduction",
  "common",
  ], function(){
});

gulp.task("watchForDev", [
  "connect",
  ], function() {
    gulp.watch([
      "js/**",
      "!js/tmpl/**", // These are genterated, so don't watch!
      "css/**",
      "*.html",
    ], function(e) {
      console.log("watch saw: " + e.path + " " + e.type);
      gulp.run("dev");
    });
});

gulp.task('deploy', [
  // "dist"
  "configureForProduction",
], function() {
  return deploy({
      bucket: "pol.is"
  });
});

gulp.task('preprod', [
  // "dist"
  "configureForProduction",
], function() {
  return deploy({
      bucket: "preprod.pol.is"
  });
});

function deploy(params) {
    var creds = JSON.parse(fs.readFileSync('.polis_s3_creds_client.json'));
    creds = _.extend(creds, params);

    // Files without Gzip
    gulp.src([
      destRoot + '/**',
      '!' + destRoot + '/js/**',
      ], {read: false}).pipe(s3(creds, {
        delay: 1000,
        headers: {
          'x-amz-acl': 'public-read',
        }
      }));

    // Gzipped Files
    gulp.src([
      destRoot + '/**/js/**', // simply saying "/js/**" causes the 'js' prefix to be stripped, and the files end up in the root of the bucket.
      ], {read: false}).pipe(s3(creds, {
        delay: 1000,
        headers: {
          'x-amz-acl': 'public-read',
          'Content-Encoding': 'gzip',
        }
      }));

}

// For now, you'll have to copy the assets from the other repo into the "about" directory
gulp.task('deployAboutPage', [
  ], function() {

    var creds = JSON.parse(fs.readFileSync('.polis_s3_creds_client.json'));
    creds.bucket = "pol.is";

    var root = "../about-polis";
    gulp.src([
      root + "/lander.html",
      root + "/marketers.html",
      root + "/company.html",
      root + "/pricing.html",
      root + "/professors.html",
      root + "/d3.js",
      root + "/clusterforce.js",
      root + "/api.html",
      root + "/politics.html",
      root + "/about.css",
      root + "/**/rainbow/**/*",
      root + "/**/bower_components/bootstrap/dist/css/bootstrap.css", // ** to preserve path
      root + "/**/node_modules/underscore/underscore-min.js", // ** to preserve path
      root + "/**/landerImages/*",
      root + "/**/bower_components/font-awesome/css/font-awesome.min.css",
      root + "/**/bower_components/font-awesome/fonts/**",
      root + "/**/bower_components/jquery/jquery.js",
      root + "/**/bower_components/jquery/jquery.min.js"
      ], {read: false}).pipe(s3(creds, {
        delay: 1000,
        headers: {
          'x-amz-acl': 'public-read',
        }
      }));
});

gulp.task('default', [
  "dev",
  "watchForDev",
  ], function() {
});

<|endoftext|>


<commit_before>var rimraf  = require('rimraf');
var gulp    = require('gulp');
var jade    = require('gulp-jade');
var stylus  = require('gulp-stylus');
var copy    = require('gulp-copy');
var connect = require('gulp-connect');
var initialized = false;

/**
 * Default
 */

gulp.task('clean', function (cb) {

  if (!initialized) {
    rimraf('../public', function () {
      initialized = true;
      cb();
    });
  } else {
    cb();
  }

});

gulp.task('jade', ['clean'], function buildHTML() {
  return gulp.src(['./src/index.jade', './src/**/*.jade'])
    .pipe(jade())
    .pipe(gulp.dest('./public'))
    .pipe(connect.reload());
});

gulp.task('stylus', ['clean'], function buildCSS() {
  return gulp.src('./src/assets/css/index.styl')
    .pipe(stylus())
    .pipe(gulp.dest('./public/assets/css'))
    .pipe(connect.reload());
});

gulp.task('img', ['clean'], function copyImages() {
  return gulp.src(['./src/assets/img/*/*.png'])
    .pipe(copy('./public/assets/img', {
      prefix: 3
    }));
});

gulp.task('lib-js', ['clean'], function copyJSLibs() {
  return gulp.src([
    './src/assets/lib/angular/angular.js',
    './src/assets/lib/jquery/dist/jquery.js',
    './src/assets/lib/semantic/dist/semantic.js',
    './src/assets/lib/angular-ui-router/release/angular-ui-router.js'
  ])
    .pipe(copy('./public/assets/lib', {prefix: 100}));
});

gulp.task('lib-css', ['clean'], function copyCSSLibs() {
  return gulp.src([
    './src/assets/lib/semantic/dist/semantic.css'
  ])
    .pipe(copy('./public/assets/css', {prefix: 100}));
});

gulp.task('favicon', ['clean'], function copyFavicon() {
  return gulp.src([
    './src/favicon.ico'
  ])
    .pipe(copy('./public', {prefix: 100}));
});

gulp.task('js', ['clean'], function copyJS() {
  return gulp.src([
    './src/app/**/*.js'
  ])
    .pipe(copy('./public', {prefix: 1}))
    .pipe(connect.reload());
});

gulp.task('font', ['clean'], function copyFont() {
  return gulp.src([
    './src/assets/lib/font-awesome/**/*'
  ])
    .pipe(copy('./public', {prefix: 1}));
});

/**
 * Dev
 */

gulp.task('connect', function connectServer() {
  return connect.server({
    root: './public',
    livereload: true,
    port: 3100
  });
});

gulp.task('watch', function watchFiles() {
  gulp.watch('./src/app/**/*.js', ['js']);
  gulp.watch('./src/**/*.jade', ['jade']);
  gulp.watch('./src/assets/css/*.styl', ['stylus']);
});

gulp.task('default', ['clean', 'jade', 'stylus', 'img', 'lib-js', 'lib-css', 'favicon', 'js', 'font']);
gulp.task('dev', ['clean', 'jade', 'stylus', 'img', 'lib-js', 'lib-css', 'favicon', 'js', 'font', 'connect', 'watch']);<commit_msg>Updated image task to deal with .jpgs<commit_after>var rimraf  = require('rimraf');
var gulp    = require('gulp');
var jade    = require('gulp-jade');
var stylus  = require('gulp-stylus');
var copy    = require('gulp-copy');
var connect = require('gulp-connect');
var initialized = false;

/**
 * Default
 */

gulp.task('clean', function (cb) {

  if (!initialized) {
    rimraf('../public', function () {
      initialized = true;
      cb();
    });
  } else {
    cb();
  }

});

gulp.task('jade', ['clean'], function buildHTML() {
  return gulp.src(['./src/index.jade', './src/**/*.jade'])
    .pipe(jade())
    .pipe(gulp.dest('./public'))
    .pipe(connect.reload());
});

gulp.task('stylus', ['clean'], function buildCSS() {
  return gulp.src('./src/assets/css/index.styl')
    .pipe(stylus())
    .pipe(gulp.dest('./public/assets/css'))
    .pipe(connect.reload());
});

gulp.task('img', ['clean'], function copyImages() {
  return gulp.src(['./src/assets/img/*/*.png', './src/assets/img/*/*.jpg'])
    .pipe(copy('./public/assets/img', {
      prefix: 3
    }));
});

gulp.task('lib-js', ['clean'], function copyJSLibs() {
  return gulp.src([
    './src/assets/lib/angular/angular.js',
    './src/assets/lib/jquery/dist/jquery.js',
    './src/assets/lib/semantic/dist/semantic.js',
    './src/assets/lib/angular-ui-router/release/angular-ui-router.js'
  ])
    .pipe(copy('./public/assets/lib', {prefix: 100}));
});

gulp.task('lib-css', ['clean'], function copyCSSLibs() {
  return gulp.src([
    './src/assets/lib/semantic/dist/semantic.css'
  ])
    .pipe(copy('./public/assets/css', {prefix: 100}));
});

gulp.task('favicon', ['clean'], function copyFavicon() {
  return gulp.src([
    './src/favicon.ico'
  ])
    .pipe(copy('./public', {prefix: 100}));
});

gulp.task('js', ['clean'], function copyJS() {
  return gulp.src([
    './src/app/**/*.js'
  ])
    .pipe(copy('./public', {prefix: 1}))
    .pipe(connect.reload());
});

gulp.task('font', ['clean'], function copyFont() {
  return gulp.src([
    './src/assets/lib/font-awesome/**/*'
  ])
    .pipe(copy('./public', {prefix: 1}));
});

/**
 * Dev
 */

gulp.task('connect', function connectServer() {
  return connect.server({
    root: './public',
    livereload: true,
    port: 3100
  });
});

gulp.task('watch', function watchFiles() {
  gulp.watch('./src/app/**/*.js', ['js']);
  gulp.watch('./src/**/*.jade', ['jade']);
  gulp.watch('./src/assets/css/*.styl', ['stylus']);
});

gulp.task('default', ['clean', 'jade', 'stylus', 'img', 'lib-js', 'lib-css', 'favicon', 'js', 'font']);
gulp.task('dev', ['clean', 'jade', 'stylus', 'img', 'lib-js', 'lib-css', 'favicon', 'js', 'font', 'connect', 'watch']);<|endoftext|>


<commit_before>/**
 * 弹出层
 */
onkeydown(document, function (e) {
    if (e.which === 27 && rootElements.length) {
        history.back();
    }
});
var animationStyle = "opacity:0;transform:scale(1.2);transition:.1s opacity ease-out,.2s transform ease-out;";
var setInitialStyle = function (element) {
    if (!element.initialStyle) element.initialStyle = animationStyle;
};
var setPosition = function (element) {
    css(element, {
        marginLeft: fromOffset(-element.offsetWidth / 2),
        marginTop: fromOffset(-element.offsetHeight / 2),
        left: "50%",
        top: "50%"
    });
};
var windowFactory = function (window) {
    css(window, `min-height:10px;min-width:10px;position:absolute;background-color:#fff;`);
    return window;
};
var loadingFactory = function (element) {
    css(element, `position:absolute;background-color:#fff;`);
    return element;
}
/**
 * 弹出子窗口的函数
 * @param {string} path 窗口路径的唯一索引
 * @param {any} parameters 给窗口的作域预先赋值
 * @param {object} style 自定义样式，主要是width,height等位置参数
 * @returns {Element} 给调用弹窗的命令暴露的可选方法
 */
var popup = function (path) {
    if (isString(path)) {
        return popup_path.apply(null, arguments);
    }
    if (isNode(path)) {
        return popup_view.apply(null, arguments);
    }
    throw new Error(`path isn't valid:${path}`);
};
var popup_path = function (path = "", parameters, target) {
    if (!popup.go || !popup.prepare) throw new Error("当前环境无法使用");
    // 3 has mask has view control
    var element;
    if (/^#/.test(path)) {
        // mask
        path = path.replace(/^#/, "");
        var load = function () {
            remove(element && element.mask);
            element = popup.create(path, parameters);
            windowFactory(element);
            setInitialStyle(element);
            popup_with_mask(element, target);
        };
    }
    // 2 has view control has no mask
    else if (/^@/.test(path)) {
        path = path.replace(/^@/, "");
        var load = function () {
            element = popup.create(path, parameters);
            windowFactory(element);
            setInitialStyle(element);
            popup_as_single(element);
        };
    }
    // 1 has mask has no control
    else if (/^!/.test(path)) {
        path = path.replace(/^!/, "");
        var load = function () {
            element = popup.create(path, parameters);
            loadingFactory(element);
            setInitialStyle(element);
            popup_with_mask(element);
        };
    }
    // 0 has no mask no control
    else {
        var load = function () {
            element = popup.create(path, parameters);
            loadingFactory(element);
            setInitialStyle(element);
            popup_as_single(element);
        };
    }
    var fullfill = function () {
        remove(element);
        load();
        if (!element) throw new Error(`路径不存在:${path}`);
        element.style.opacity = 0;
        element.$reload = fullfill;
        if (element.parentNode) setPosition(element);
        else once('append')(element, function () {
            setPosition(element);
            element.style.opacity = 1;
        });
    };
    popup.prepare(path, fullfill);
    return element;
};

var popup_view = function (element, target) {
    if (isNode(target)) {
        if (target.isMask) {
            popup_with_mask(element, target);
            return element;
        }
        return popup_as_extra(element, target);
    }
    if (target instanceof Event) {
        popup_to_event(element, target);
    } else if (target instanceof Array) {
        popup_to_point(element, target);
    } else if (target) {
        popup_with_mask(element);
    } else {
        popup_as_single(element);
    }
    return element;
};

css(".mask", `position:absolute;position:fixed;left:0;right:0;bottom:0;top:0;width:auto;height:auto;background:#000;opacity:0.2;transform:scale(1);display:block`);
var createMask = function () {
    var mask = document.createElement("mask");
    mask.initialStyle = animationStyle;
    css(mask, `z-index:${zIndex()};`);
    mask.className = "mask";
    mask.isMask = true;
    return mask;
};
var popup_with_mask = function (element, mask = createMask()) {
    onremove(element, mask.clean);
    css(element, `z-index:${zIndex()};`);
    if (mask.parentNode) {
        global(element);
    }
    if (!element.with) {
        element.with = [mask];
    } else if (element.with instanceof Array) {
        if (!~element.with.indexOf(element)) element.with.push(mask);
    } else {
        if (element.with !== element) element.with = [element.with, mask];
    }
    if (!mask.clean) {
        mask.clean = new Cleanup(element.with);
    }
    if (!element.parentNode) global(element);
    return element;
};
var popup_as_extra = function (element, target) {
    var { offsetParent, nextSibling, previousSibling } = target;
    if (
        nextSibling
        && (
            nextSibling.offsetLeft - target.offsetLeft >= target.offsetWidth / 2
            || target.offsetLeft - nextSibling.offsetLeft >= nextSibling.offsetWidth / 2
        )
        || previousSibling
        && (
            previousSibling.offsetLeft - target.offsetLeft >= target.offsetWidth / 2
            || target.offsetLeft - previousSibling.offsetLeft >= previousSibling.offsetWidth / 2
        )
    ) {
        popup_as_yextra(global, element, target);
    } else if (offsetParent) {
        if (innerHeight - target.offsetHeight > innerWidth - target.offsetWidth && offsetParent.clientWidth !== target.offsetWidth) {
            popup_as_yextra(global, element, target);
        } else {
            popup_as_xextra(global, element, target);
        }
    } else if (/inline|cell/i.test(getComputedStyle(target).display)) {
        popup_as_yextra(global, element, target);
    } else {
        popup_as_xextra(global, element, target);
    }
};
var popup_as_yextra = function (global, element, target) {
    if (!element.origin) {
        element.origin = {
            height: element.style.height,
            width: element.style.width,
            minWidth: element.style.minWidth,
            display: element.style.display
        };
    }
    css(element, `position:absolute;z-index:${zIndex()}`);
    var release1 = onremove(target, function () {
        remove(element);
    });
    var release2 = onremove(element, function () {
        release1();
        release2();
        if (document.removeEventListener) {
            document.removeEventListener("scroll", reshape, true);
            document.removeEventListener("resize", reshape);
        }
    });
    global(element);
    var reshape = function () {
        extend(element.style, element.origin);
        var position = getScreenPosition(target);
        var viewrect = getScreenPosition(element.offsetParent);
        var maxHeight = Math.max(position.top, innerHeight - position.top - position.height);
        var maxWidth = Math.max(position.left + position.width, innerWidth - position.left);
        var height = element.offsetHeight;
        //如果高度超出可视区，调整高度
        if (height > maxHeight) {
            css(element, `height:${maxHeight}px;`);
        }
        css(element, `min-width:auto;`);
        var aimedWidth = element.offsetWidth;
        //如果宽度不足其附着元素的宽度
        if (aimedWidth < target.offsetWidth) {
            aimedWidth = target.offsetWidth;
        }

        //如果宽度超出可视区，调整宽度
        if (aimedWidth > maxWidth) {
            aimedWidth = maxWidth;
        }
        if (aimedWidth !== element.offsetWidth) {
            css(element, `width:${aimedWidth}px`);
        }
        if (position.top + element.offsetHeight + position.height > innerHeight) {
            css(element, `bottom:${viewrect.height - position.top + viewrect.top}px;top:auto;`);
        } else {
            css(element, `top:${position.top - viewrect.top + position.height}px;bottom:auto;`);
        }
        if (position.left + element.offsetWidth > innerWidth) {
            css(element, `right:${viewrect.width + viewrect.left - position.left - position.width}px;left:auto;`);
        } else {
            css(element, `left:${position.left - viewrect.left}px;right:auto;`);
        }
        var offsetParent = target.offsetParent;
        if (offsetParent) {
            if (overlap(position, offsetParent) > 0) {
                element.style.display = element.origin.display;
            } else {
                element.style.display = "none";
            };
        }

    }
    if (document.addEventListener) {
        document.addEventListener("scroll", reshape, true);
        document.addEventListener("resize", reshape);
    }
    reshape();

};
var popup_as_xextra = arriswise(popup_as_yextra, arguments);
var popup_as_single = function (element) {
    css(element, `z-index:${zIndex()};`);
    global(element);
};
var popup_to_point = function (element, [x, y]) {
    css(element, {
        position: 'absolute',
        left: fromPixel(x),
        top: fromPixel(y)
    });
    popup_as_single(element);
};
var popup_to_event = function (element, { clientX, clientY }) {
    css(element, {
        position: 'absolute',
        left: fromOffset(clientX),
        top: fromOffset(clientY)
    });
    popup_as_single(element);
};
var global = function (element) {
    once("remove")(element, cleanup);
    popup.global ? popup.global(element, true) : appendChild(document.body, element);
};
var cleanup = new Cleanup(rootElements);<commit_msg>支持指定弹出框的方向<commit_after>/**
 * 弹出层
 */
onkeydown(document, function (e) {
    if (e.which === 27 && rootElements.length) {
        history.back();
    }
});
var animationStyle = "opacity:0;transform:scale(1.2);transition:.1s opacity ease-out,.2s transform ease-out;";
var setInitialStyle = function (element) {
    if (!element.initialStyle) element.initialStyle = animationStyle;
};
var setPosition = function (element) {
    css(element, {
        marginLeft: fromOffset(-element.offsetWidth / 2),
        marginTop: fromOffset(-element.offsetHeight / 2),
        left: "50%",
        top: "50%"
    });
};
var windowFactory = function (window) {
    css(window, `min-height:10px;min-width:10px;position:absolute;background-color:#fff;`);
    return window;
};
var loadingFactory = function (element) {
    css(element, `position:absolute;background-color:#fff;`);
    return element;
}
/**
 * 弹出子窗口的函数
 * @param {string} path 窗口路径的唯一索引
 * @param {any} parameters 给窗口的作域预先赋值
 * @param {object} style 自定义样式，主要是width,height等位置参数
 * @returns {Element} 给调用弹窗的命令暴露的可选方法
 */
var popup = function (path) {
    if (isString(path)) {
        return popup_path.apply(null, arguments);
    }
    if (isNode(path)) {
        return popup_view.apply(null, arguments);
    }
    throw new Error(`path isn't valid:${path}`);
};
var popup_path = function (path = "", parameters, target) {
    if (!popup.go || !popup.prepare) throw new Error("当前环境无法使用");
    // 3 has mask has view control
    var element;
    if (/^#/.test(path)) {
        // mask
        path = path.replace(/^#/, "");
        var load = function () {
            remove(element && element.mask);
            element = popup.create(path, parameters);
            windowFactory(element);
            setInitialStyle(element);
            popup_with_mask(element, target);
        };
    }
    // 2 has view control has no mask
    else if (/^@/.test(path)) {
        path = path.replace(/^@/, "");
        var load = function () {
            element = popup.create(path, parameters);
            windowFactory(element);
            setInitialStyle(element);
            popup_as_single(element);
        };
    }
    // 1 has mask has no control
    else if (/^!/.test(path)) {
        path = path.replace(/^!/, "");
        var load = function () {
            element = popup.create(path, parameters);
            loadingFactory(element);
            setInitialStyle(element);
            popup_with_mask(element);
        };
    }
    // 0 has no mask no control
    else {
        var load = function () {
            element = popup.create(path, parameters);
            loadingFactory(element);
            setInitialStyle(element);
            popup_as_single(element);
        };
    }
    var fullfill = function () {
        remove(element);
        load();
        if (!element) throw new Error(`路径不存在:${path}`);
        element.style.opacity = 0;
        element.$reload = fullfill;
        if (element.parentNode) setPosition(element);
        else once('append')(element, function () {
            setPosition(element);
            element.style.opacity = 1;
        });
    };
    popup.prepare(path, fullfill);
    return element;
};

var popup_view = function (element, target, style) {
    if (isNode(target)) {
        if (target.isMask) {
            popup_with_mask(element, target);
            return element;
        }
        return popup_as_extra(element, target, style);
    }
    if (target instanceof Event) {
        popup_to_event(element, target);
    } else if (target instanceof Array) {
        popup_to_point(element, target);
    } else if (target) {
        popup_with_mask(element);
    } else {
        popup_as_single(element);
    }
    return element;
};

css(".mask", `position:absolute;position:fixed;left:0;right:0;bottom:0;top:0;width:auto;height:auto;background:#000;opacity:0.2;transform:scale(1);display:block`);
var createMask = function () {
    var mask = document.createElement("mask");
    mask.initialStyle = animationStyle;
    css(mask, `z-index:${zIndex()};`);
    mask.className = "mask";
    mask.isMask = true;
    return mask;
};
var popup_with_mask = function (element, mask = createMask()) {
    onremove(element, mask.clean);
    css(element, `z-index:${zIndex()};`);
    if (mask.parentNode) {
        global(element);
    }
    if (!element.with) {
        element.with = [mask];
    } else if (element.with instanceof Array) {
        if (!~element.with.indexOf(element)) element.with.push(mask);
    } else {
        if (element.with !== element) element.with = [element.with, mask];
    }
    if (!mask.clean) {
        mask.clean = new Cleanup(element.with);
    }
    if (!element.parentNode) global(element);
    return element;
};
var popup_as_extra = function (element, target, style) {
    if (style) {
        if (/^[vy]/i.test(style)) {
            popup_as_yextra(global, element, target);
        } else {
            popup_as_xextra(global, element, target);
        }
        return;
    }
    var { offsetParent, nextSibling, previousSibling } = target;
    if (
        nextSibling
        && (
            nextSibling.offsetLeft - target.offsetLeft >= target.offsetWidth / 2
            || target.offsetLeft - nextSibling.offsetLeft >= nextSibling.offsetWidth / 2
        )
        || previousSibling
        && (
            previousSibling.offsetLeft - target.offsetLeft >= target.offsetWidth / 2
            || target.offsetLeft - previousSibling.offsetLeft >= previousSibling.offsetWidth / 2
        )
    ) {
        popup_as_yextra(global, element, target);
    } else if (offsetParent) {
        if (innerHeight - target.offsetHeight > innerWidth - target.offsetWidth && offsetParent.clientWidth !== target.offsetWidth) {
            popup_as_yextra(global, element, target);
        } else {
            popup_as_xextra(global, element, target);
        }
    } else if (/inline|cell/i.test(getComputedStyle(target).display)) {
        popup_as_yextra(global, element, target);
    } else {
        popup_as_xextra(global, element, target);
    }
};
var popup_as_yextra = function (global, element, target) {
    if (!element.origin) {
        element.origin = {
            height: element.style.height,
            width: element.style.width,
            minWidth: element.style.minWidth,
            display: element.style.display
        };
    }
    css(element, `position:absolute;z-index:${zIndex()}`);
    var release1 = onremove(target, function () {
        remove(element);
    });
    var release2 = onremove(element, function () {
        release1();
        release2();
        if (document.removeEventListener) {
            document.removeEventListener("scroll", reshape, true);
            document.removeEventListener("resize", reshape);
        }
    });
    global(element);
    var reshape = function () {
        extend(element.style, element.origin);
        var position = getScreenPosition(target);
        var viewrect = getScreenPosition(element.offsetParent);
        var maxHeight = Math.max(position.top, innerHeight - position.top - position.height);
        var maxWidth = Math.max(position.left + position.width, innerWidth - position.left);
        var height = element.offsetHeight;
        //如果高度超出可视区，调整高度
        if (height > maxHeight) {
            css(element, `height:${maxHeight}px;`);
        }
        css(element, `min-width:auto;`);
        var aimedWidth = element.offsetWidth;
        //如果宽度不足其附着元素的宽度
        if (aimedWidth < target.offsetWidth) {
            aimedWidth = target.offsetWidth;
        }

        //如果宽度超出可视区，调整宽度
        if (aimedWidth > maxWidth) {
            aimedWidth = maxWidth;
        }
        if (aimedWidth !== element.offsetWidth) {
            css(element, `width:${aimedWidth}px`);
        }
        if (position.top + element.offsetHeight + position.height > innerHeight) {
            css(element, `bottom:${viewrect.height - position.top + viewrect.top}px;top:auto;`);
        } else {
            css(element, `top:${position.top - viewrect.top + position.height}px;bottom:auto;`);
        }
        if (position.left + element.offsetWidth > innerWidth) {
            css(element, `right:${viewrect.width + viewrect.left - position.left - position.width}px;left:auto;`);
        } else {
            css(element, `left:${position.left - viewrect.left}px;right:auto;`);
        }
        var offsetParent = target.offsetParent;
        if (offsetParent) {
            if (overlap(position, offsetParent) > 0) {
                element.style.display = element.origin.display;
            } else {
                element.style.display = "none";
            };
        }

    }
    if (document.addEventListener) {
        document.addEventListener("scroll", reshape, true);
        document.addEventListener("resize", reshape);
    }
    reshape();

};
var popup_as_xextra = arriswise(popup_as_yextra, arguments);
var popup_as_single = function (element) {
    css(element, `z-index:${zIndex()};`);
    global(element);
};
var popup_to_point = function (element, [x, y]) {
    css(element, {
        position: 'absolute',
        left: fromPixel(x),
        top: fromPixel(y)
    });
    popup_as_single(element);
};
var popup_to_event = function (element, { clientX, clientY }) {
    css(element, {
        position: 'absolute',
        left: fromOffset(clientX),
        top: fromOffset(clientY)
    });
    popup_as_single(element);
};
var global = function (element) {
    once("remove")(element, cleanup);
    popup.global ? popup.global(element, true) : appendChild(document.body, element);
};
var cleanup = new Cleanup(rootElements);<|endoftext|>


<commit_before>/* global analytics */
/* eslint no-console:0, no-unused-vars:0, no-extra-parens:0 */

'use strict';

var integration = require('analytics.js-integration');
var request = require('visionmedia/superagent');
var prefix = require('johntron/superagent-prefix');
var async = require('caolan/async');

/**
 * Expose `Astronomer` integration.
 */

window._astq = window._astq || [];

var Astronomer = module.exports = exports = integration('astronomer')
  .global('_astronomer')
  .global('_astq')
  .option('appId', null)
  .option('credentialServer', 'https://app.astronomer.io:443')
  .option('trackAllPages', false)
  .option('trackNamedPages', true)
  .option('trackCategorizedPages', true)
  .tag('library', '<script src="https://sdk.amazonaws.com/js/aws-sdk-2.1.33.min.js">');

/**
 * Initialize astronomer.
 *
 * @param {Facade} page
 */

Astronomer.prototype.initialize = function() {
  var self = this;
  window._astronomer = {};

  async.waterfall([
    function load(callback) {
      self.load('library', callback);
    },
    self.auth
  ], function(err, results) {
    console.log(err, results);
  });
};

Astronomer.prototype.auth = function(callback) {
  console.log('Authenticating with ' + this.options.credentialServer);
  request
    .get('/api/v1/applications/credentials/' + self.options.appId)
    .use(prefix(this.options.credentialServer))
    .end(callback);
};

Astronomer.prototype.configAws = function(config) {
  window._astronomer.config = config;
  window._astronomer.kinesis = new window.AWS.Kinesis({
    region: window._astronomer.config.region,
    credentials: new window.AWS.WebIdentityCredentials({
      RoleArn: window._astronomer.config.roleArn,
      WebIdentityToken: window._astronomer.config.credentials.Token
    })
  });
};

Astronomer.prototype.dequeue = function() {
  while (window._astq.length > 0) {
    var item = window._astq.shift();
    var method = item.shift();
    if (analytics[method]) analytics[method].apply(analytics, item);
  }
};

/**
 * Has the astronomer library been loaded yet?
 *
 * @return {Boolean}
 */

Astronomer.prototype.loaded = function() {
  return !!((((window.AWS) || {}).config || {}).credentials || {}).accessKeyId;
};
/**
 * Trigger a page view.
 *
 * @param {Facade} identify
 */

Astronomer.prototype.page = function(page) {
  var category = page.category();
  var props = page.properties();
  var name = page.fullName();
  var opts = this.options;

  // all pages
  if (opts.trackAllPages) {
    this.track(page.track());
  }

  // named pages
  if (name && opts.trackNamedPages) {
    this.track(page.track(name));
  }

  // categorized pages
  // if (category && opts.trackCategorizedPages) {
  //   this.track(page.track(category));
  // }
};

/**
 * Identify a user.
 *
 * @param {Facade} identify
 */

Astronomer.prototype.identify = function(identify) {
  var id = identify.userId();
  var traits = identify.traits();
  window._astronomer.userId = id;
  window._astronomer.userProperties = traits;
};

/**
 * Associate the current user with a group of users.
 *
 * @param {Facade} group
 */

Astronomer.prototype.group = function(group) {
  var id = group.groupId();
  var traits = group.traits();
  window._astronomer.groupId = id;
  window._astronomer.groupProperties = traits;
};

/**
 * Track an event.
 *
 * @param {Facade} track
 */

Astronomer.prototype.track = function(track) {
  var record = JSON.stringify({
    event: track.event(),
    properties: track.properties(),
    userId: window._astronomer.userId,
    anonymousId: analytics.user().anonymousId(),
    traits: window._astronomer.userProperties
  });

  var params = {
    Data: record,
    StreamName: window._astronomer.config.streamName,
    PartitionKey: this.options.appId
  };

  window._astronomer.kinesis.putRecord(params, function(error, data) {
    if (error) {
      console.error(error);
    }
  });
};
<commit_msg>SAVEPOINT<commit_after>/* global analytics */
/* eslint no-console:0, no-unused-vars:0, no-extra-parens:0 */

'use strict';

var integration = require('analytics.js-integration');
var request = require('visionmedia/superagent');
var prefix = require('johntron/superagent-prefix');
var async = require('caolan/async');

/**
 * Expose `Astronomer` integration.
 */

window._astq = window._astq || [];

var Astronomer = module.exports = exports = integration('astronomer')
  .global('_astronomer')
  .global('_astq')
  .option('appId', null)
  .option('credentialServer', 'https://app.astronomer.io:443')
  .option('trackAllPages', false)
  .option('trackNamedPages', true)
  .option('trackCategorizedPages', true)
  .tag('library', '<script src="https://sdk.amazonaws.com/js/aws-sdk-2.1.33.min.js">');

/**
 * Initialize astronomer.
 *
 * @param {Facade} page
 */

Astronomer.prototype.initialize = function() {
  var self = this;
  window._astronomer = {};

  async.waterfall([
    function load(callback) {
      self.load('library', callback);
    },
    self.auth
  ], function(err, results) {
    console.log(err, results);
  });
};

Astronomer.prototype.auth = function(callback) {
  console.log('Authenticating with ' + this.options.credentialServer);
  request
    .get('/api/v1/applications/credentials/' + this.options.appId)
    .use(prefix(this.options.credentialServer))
    .end(callback);
};

Astronomer.prototype.configAws = function(config) {
  window._astronomer.config = config;
  window._astronomer.kinesis = new window.AWS.Kinesis({
    region: window._astronomer.config.region,
    credentials: new window.AWS.WebIdentityCredentials({
      RoleArn: window._astronomer.config.roleArn,
      WebIdentityToken: window._astronomer.config.credentials.Token
    })
  });
};

Astronomer.prototype.dequeue = function() {
  while (window._astq.length > 0) {
    var item = window._astq.shift();
    var method = item.shift();
    if (analytics[method]) analytics[method].apply(analytics, item);
  }
};

/**
 * Has the astronomer library been loaded yet?
 *
 * @return {Boolean}
 */

Astronomer.prototype.loaded = function() {
  return !!((((window.AWS) || {}).config || {}).credentials || {}).accessKeyId;
};
/**
 * Trigger a page view.
 *
 * @param {Facade} identify
 */

Astronomer.prototype.page = function(page) {
  var category = page.category();
  var props = page.properties();
  var name = page.fullName();
  var opts = this.options;

  // all pages
  if (opts.trackAllPages) {
    this.track(page.track());
  }

  // named pages
  if (name && opts.trackNamedPages) {
    this.track(page.track(name));
  }

  // categorized pages
  // if (category && opts.trackCategorizedPages) {
  //   this.track(page.track(category));
  // }
};

/**
 * Identify a user.
 *
 * @param {Facade} identify
 */

Astronomer.prototype.identify = function(identify) {
  var id = identify.userId();
  var traits = identify.traits();
  window._astronomer.userId = id;
  window._astronomer.userProperties = traits;
};

/**
 * Associate the current user with a group of users.
 *
 * @param {Facade} group
 */

Astronomer.prototype.group = function(group) {
  var id = group.groupId();
  var traits = group.traits();
  window._astronomer.groupId = id;
  window._astronomer.groupProperties = traits;
};

/**
 * Track an event.
 *
 * @param {Facade} track
 */

Astronomer.prototype.track = function(track) {
  var record = JSON.stringify({
    event: track.event(),
    properties: track.properties(),
    userId: window._astronomer.userId,
    anonymousId: analytics.user().anonymousId(),
    traits: window._astronomer.userProperties
  });

  var params = {
    Data: record,
    StreamName: window._astronomer.config.streamName,
    PartitionKey: this.options.appId
  };

  window._astronomer.kinesis.putRecord(params, function(error, data) {
    if (error) {
      console.error(error);
    }
  });
};
<|endoftext|>


<commit_before>const Promise = require( 'promise' );

module.exports = function( app ) {
  const
    Model = app.models.speaker,
    speaker = require( '../lib/mongoose' )( Model );

  function create( req, res ) {
    const doc = req.body;

    Promise.resolve( doc )
      .then( validateName )
      .then( save )
      .then( _speaker => res.status( 200 ).json( _speaker._doc ) )
      .catch( error => res.status( 500 ).send( { message: error.message, stack: error.stack } ) );

    function validateName( _doc ) {
      if ( !_doc.name ) {
        throw new ReferenceError( 'A propriedade name é obrigatória' );
      }

      return _doc;
    }

    function save( _doc ) {
      return speaker.save( _doc );
    }
  }

  function list( req, res ) {

    Promise.resolve()
      .then( query )
      .then( _speakers => res.status( 200 ).json( _speakers ) )
      .catch( error => res.status( 500 ).send( { message: error.message, stack: error.stack } ) );

    function query() {
      return speaker.query();
    }
  }

  function update( req, res ) {
    const doc = req.body;

    Promise.resolve( doc )
      .then( validateId )
      .then( updateDate )
      .then( setNewData )
      .then( status => res.status( 200 ).json( status ) )
      .catch( error => res.status( 500 ).send( { message: error.message, stack: error.stack } ) )

    function validateId( _doc ) {
      if ( !_doc._id ) {
        throw new Error( 'A propriedade _id é obrigatória' );
      }
      return _doc;
    }

    function updateDate( _doc ) {
      _doc.lastUpdate = Date.now();
      return _doc;
    }

    function setNewData( _doc ) {
      return speaker.update( { _id: _doc._id }, _doc );
    }
  }

  function disable( req, res ) {
    const speakerId = req.body._id;

    Promise.resolve( speakerId )
      .then( validateId )
      .then( logicalRemove )
      .then( status => res.status( 200 ).json( status ) )
      .catch( error => res.status( 500 ).send( { message: error.message, stack: error.stack } ) );

    function validateId( _speakerId ) {
      if ( typeof _speakerId !== 'string' || _speakerId.length < 24 ) {
        throw new Error( 'A propriedade _id é inválida' );
      }

      return _speakerId;
    }

    function logicalRemove( _speakerId ) {
      return speaker.logicalRemove( { _id: speakerId } );
    }

  }

  function findOne( req, res ) {
    const speakerId = req.params._id;

    Promise.resolve( speakerId )
      .then( validateId )
      .then( find )
      .then( _speaker => res.status( 200 ).json( _speaker ) )
      .catch( error => res.status( 500 ).send( { message: error.message, stack: error.stack } ) );

    function validateId( _speakerId ) {
      if ( typeof _speakerId !== 'string' || _speakerId.length < 24 ) {
        throw new Error( 'A propriedade _id é inválida' );
      }

      return _speakerId;
    }

    function find( _speakerId ) {
      return speaker.get( { _id: _speakerId } );
    }

  }

  return {
    create,
    list,
    findOne,
    update,
    disable
  };
};<commit_msg>[UPDATE]: função logicalRemove agora acessa a propriedade _speakerId local.<commit_after>const Promise = require( 'promise' );

module.exports = function( app ) {
  const
    Model = app.models.speaker,
    speaker = require( '../lib/mongoose' )( Model );

  function create( req, res ) {
    const doc = req.body;

    Promise.resolve( doc )
      .then( validateName )
      .then( save )
      .then( _speaker => res.status( 200 ).json( _speaker._doc ) )
      .catch( error => res.status( 500 ).send( { message: error.message, stack: error.stack } ) );

    function validateName( _doc ) {
      if ( !_doc.name ) {
        throw new ReferenceError( 'A propriedade name é obrigatória' );
      }

      return _doc;
    }

    function save( _doc ) {
      return speaker.save( _doc );
    }
  }

  function list( req, res ) {

    Promise.resolve()
      .then( query )
      .then( _speakers => res.status( 200 ).json( _speakers ) )
      .catch( error => res.status( 500 ).send( { message: error.message, stack: error.stack } ) );

    function query() {
      return speaker.query();
    }
  }

  function update( req, res ) {
    const doc = req.body;

    Promise.resolve( doc )
      .then( validateId )
      .then( updateDate )
      .then( setNewData )
      .then( status => res.status( 200 ).json( status ) )
      .catch( error => res.status( 500 ).send( { message: error.message, stack: error.stack } ) );

    function validateId( _doc ) {
      if ( !_doc._id ) {
        throw new Error( 'A propriedade _id é obrigatória' );
      }
      return _doc;
    }

    function updateDate( _doc ) {
      _doc.lastUpdate = Date.now();
      return _doc;
    }

    function setNewData( _doc ) {
      return speaker.update( { _id: _doc._id }, _doc );
    }
  }

  function disable( req, res ) {
    const speakerId = req.body._id;

    Promise.resolve( speakerId )
      .then( validateId )
      .then( logicalRemove )
      .then( status => res.status( 200 ).json( status ) )
      .catch( error => res.status( 500 ).send( { message: error.message, stack: error.stack } ) );

    function validateId( _speakerId ) {
      if ( typeof _speakerId !== 'string' || _speakerId.length < 24 ) {
        throw new Error( 'A propriedade _id é inválida' );
      }

      return _speakerId;
    }

    function logicalRemove( _speakerId ) {
      return speaker.logicalRemove( { _id: _speakerId } );
    }

  }

  function findOne( req, res ) {
    const speakerId = req.params._id;

    Promise.resolve( speakerId )
      .then( validateId )
      .then( find )
      .then( _speaker => res.status( 200 ).json( _speaker ) )
      .catch( error => res.status( 500 ).send( { message: error.message, stack: error.stack } ) );

    function validateId( _speakerId ) {
      if ( typeof _speakerId !== 'string' || _speakerId.length < 24 ) {
        throw new Error( 'A propriedade _id é inválida' );
      }

      return _speakerId;
    }

    function find( _speakerId ) {
      return speaker.get( { _id: _speakerId } );
    }

  }

  return {
    create,
    list,
    findOne,
    update,
    disable
  };
};<|endoftext|>


<commit_before>/*jshint esnext:true*/

import {mix} from 'js/oop';
import EventTarget from 'js/eventTarget';

// region Attribute
function Attribute () {}

Attribute.INVALID = {};

Attribute.CONFIG_KEYS = ['value', 'validator', 'getter', 'setter'];

Attribute.prototype = {
	constructor: Attribute,

	init: function (config) {
		this._attributes = {};

		this._initAttributes(config);
	},

	/**
	 * Config can have value, validator, getters, setter
	 *
	 * @param {String} name
	 * @param {Object} [config]
	 */
	addAttribute: function (name, config) {
		if (this.hasAttribute(name)) {
			throw new Error(`Attribute "${name}" has already been added`);
		}

		// sanitize config
		let cfg = {};
		if (config && Object.keys(config).length) {
			Attribute.CONFIG_KEYS.forEach(key => {
				if (config.hasOwnProperty(key)) {
					cfg[key] = config[key];				// this clones the config, which is important, because we don't want to set the reference
				}
			});
		}

		this._attributes[name] = cfg;
	},

	/**
	 *
	 * @param {String} name
	 * @returns {boolean}
	 */
	hasAttribute: function (name) {
		return this._attributes.hasOwnProperty(name);
	},

	_initAttributes: function (values) {
		let attrConfigs = this._mergeAttrConfigs(this.constructor);

		Object.keys(attrConfigs).forEach(name => {
			this.addAttribute(name, attrConfigs[name]);

			if (values && values.hasOwnProperty(name)) {
				this.set(name, values[name]);
			}
		});
	},

	/**
	 * @param	{Function} constructor
	 * @param	{Function} [constructor.superclass]
	 * @param	{Object} [constructor.ATTRS]
	 * @param	{Function[]} [constructor.__mix]
	 * @returns {Object}
	 * @private
	 */
	_mergeAttrConfigs: function (constructor) {
		let attrs = {};

		// add super class chain ATTRs first (top down recursion)
		let superClass = Object.getPrototypeOf(constructor);
		if (superClass !== Function.prototype) {	// constructor is base constructor
			attrs = this._mergeAttrConfigs(superClass);
		}

		// add this class's ATTRs
		if (constructor.ATTRS) {
			Object.assign(attrs, constructor.ATTRS);
		}

		// add mixin ATTRs
		if (constructor.hasOwnProperty('__mixins')) {
			constructor.__mixins.forEach(mix => {
				Object.assign(attrs, this._mergeAttrConfigs(mix));
			});
		}

		return attrs;
	},

	/**
	 *
	 * @param {String} name
	 * @param {*} value
	 * @returns {SimpleAttribute}
	 */
	set: function (name, value) {
		this._set(name, value);
		return this;
	},

	_set: function (name, value) {
		let attrConfig = this._attributes[name],
			current = this.get(name),	// will throw Error if attr doesn't exist, which if fine!
			okToSet = true;

		// call validator / setter
		if (attrConfig.validator) {
			okToSet = attrConfig.validator(value, name, this) !== false;
		}

		if (okToSet && attrConfig.setter) {
			value = attrConfig.setter(value, name);
			if (value === Attribute.INVALID) {
				okToSet = false;
			}
		}

		// check if value has actually changed
		if (value === current) {
			okToSet = false;
		}

		if (okToSet) {
			this._attributes[name].value = value;
		}
		return okToSet;
	},

	/**
	 *
	 * @param {String} name
	 * @returns {*}
	 */
	get: function (name) {
		if (!this.hasAttribute(name)) {
			throw new Error(`Attribute "${name}" has not been added`);
		}

		let attrConfig = this._attributes[name],
			value = this._attributes[name].value;

		if (attrConfig.getter) {
			value = attrConfig.getter(value, name);
		}
		return value;
	}
};
// endregion

// region AttributeObservable
class AttributeObservable {
	constructor (config) {
		EventTarget.prototype.init.call(this, config);
		Attribute.prototype.init.call(this, config);
	}

	_set (name, value) {
		let data = {
				prevVal:	this.get(name),
				newVal:		value,
				attrName:	name
			};

		let e = this._eventDispatch.createEvent(
			name + 'Change', true, data
		);

		let success = this._eventDispatch.dispatch(e);

		if (success) {
			value = e.newVal;		// allow on() listeners to change the new value

			success = Attribute.prototype._set.call(this, name, value);

			if (success) {		// attribute value was changed
				data.newVal = this.get(name);		// update newVal (post-setter)
				success = this._eventDispatch.dispatch('AFTER:' + name + 'Change', false, data);
			}
		}

		return success;
	}
}

mix(AttributeObservable, EventTarget, Attribute);
// endregion

export {Attribute, AttributeObservable};
<commit_msg>Made Attribute._mergeAttrConfigs static<commit_after>/*jshint esnext:true*/

import {mix} from 'js/oop';
import EventTarget from 'js/eventTarget';

// region Attribute
function Attribute () {}

Attribute.INVALID = {};

Attribute.CONFIG_KEYS = ['value', 'validator', 'getter', 'setter'];

Attribute._mergeAttrConfigs = function (constructor) {
	let attrs = {};

	// add super class chain ATTRs first (top down recursion)
	let superClass = Object.getPrototypeOf(constructor);
	if (superClass !== Function.prototype) {	// constructor is base constructor
		attrs = Attribute._mergeAttrConfigs(superClass);
	}

	// add this class's ATTRs
	if (constructor.ATTRS) {
		Object.assign(attrs, constructor.ATTRS);
	}

	// add mixin ATTRs
	if (constructor.hasOwnProperty('__mixins')) {
		constructor.__mixins.forEach(mix => {
			Object.assign(attrs, Attribute._mergeAttrConfigs(mix));
		});
	}

	return attrs;
};

Attribute.prototype = {
	constructor: Attribute,

	init: function (config) {
		this._attributes = {};

		this._initAttributes(config);
	},

	/**
	 * Config can have value, validator, getters, setter
	 *
	 * @param {String} name
	 * @param {Object} [config]
	 */
	addAttribute: function (name, config) {
		if (this.hasAttribute(name)) {
			throw new Error(`Attribute "${name}" has already been added`);
		}

		// sanitize config
		let cfg = {};
		if (config && Object.keys(config).length) {
			Attribute.CONFIG_KEYS.forEach(key => {
				if (config.hasOwnProperty(key)) {
					cfg[key] = config[key];				// this clones the config, which is important, because we don't want to set the reference
				}
			});
		}

		this._attributes[name] = cfg;
	},

	/**
	 *
	 * @param {String} name
	 * @returns {boolean}
	 */
	hasAttribute: function (name) {
		return this._attributes.hasOwnProperty(name);
	},

	_initAttributes: function (values) {
		let attrConfigs = Attribute._mergeAttrConfigs(this.constructor);

		Object.keys(attrConfigs).forEach(name => {
			this.addAttribute(name, attrConfigs[name]);

			if (values && values.hasOwnProperty(name)) {
				this.set(name, values[name]);
			}
		});
	},

	/**
	 *
	 * @param {String} name
	 * @param {*} value
	 * @returns {SimpleAttribute}
	 */
	set: function (name, value) {
		this._set(name, value);
		return this;
	},

	_set: function (name, value) {
		let attrConfig = this._attributes[name],
			current = this.get(name),	// will throw Error if attr doesn't exist, which if fine!
			okToSet = true;

		// call validator / setter
		if (attrConfig.validator) {
			okToSet = attrConfig.validator(value, name, this) !== false;
		}

		if (okToSet && attrConfig.setter) {
			value = attrConfig.setter(value, name);
			if (value === Attribute.INVALID) {
				okToSet = false;
			}
		}

		// check if value has actually changed
		if (value === current) {
			okToSet = false;
		}

		if (okToSet) {
			this._attributes[name].value = value;
		}
		return okToSet;
	},

	/**
	 *
	 * @param {String} name
	 * @returns {*}
	 */
	get: function (name) {
		if (!this.hasAttribute(name)) {
			throw new Error(`Attribute "${name}" has not been added`);
		}

		let attrConfig = this._attributes[name],
			value = this._attributes[name].value;

		if (attrConfig.getter) {
			value = attrConfig.getter(value, name);
		}
		return value;
	}
};
// endregion

// region AttributeObservable
class AttributeObservable {
	constructor (config) {
		EventTarget.prototype.init.call(this, config);
		Attribute.prototype.init.call(this, config);
	}

	_set (name, value) {
		let data = {
				prevVal:	this.get(name),
				newVal:		value,
				attrName:	name
			};

		let e = this._eventDispatch.createEvent(
			name + 'Change', true, data
		);

		let success = this._eventDispatch.dispatch(e);

		if (success) {
			value = e.newVal;		// allow on() listeners to change the new value

			success = Attribute.prototype._set.call(this, name, value);

			if (success) {		// attribute value was changed
				data.newVal = this.get(name);		// update newVal (post-setter)
				success = this._eventDispatch.dispatch('AFTER:' + name + 'Change', false, data);
			}
		}

		return success;
	}
}

mix(AttributeObservable, EventTarget, Attribute);
// endregion

export {Attribute, AttributeObservable};
<|endoftext|>


<commit_before>var gulp    = require('gulp'),
  less      = require('gulp-less'),
  usemin    = require('gulp-usemin'),
  wrap      = require('gulp-wrap');

var paths = {
  js: 'src/js/**/*.*',
  fonts: 'src/fonts/**.*',
  images: 'src/img/**/*.*',
  styles: 'src/less/**/*.less',
  index: 'src/index.html',
  bower_fonts: 'src/bower_components/**/*.{ttf,woff,eof,svg}',
  bower_components: 'src/bower_components/**/*.*'
};

gulp.task('usemin', function() {
  return gulp.src(paths.index)
    .pipe(usemin({
      less: [less(), 'concat'],
      js: ['concat', wrap('(function(){ \n<%= contents %>\n})();')],
    }))
    .pipe(gulp.dest('dist/'));
});

/**
 * Copy assets
 */
gulp.task('copy-assets', ['copy-images', 'copy-fonts', 'copy-bower_fonts']);

gulp.task('copy-images', function(){
  return gulp.src(paths.images)
    .pipe(gulp.dest('dist/img'));
});

gulp.task('copy-fonts', function(){
  return gulp.src(paths.fonts)
    .pipe(gulp.dest('dist/fonts'));
});

gulp.task('copy-bower_fonts', function(){
  return gulp.src(paths.bower_fonts)
    .pipe(gulp.dest('dist/lib'));
});

/**
 * Compile less
 */
gulp.task('compile-less', function(){
  return gulp.src(paths.styles)
      .pipe(less())
      .pipe(gulp.dest('dist/css'));
});

gulp.task('build', ['usemin', 'copy-assets']);
gulp.task('default', ['build']);
<commit_msg>add gulp watch<commit_after>var gulp    = require('gulp'),
  less      = require('gulp-less'),
  usemin    = require('gulp-usemin'),
  wrap      = require('gulp-wrap');

var paths = {
  js: 'src/js/**/*.*',
  fonts: 'src/fonts/**.*',
  images: 'src/img/**/*.*',
  styles: 'src/less/**/*.less',
  index: 'src/index.html',
  bower_fonts: 'src/bower_components/**/*.{ttf,woff,eof,svg}',
  bower_components: 'src/bower_components/**/*.*',
  watch_path: 'src/less/dashboard/**/*.less'
};

gulp.task('usemin', function() {
  return gulp.src(paths.index)
    .pipe(usemin({
      less: [less(), 'concat'],
      js: ['concat', wrap('(function(){ \n<%= contents %>\n})();')],
    }))
    .pipe(gulp.dest('dist/'));
});

/**
 * Copy assets
 */
gulp.task('copy-assets', ['copy-images', 'copy-fonts', 'copy-bower_fonts']);

gulp.task('copy-images', function(){
  return gulp.src(paths.images)
    .pipe(gulp.dest('dist/img'));
});

gulp.task('copy-fonts', function(){
  return gulp.src(paths.fonts)
    .pipe(gulp.dest('dist/fonts'));
});

gulp.task('copy-bower_fonts', function(){
  return gulp.src(paths.bower_fonts)
    .pipe(gulp.dest('dist/lib'));
});

/**
 * Compile less
 */
gulp.task('compile-less', function(){
  return gulp.src(paths.styles)
      .pipe(less())
      .pipe(gulp.dest('dist/css'));
});

/**
 * Watch less
 */
gulp.task('watch-less', function() {
  gulp.watch(paths.watch_path, ['compile-less']);
})

gulp.task('build', ['usemin', 'copy-assets']);
gulp.task('default', ['build']);
<|endoftext|>