<commit_before>'use strict';

var _ = require('underscore.string')
  , fs = require('fs')
  , path = require('path')

  , bowerDir = JSON.parse(fs.readFileSync('.bowerrc')).directory + path.sep;

module.exports = function (gulp, $, config) {
  var isProd = $.yargs.argv.stage === 'prod';

  // delete build directory
  gulp.task('clean', function (cb) {
    return $.del(config.buildDir, cb);
  });

  // compile markup files and copy into build directory
  gulp.task('markup', ['clean'], function () {
    var hamlFilter = $.filter('**/*.haml')
      , jadeFilter = $.filter('**/*.jade');

    return gulp.src([
      config.appMarkupFiles<% if (polymer) { %>,
      '!' + config.appComponents<% } %>
    ])
      .pipe(hamlFilter)
      .pipe($.haml())
      .pipe(hamlFilter.restore())
      .pipe(jadeFilter)
      .pipe($.jade())
      .pipe(jadeFilter.restore())
      .pipe(gulp.dest(config.buildDir));
  });

  // compile styles and copy into build directory
  gulp.task('styles', ['clean'], function () {
    var lessFilter = $.filter('**/*.less')
      , scssFilter = $.filter('**/*.scss')
      , stylusFilter = $.filter('**/*.styl');

    return gulp.src([
      config.appStyleFiles<% if (polymer) { %>,
      '!' + config.appComponents<% } %>
    ])
      .pipe($.plumber({errorHandler: function (err) {
        $.notify.onError({
          title: 'Error linting at ' + err.plugin,
          subtitle: ' ', //overrides defaults
          message: err.message.replace(/\u001b\[.*?m/g, ''),
          sound: ' ' //overrides defaults
        })(err);

        this.emit('end');
      }}))
      .pipe(lessFilter)
      .pipe($.less())
      .pipe(lessFilter.restore())
      .pipe(scssFilter)
      .pipe($.sass())
      .pipe(scssFilter.restore())
      .pipe(stylusFilter)
      .pipe($.stylus({
        use: $.nib()
      }))
      .pipe(stylusFilter.restore())
      .pipe($.autoprefixer())
      .pipe($.if(isProd, $.cssRebaseUrls()))
      .pipe($.if(isProd, $.modifyCssUrls({
        modify: function (url) {
          // determine if url is using http, https, or data protocol
          // cssRebaseUrls rebases these URLs, too, so we need to fix that
          var beginUrl = url.indexOf('http:');
          if (beginUrl < 0) {
            beginUrl = url.indexOf('https:');
          }
          if (beginUrl < 0) {
            beginUrl = url.indexOf('data:');
          }

          if (beginUrl > -1) {
            return url.substring(beginUrl, url.length);
          }

          // prepend all other urls
          return '../' + url;
        }
      })))
      .pipe($.if(isProd, $.concat('app.css')))
      .pipe($.if(isProd, $.cssmin()))
      .pipe($.if(isProd, $.rev()))
      .pipe(gulp.dest(config.buildCss));
  });

  // compile scripts and copy into build directory
  gulp.task('scripts', ['clean', 'analyze', 'markup'], function () {
    var typescriptFilter = $.filter('**/*.ts')
      , coffeeFilter = $.filter('**/*.coffee')
      , es6Filter = $.filter('**/*.es6')
      , htmlFilter = $.filter('**/*.html')
      , jsFilter = $.filter('**/*.js');

    return gulp.src([
      config.appScriptFiles,
      config.buildDir + '**/*.html'<% if (polymer) { %>,
      '!' + config.appComponents<% } %>,
      '!**/*_test.*',
      '!**/index.html'
    ])
      .pipe(es6Filter)
      .pipe($.sourcemaps.init())
      .pipe($.babel())
      .pipe($.rename(function (filePath) {
        filePath.extname = '.js';
      }))
      .pipe(es6Filter.restore())
      .pipe(typescriptFilter)
      .pipe($.typescript(config.tsProject))
      .pipe(typescriptFilter.restore())
      .pipe(coffeeFilter)
      .pipe($.coffee())
      .pipe(coffeeFilter.restore())
      .pipe($.if(isProd, htmlFilter))
      .pipe($.if(isProd, $.ngHtml2js({
        // lower camel case all app names
        moduleName: _.camelize(_.slugify(_.humanize(require('../package.json').name))),
        declareModule: false
      })))
      .pipe($.if(isProd, htmlFilter.restore()))
      .pipe(jsFilter)
      .pipe($.if(isProd, $.angularFilesort()))
      .pipe($.if(isProd, $.concat('app.js')))
      .pipe($.if(isProd, $.ngAnnotate()))
      .pipe($.if(isProd, $.uglify()))
      .pipe($.if(isProd, $.rev()))<% if (polymer) { %>
      .pipe($.addSrc($.mainBowerFiles({filter: /webcomponents/})))<% } %>
      .pipe($.sourcemaps.write('.'))
      .pipe(gulp.dest(config.buildJs))
      .pipe(jsFilter.restore());
  });

  // inject custom CSS and JavaScript into index.html
  gulp.task('inject', ['markup', 'styles', 'scripts'], function () {
    var jsFilter = $.filter('**/*.js');

    return gulp.src(config.buildDir + 'index.html')
      .pipe($.inject(gulp.src([
          config.buildCss + '**/*',
          config.buildJs + '**/*'<% if (polymer) { %>,
          '!**/webcomponents.js'<% } %>
        ])
        .pipe(jsFilter)
        .pipe($.angularFilesort())
        .pipe(jsFilter.restore()), {
          addRootSlash: false,
          ignorePath: config.buildDir
        })
      )<% if (polymer) { %>
      .pipe($.inject(gulp.src([
          config.buildJs + 'webcomponents.js'
        ]), {
          starttag: '<!-- inject:head:{{ext}} -->',
          endtag: '<!-- endinject -->',
          addRootSlash: false,
          ignorePath: config.buildDir
        })
      )<% } %>
      .pipe(gulp.dest(config.buildDir));
  });

  // copy bower components into build directory
  gulp.task('bowerCopy', ['inject'], function () {
    var cssFilter = $.filter('**/*.css')
      , jsFilter = $.filter('**/*.js');

    return gulp.src($.mainBowerFiles(), {base: bowerDir})
      .pipe(cssFilter)
      .pipe($.if(isProd, $.modifyCssUrls({
        modify: function (url, filePath) {
          if (url.indexOf('http') !== 0 && url.indexOf('data:') !== 0) {
            filePath = path.dirname(filePath) + path.sep;
            filePath = filePath.substring(filePath.indexOf(bowerDir) + bowerDir.length,
              filePath.length);
          }
          url = path.normalize(filePath + url);
          url = url.replace(/[/\\]/g, '/');
          console.log(url);
          return url;
        }
      })))
      .pipe($.if(isProd, $.concat('vendor.css')))
      .pipe($.if(isProd, $.cssmin()))
      .pipe($.if(isProd, $.rev()))
      .pipe(gulp.dest(config.extDir))
      .pipe(cssFilter.restore())
      .pipe(jsFilter)
      .pipe($.if(isProd, $.concat('vendor.js')))
      .pipe($.if(isProd, $.uglify({
        preserveComments: $.uglifySaveLicense
      })))
      .pipe($.if(isProd, $.rev()))
      .pipe(gulp.dest(config.extDir))
      .pipe(jsFilter.restore());
  });

  // inject bower components into index.html
  gulp.task('bowerInject', ['bowerCopy'], function () {
    if (isProd) {
      return gulp.src(config.buildDir + 'index.html')
        .pipe($.inject(gulp.src([
          config.extDir + 'vendor*.css',
          config.extDir + 'vendor*.js'
        ], {
          read: false
        }), {
          starttag: '<!-- bower:{{ext}} -->',
          endtag: '<!-- endbower -->',
          addRootSlash: false,
          ignorePath: config.buildDir
        }))
        .pipe($.htmlmin({
          collapseWhitespace: true,
          removeComments: true
        }))
        .pipe(gulp.dest(config.buildDir));
    } else {
      return gulp.src(config.buildDir + 'index.html')
        .pipe($.wiredep.stream({<% if (polymer || framework === 'uibootstrap') { %>
          exclude: [<% } %><% if (framework === 'uibootstrap') { %>/bootstrap[.]js/<% } %><% if (polymer && framework === 'uibootstrap') { %>, <% } %><% if (polymer) { %>/polymer/, /webcomponents/<% } %><% if (polymer || framework === 'uibootstrap') { %>],<% } %>
          ignorePath: '../../' + bowerDir.replace(/\\/g, '/'),
          fileTypes: {
            html: {
              replace: {
                css: function (filePath) {
                  return '<link rel="stylesheet" href="' + config.extDir.replace(config.buildDir, '') +
                    filePath + '">';
                },
                js: function (filePath) {
                  return '<script src="' + config.extDir.replace(config.buildDir, '') +
                    filePath + '"></script>';
                }
              }
            }
          }
        }))
        .pipe(gulp.dest(config.buildDir));
    }
  });<% if (polymer) { %>

  // compile components and copy into build directory
  gulp.task('components', ['bowerInject'], function () {
    var typeScriptFilter = $.filter('**/*.ts')
      , coffeeFilter = $.filter('**/*.coffee')
      , es6Filter = $.filter('**/*.es6')
      , hamlFilter = $.filter('**/*.haml')
      , jadeFilter = $.filter('**/*.jade')
      , lessFilter = $.filter('**/*.less')
      , scssFilter = $.filter('**/*.scss')
      , stylFilter = $.filter('**/*.styl');

    return gulp.src(config.appComponents)
      .pipe($.addSrc(bowerDir + 'polymer/{layout,polymer}.{html,js}', {base: bowerDir}))
      .pipe($.sourcemaps.init())
      .pipe(es6Filter)
      .pipe($.babel())
      .pipe($.rename(function (filePath) {
        filePath.extname = '.js';
      }))
      .pipe(es6Filter.restore())
      .pipe(typeScriptFilter)
      .pipe($.typescript())
      .pipe(typeScriptFilter.restore())
      .pipe(coffeeFilter)
      .pipe($.coffee())
      .pipe(coffeeFilter.restore())
      .pipe(hamlFilter)
      .pipe($.haml())
      .pipe(hamlFilter.restore())
      .pipe(jadeFilter)
      .pipe($.jade())
      .pipe(jadeFilter.restore())
      .pipe(lessFilter)
      .pipe($.less())
      .pipe(lessFilter.restore())
      .pipe(scssFilter)
      .pipe($.sass())
      .pipe(scssFilter.restore())
      .pipe(stylFilter)
      .pipe($.stylus())
      .pipe(stylFilter.restore())
      .pipe($.sourcemaps.write('.'))
      .pipe(gulp.dest(config.buildComponents));
  });<% } %>

  // copy Bower fonts and images into build directory
  gulp.task('bowerAssets', ['clean'], function () {
    var assetFilter = $.filter('**/*.{eot,otf,svg,ttf,woff,gif,jpg,jpeg,png}');
    return gulp.src($.mainBowerFiles(), {base: bowerDir})
      .pipe(assetFilter)
      .pipe(gulp.dest(config.extDir))
      .pipe(assetFilter.restore());
  });

  // copy custom fonts into build directory
  gulp.task('fonts', ['clean'], function () {
    var fontFilter = $.filter('**/*.{eot,otf,svg,ttf,woff}');
    return gulp.src([config.appFontFiles])
      .pipe(fontFilter)
      .pipe(gulp.dest(config.buildFonts))
      .pipe(fontFilter.restore());
  });

  // copy and optimize images into build directory
  gulp.task('images', ['clean'], function () {
    return gulp.src(config.appImageFiles)
      .pipe($.if(isProd, $.imagemin()))
      .pipe(gulp.dest(config.buildImages));
  });

  gulp.task('copyTemplates', [<% if (polymer) { %>'components'<% } else { %>'bowerInject'<% } %>], function () {
    // always copy templates to testBuild directory
    var stream = $.streamqueue({objectMode: true});

    stream.queue(gulp.src([config.buildDirectiveTemplateFiles]));

    return stream.done()
      .pipe(gulp.dest(config.buildTestDirectiveTemplatesDir));
  });

  gulp.task('deleteTemplates', ['copyTemplates'], function (cb) {
    // only delete templates in production
    // the templates are injected into the app during prod build
    if (!isProd) {
      return cb();
    }

    gulp.src([config.buildDir + '**/*.html'])
      .pipe(gulp.dest('tmp/' + config.buildDir))
      .on('end', function () {
        $.del([
          config.buildDir + '*'<% if (polymer) { %>,
          '!' + config.buildComponents<% } %>,
          '!' + config.buildCss,
          '!' + config.buildFonts,
          '!' + config.buildImages,
          '!' + config.buildImages,
          '!' + config.buildJs,
          '!' + config.extDir,
          '!' + config.buildDir + 'index.html'
        ], {mark: true}, cb);
      });
  });

  gulp.task('build', ['deleteTemplates', 'bowerAssets', 'images', 'fonts']);
};
<commit_msg>fix(gulp/build) init sourcemaps before es6 filter<commit_after>'use strict';

var _ = require('underscore.string')
  , fs = require('fs')
  , path = require('path')

  , bowerDir = JSON.parse(fs.readFileSync('.bowerrc')).directory + path.sep;

module.exports = function (gulp, $, config) {
  var isProd = $.yargs.argv.stage === 'prod';

  // delete build directory
  gulp.task('clean', function (cb) {
    return $.del(config.buildDir, cb);
  });

  // compile markup files and copy into build directory
  gulp.task('markup', ['clean'], function () {
    var hamlFilter = $.filter('**/*.haml')
      , jadeFilter = $.filter('**/*.jade');

    return gulp.src([
      config.appMarkupFiles<% if (polymer) { %>,
      '!' + config.appComponents<% } %>
    ])
      .pipe(hamlFilter)
      .pipe($.haml())
      .pipe(hamlFilter.restore())
      .pipe(jadeFilter)
      .pipe($.jade())
      .pipe(jadeFilter.restore())
      .pipe(gulp.dest(config.buildDir));
  });

  // compile styles and copy into build directory
  gulp.task('styles', ['clean'], function () {
    var lessFilter = $.filter('**/*.less')
      , scssFilter = $.filter('**/*.scss')
      , stylusFilter = $.filter('**/*.styl');

    return gulp.src([
      config.appStyleFiles<% if (polymer) { %>,
      '!' + config.appComponents<% } %>
    ])
      .pipe($.plumber({errorHandler: function (err) {
        $.notify.onError({
          title: 'Error linting at ' + err.plugin,
          subtitle: ' ', //overrides defaults
          message: err.message.replace(/\u001b\[.*?m/g, ''),
          sound: ' ' //overrides defaults
        })(err);

        this.emit('end');
      }}))
      .pipe(lessFilter)
      .pipe($.less())
      .pipe(lessFilter.restore())
      .pipe(scssFilter)
      .pipe($.sass())
      .pipe(scssFilter.restore())
      .pipe(stylusFilter)
      .pipe($.stylus({
        use: $.nib()
      }))
      .pipe(stylusFilter.restore())
      .pipe($.autoprefixer())
      .pipe($.if(isProd, $.cssRebaseUrls()))
      .pipe($.if(isProd, $.modifyCssUrls({
        modify: function (url) {
          // determine if url is using http, https, or data protocol
          // cssRebaseUrls rebases these URLs, too, so we need to fix that
          var beginUrl = url.indexOf('http:');
          if (beginUrl < 0) {
            beginUrl = url.indexOf('https:');
          }
          if (beginUrl < 0) {
            beginUrl = url.indexOf('data:');
          }

          if (beginUrl > -1) {
            return url.substring(beginUrl, url.length);
          }

          // prepend all other urls
          return '../' + url;
        }
      })))
      .pipe($.if(isProd, $.concat('app.css')))
      .pipe($.if(isProd, $.cssmin()))
      .pipe($.if(isProd, $.rev()))
      .pipe(gulp.dest(config.buildCss));
  });

  // compile scripts and copy into build directory
  gulp.task('scripts', ['clean', 'analyze', 'markup'], function () {
    var typescriptFilter = $.filter('**/*.ts')
      , coffeeFilter = $.filter('**/*.coffee')
      , es6Filter = $.filter('**/*.es6')
      , htmlFilter = $.filter('**/*.html')
      , jsFilter = $.filter('**/*.js');

    return gulp.src([
      config.appScriptFiles,
      config.buildDir + '**/*.html'<% if (polymer) { %>,
      '!' + config.appComponents<% } %>,
      '!**/*_test.*',
      '!**/index.html'
    ])
      .pipe($.sourcemaps.init())
      .pipe(es6Filter)
      .pipe($.babel())
      .pipe($.rename(function (filePath) {
        filePath.extname = '.js';
      }))
      .pipe(es6Filter.restore())
      .pipe(typescriptFilter)
      .pipe($.typescript(config.tsProject))
      .pipe(typescriptFilter.restore())
      .pipe(coffeeFilter)
      .pipe($.coffee())
      .pipe(coffeeFilter.restore())
      .pipe($.if(isProd, htmlFilter))
      .pipe($.if(isProd, $.ngHtml2js({
        // lower camel case all app names
        moduleName: _.camelize(_.slugify(_.humanize(require('../package.json').name))),
        declareModule: false
      })))
      .pipe($.if(isProd, htmlFilter.restore()))
      .pipe(jsFilter)
      .pipe($.if(isProd, $.angularFilesort()))
      .pipe($.if(isProd, $.concat('app.js')))
      .pipe($.if(isProd, $.ngAnnotate()))
      .pipe($.if(isProd, $.uglify()))
      .pipe($.if(isProd, $.rev()))<% if (polymer) { %>
      .pipe($.addSrc($.mainBowerFiles({filter: /webcomponents/})))<% } %>
      .pipe($.sourcemaps.write('.'))
      .pipe(gulp.dest(config.buildJs))
      .pipe(jsFilter.restore());
  });

  // inject custom CSS and JavaScript into index.html
  gulp.task('inject', ['markup', 'styles', 'scripts'], function () {
    var jsFilter = $.filter('**/*.js');

    return gulp.src(config.buildDir + 'index.html')
      .pipe($.inject(gulp.src([
          config.buildCss + '**/*',
          config.buildJs + '**/*'<% if (polymer) { %>,
          '!**/webcomponents.js'<% } %>
        ])
        .pipe(jsFilter)
        .pipe($.angularFilesort())
        .pipe(jsFilter.restore()), {
          addRootSlash: false,
          ignorePath: config.buildDir
        })
      )<% if (polymer) { %>
      .pipe($.inject(gulp.src([
          config.buildJs + 'webcomponents.js'
        ]), {
          starttag: '<!-- inject:head:{{ext}} -->',
          endtag: '<!-- endinject -->',
          addRootSlash: false,
          ignorePath: config.buildDir
        })
      )<% } %>
      .pipe(gulp.dest(config.buildDir));
  });

  // copy bower components into build directory
  gulp.task('bowerCopy', ['inject'], function () {
    var cssFilter = $.filter('**/*.css')
      , jsFilter = $.filter('**/*.js');

    return gulp.src($.mainBowerFiles(), {base: bowerDir})
      .pipe(cssFilter)
      .pipe($.if(isProd, $.modifyCssUrls({
        modify: function (url, filePath) {
          if (url.indexOf('http') !== 0 && url.indexOf('data:') !== 0) {
            filePath = path.dirname(filePath) + path.sep;
            filePath = filePath.substring(filePath.indexOf(bowerDir) + bowerDir.length,
              filePath.length);
          }
          url = path.normalize(filePath + url);
          url = url.replace(/[/\\]/g, '/');
          console.log(url);
          return url;
        }
      })))
      .pipe($.if(isProd, $.concat('vendor.css')))
      .pipe($.if(isProd, $.cssmin()))
      .pipe($.if(isProd, $.rev()))
      .pipe(gulp.dest(config.extDir))
      .pipe(cssFilter.restore())
      .pipe(jsFilter)
      .pipe($.if(isProd, $.concat('vendor.js')))
      .pipe($.if(isProd, $.uglify({
        preserveComments: $.uglifySaveLicense
      })))
      .pipe($.if(isProd, $.rev()))
      .pipe(gulp.dest(config.extDir))
      .pipe(jsFilter.restore());
  });

  // inject bower components into index.html
  gulp.task('bowerInject', ['bowerCopy'], function () {
    if (isProd) {
      return gulp.src(config.buildDir + 'index.html')
        .pipe($.inject(gulp.src([
          config.extDir + 'vendor*.css',
          config.extDir + 'vendor*.js'
        ], {
          read: false
        }), {
          starttag: '<!-- bower:{{ext}} -->',
          endtag: '<!-- endbower -->',
          addRootSlash: false,
          ignorePath: config.buildDir
        }))
        .pipe($.htmlmin({
          collapseWhitespace: true,
          removeComments: true
        }))
        .pipe(gulp.dest(config.buildDir));
    } else {
      return gulp.src(config.buildDir + 'index.html')
        .pipe($.wiredep.stream({<% if (polymer || framework === 'uibootstrap') { %>
          exclude: [<% } %><% if (framework === 'uibootstrap') { %>/bootstrap[.]js/<% } %><% if (polymer && framework === 'uibootstrap') { %>, <% } %><% if (polymer) { %>/polymer/, /webcomponents/<% } %><% if (polymer || framework === 'uibootstrap') { %>],<% } %>
          ignorePath: '../../' + bowerDir.replace(/\\/g, '/'),
          fileTypes: {
            html: {
              replace: {
                css: function (filePath) {
                  return '<link rel="stylesheet" href="' + config.extDir.replace(config.buildDir, '') +
                    filePath + '">';
                },
                js: function (filePath) {
                  return '<script src="' + config.extDir.replace(config.buildDir, '') +
                    filePath + '"></script>';
                }
              }
            }
          }
        }))
        .pipe(gulp.dest(config.buildDir));
    }
  });<% if (polymer) { %>

  // compile components and copy into build directory
  gulp.task('components', ['bowerInject'], function () {
    var typeScriptFilter = $.filter('**/*.ts')
      , coffeeFilter = $.filter('**/*.coffee')
      , es6Filter = $.filter('**/*.es6')
      , hamlFilter = $.filter('**/*.haml')
      , jadeFilter = $.filter('**/*.jade')
      , lessFilter = $.filter('**/*.less')
      , scssFilter = $.filter('**/*.scss')
      , stylFilter = $.filter('**/*.styl');

    return gulp.src(config.appComponents)
      .pipe($.addSrc(bowerDir + 'polymer/{layout,polymer}.{html,js}', {base: bowerDir}))
      .pipe($.sourcemaps.init())
      .pipe(es6Filter)
      .pipe($.babel())
      .pipe($.rename(function (filePath) {
        filePath.extname = '.js';
      }))
      .pipe(es6Filter.restore())
      .pipe(typeScriptFilter)
      .pipe($.typescript())
      .pipe(typeScriptFilter.restore())
      .pipe(coffeeFilter)
      .pipe($.coffee())
      .pipe(coffeeFilter.restore())
      .pipe(hamlFilter)
      .pipe($.haml())
      .pipe(hamlFilter.restore())
      .pipe(jadeFilter)
      .pipe($.jade())
      .pipe(jadeFilter.restore())
      .pipe(lessFilter)
      .pipe($.less())
      .pipe(lessFilter.restore())
      .pipe(scssFilter)
      .pipe($.sass())
      .pipe(scssFilter.restore())
      .pipe(stylFilter)
      .pipe($.stylus())
      .pipe(stylFilter.restore())
      .pipe($.sourcemaps.write('.'))
      .pipe(gulp.dest(config.buildComponents));
  });<% } %>

  // copy Bower fonts and images into build directory
  gulp.task('bowerAssets', ['clean'], function () {
    var assetFilter = $.filter('**/*.{eot,otf,svg,ttf,woff,gif,jpg,jpeg,png}');
    return gulp.src($.mainBowerFiles(), {base: bowerDir})
      .pipe(assetFilter)
      .pipe(gulp.dest(config.extDir))
      .pipe(assetFilter.restore());
  });

  // copy custom fonts into build directory
  gulp.task('fonts', ['clean'], function () {
    var fontFilter = $.filter('**/*.{eot,otf,svg,ttf,woff}');
    return gulp.src([config.appFontFiles])
      .pipe(fontFilter)
      .pipe(gulp.dest(config.buildFonts))
      .pipe(fontFilter.restore());
  });

  // copy and optimize images into build directory
  gulp.task('images', ['clean'], function () {
    return gulp.src(config.appImageFiles)
      .pipe($.if(isProd, $.imagemin()))
      .pipe(gulp.dest(config.buildImages));
  });

  gulp.task('copyTemplates', [<% if (polymer) { %>'components'<% } else { %>'bowerInject'<% } %>], function () {
    // always copy templates to testBuild directory
    var stream = $.streamqueue({objectMode: true});

    stream.queue(gulp.src([config.buildDirectiveTemplateFiles]));

    return stream.done()
      .pipe(gulp.dest(config.buildTestDirectiveTemplatesDir));
  });

  gulp.task('deleteTemplates', ['copyTemplates'], function (cb) {
    // only delete templates in production
    // the templates are injected into the app during prod build
    if (!isProd) {
      return cb();
    }

    gulp.src([config.buildDir + '**/*.html'])
      .pipe(gulp.dest('tmp/' + config.buildDir))
      .on('end', function () {
        $.del([
          config.buildDir + '*'<% if (polymer) { %>,
          '!' + config.buildComponents<% } %>,
          '!' + config.buildCss,
          '!' + config.buildFonts,
          '!' + config.buildImages,
          '!' + config.buildImages,
          '!' + config.buildJs,
          '!' + config.extDir,
          '!' + config.buildDir + 'index.html'
        ], {mark: true}, cb);
      });
  });

  gulp.task('build', ['deleteTemplates', 'bowerAssets', 'images', 'fonts']);
};
<|endoftext|>


<commit_before>'use strict';

(function (exports, undefined) {
  var images = [];
  var clientId = '22729e0c12254816aba48fcd8007d74c';
  var accessToken = null;

  var retrieveAccessToken = function () {
    if (accessToken !== null) {
      return;
    }
    if (window.location.hash) {
      accessToken = window.location.hash.substring(14);
      window.location.hash = '';
    } else {
      auth();
    }
  };

  var auth = function () {
    var redirectTo = window.location.href;
    if (redirectTo[redirectTo.length - 1] === '/') {
      redirectTo = redirectTo.slice(0, redirectTo.length - 1);
    }
    window.location =
        'https://instagram.com/oauth/authorize/?client_id=' + clientId +
        '&redirect_uri=' + redirectTo + '&response_type=token';
  };

  // http://stackoverflow.com/questions/22780430/javascript-xmlhttprequest-using-jsonp
  var jsonp = function (url, callback) {
    var callbackName = 'jsonp_callback_' + Math.round(100000 * Math.random());
    window[callbackName] = function(data) {
      window[callbackName] = undefined;
      try {
        delete window[callbackName];
      } catch (e) {}
      document.body.removeChild(script);
      callback(data);
    };
    var script = document.createElement('script');
    script.src = url + (url.indexOf('?') >= 0 ? '&' : '?') + 'callback=' + callbackName;
    document.body.appendChild(script);
  };

  exports.loadImages = function () {
    retrieveAccessToken();
    var req = new XMLHttpRequest();
    jsonp('https://api.instagram.com/v1/media/popular?access_token=' + accessToken, function (response) {
      images = response.data;
      window.lightbox.setImages(images);
    });
  };

  exports.listImages = function () {
    return images;
  };

})(window.images = window.images || {});
<commit_msg>cleanup and ui tweaks and title<commit_after>'use strict';

(function (exports, undefined) {
  var images = [];
  var clientId = '22729e0c12254816aba48fcd8007d74c';
  var accessToken = null;

  var retrieveAccessToken = function () {
    if (accessToken !== null) {
      return;
    }
    if (window.location.hash) {
      accessToken = window.location.hash.substring(14);
    } else {
      auth();
    }
  };

  var auth = function () {
    var redirectTo = window.location.href;
    if (redirectTo[redirectTo.length - 1] === '/') {
      redirectTo = redirectTo.slice(0, redirectTo.length - 1);
    }
    window.location =
        'https://instagram.com/oauth/authorize/?client_id=' + clientId +
        '&redirect_uri=' + redirectTo + '&response_type=token';
  };

  // http://stackoverflow.com/questions/22780430/javascript-xmlhttprequest-using-jsonp
  var jsonp = function (url, callback) {
    var callbackName = 'jsonp_callback_' + Math.round(100000 * Math.random());
    window[callbackName] = function(data) {
      window[callbackName] = undefined;
      try {
        delete window[callbackName];
      } catch (e) {}
      document.body.removeChild(script);
      callback(data);
    };
    var script = document.createElement('script');
    script.src = url + (url.indexOf('?') >= 0 ? '&' : '?') + 'callback=' + callbackName;
    document.body.appendChild(script);
  };

  exports.loadImages = function () {
    retrieveAccessToken();
    var req = new XMLHttpRequest();
    jsonp('https://api.instagram.com/v1/media/popular?access_token=' + accessToken, function (response) {
      images = response.data;
      window.lightbox.setImages(images);
    });
  };

  exports.listImages = function () {
    return images;
  };

})(window.images = window.images || {});
<|endoftext|>


<commit_before>var map = L.map('map');

//ピンを追加 childrencafeteria:cc
var cc1 = L.marker([34.392487, 132.475126]).bindPopup('青い鳥'),
    cc2 = L.marker([34.361050, 132.463745]).bindPopup('くるり食堂');

var childrencafeteria = L.layerGroup([
    cc1, cc2
]);

var pale = L.tileLayer('http://cyberjapandata.gsi.go.jp/xyz/pale/{z}/{x}/{y}.png',
{id: 'palemap', attribution: "国土地理院"}),
    blank = L.tileLayer('http://cyberjapandata.gsi.go.jp/xyz/blank/{z}/{x}/{y}.png',
{id: 'blankmap', attribution: "国土地理院"}),
    osm = L.tileLayer('http://tile.openstreetmap.jp/{z}/{x}/{y}.png',
{ id: 'osmmap', attribution: '© OpenStreetMap contributors' });

var map = L.map('map', {
    layers: [pale, childrencafeteria]
});

var baseMaps = {
    "淡色地図" : pale,
    "白地図"   : blank,
    "OSM japan"  : osm
};

var overlayMaps = {
    "こども食堂" : childrencafeteria
};

L.control.layers(baseMaps, overlayMaps).addTo(map);

map.setView([34.393073, 132.452091], 16);<commit_msg>map定義の変更<commit_after>//var map = L.map('map');

//ピンを追加 childrencafeteria:cc
var cc1 = L.marker([34.392487, 132.475126]).bindPopup('青い鳥'),
    cc2 = L.marker([34.361050, 132.463745]).bindPopup('くるり食堂');

var childrencafeteria = L.layerGroup([
    cc1, cc2
]);

var pale = L.tileLayer('http://cyberjapandata.gsi.go.jp/xyz/pale/{z}/{x}/{y}.png',
{id: 'palemap', attribution: "国土地理院"}),
    blank = L.tileLayer('http://cyberjapandata.gsi.go.jp/xyz/blank/{z}/{x}/{y}.png',
{id: 'blankmap', attribution: "国土地理院"}),
    osm = L.tileLayer('http://tile.openstreetmap.jp/{z}/{x}/{y}.png',
{ id: 'osmmap', attribution: '© OpenStreetMap contributors' });

var map = L.map('map', {
    layers: [pale, childrencafeteria]
});

var baseMaps = {
    "淡色地図" : pale,
    "白地図"   : blank,
    "OSM japan"  : osm
};

var overlayMaps = {
    "こども食堂" : childrencafeteria
};

L.control.layers(baseMaps, overlayMaps).addTo(map);

map.setView([34.393073, 132.452091], 16);<|endoftext|>


<commit_before>"use strict";

var async = require('async');
var Anyfetch = require('anyfetch');
var mongoose = require('mongoose');
var rarity = require('rarity');
var restify = require('restify');
var ObjectId = mongoose.Types.ObjectId;

var ImportantDocument = mongoose.model('ImportantDocument');

module.exports.post = function post(req, res, next) {
  var anyfetchClient = new Anyfetch(req.accessToken.token);
  async.waterfall([
    function checkForExisting(cb) {
      ImportantDocument.findOne({eventId: req.params.eventId, document: new ObjectId(req.params.id)}, cb);
    },
    function getDocumentFull(existing, cb) {
      if(existing) {
        return cb(new restify.ConflictError("Document already marked as important"));
      }
      anyfetchClient.getDocumentById(req.params.id, { search: req.query.context, render_templates: true }, cb);
    },
    function getDocumentSnippet(fullRes, cb) {
      anyfetchClient.getDocuments({ search: req.query.context, id: req.params.id, render_templates: true }, rarity.carry([fullRes], cb));
    },
    function saveImportantDocument(fullRes, snippetRes, cb) {
      var document = fullRes.body;
      if(!snippetRes.body.data[0]) {
        return cb(new restify.InternalError("Anyfetch index has diverged from its database"));
      }
      var importantDocument = new ImportantDocument({
        type: document.document_type.name,
        date: new Date(document.modification_date),
        document: new ObjectId(req.params.id),
        company: req.accessToken.company,
        eventId: req.params.eventId,
        title: document.rendered_title,
        full: document.rendered_full,
        snippet: snippetRes.body.data[0].rendered_snippet
      });
      importantDocument.save(cb);
    },
    function confirmSave(doc, affected, cb) {
      res.send(202);
      cb();
    }
  ], next);
};

module.exports.del = function del(req, res, next) {
  async.waterfall([
    function queryDocument(cb) {
      ImportantDocument.findOne({ eventId: req.params.eventId, company: req.accessToken.company, document: new ObjectId(req.params.id) }, cb);
    },
    function startDeletion(doc, cb) {
      if(!doc) {
        return cb(new restify.ConflictError("This document is not important"));
      }
      doc.remove(cb);
    },
    function writeRes(doc, cb) {
      res.send(202);
      cb();
    }
  ], next);
};
<commit_msg>Check for the format of the document id (ObjectId)<commit_after>"use strict";

var async = require('async');
var Anyfetch = require('anyfetch');
var mongoose = require('mongoose');
var rarity = require('rarity');
var restify = require('restify');
var ObjectId = mongoose.Types.ObjectId;

var ImportantDocument = mongoose.model('ImportantDocument');

function checkObjectId(req, paramName) {
  return function check(cb) {
    if(!req.params[paramName || 'id'].match(/^[0-9a-fA-F]{24}$/)) {
      return cb(new restify.NotFoundError());
    }
    cb(null);
  };
}

module.exports.post = function post(req, res, next) {
  var anyfetchClient = new Anyfetch(req.accessToken.token);
  async.waterfall([
    checkObjectId(req),
    function checkForExisting(cb) {
      ImportantDocument.findOne({eventId: req.params.eventId, document: new ObjectId(req.params.id)}, cb);
    },
    function getDocumentFull(existing, cb) {
      if(existing) {
        return cb(new restify.ConflictError("Document already marked as important"));
      }
      anyfetchClient.getDocumentById(req.params.id, { search: req.query.context, render_templates: true }, cb);
    },
    function getDocumentSnippet(fullRes, cb) {
      anyfetchClient.getDocuments({ search: req.query.context, id: req.params.id, render_templates: true }, rarity.carry([fullRes], cb));
    },
    function saveImportantDocument(fullRes, snippetRes, cb) {
      var document = fullRes.body;
      if(!snippetRes.body.data[0]) {
        return cb(new restify.InternalError("Anyfetch index has diverged from its database"));
      }
      var importantDocument = new ImportantDocument({
        type: document.document_type.name,
        date: new Date(document.modification_date),
        document: new ObjectId(req.params.id),
        company: req.accessToken.company,
        eventId: req.params.eventId,
        title: document.rendered_title,
        full: document.rendered_full,
        snippet: snippetRes.body.data[0].rendered_snippet
      });
      importantDocument.save(cb);
    },
    function confirmSave(doc, affected, cb) {
      res.send(202);
      cb();
    }
  ], next);
};

module.exports.del = function del(req, res, next) {
  async.waterfall([
    checkObjectId(req),
    function queryDocument(cb) {
      ImportantDocument.findOne({ eventId: req.params.eventId, company: req.accessToken.company, document: new ObjectId(req.params.id) }, cb);
    },
    function startDeletion(doc, cb) {
      if(!doc) {
        return cb(new restify.ConflictError("This document is not important"));
      }
      doc.remove(cb);
    },
    function writeRes(doc, cb) {
      res.send(202);
      cb();
    }
  ], next);
};
<|endoftext|>


<commit_before>$(function() {
    var iframe_clone = null;
    var popup = null;
    var placeholder = null;

    $('.tearout').on('mouseover', 'a.open', function(event) {
        if (!$('.tearout .problem:visible').length) {
            $('.tearout .warning-about-time').fadeIn(100);
        }
    }).on('mouseout', 'a.open', function(event) {
        $('.tearout .warning-about-time').fadeOut(300);
    });

    $('.tearout').on('click', 'a.open', function(event) {
        event.preventDefault();
        var iframe = $('.entry-content iframe');
        var player_wrapper = $('.entry-content #player_wrapper');

        var video_url = location.href + 'video/?embedded=false&autoplay=true';
        var video_name = '_blank';
        var features = 'menubar=no,location=no,resizable=no,scrollbars=no,status=no';
        if (iframe.length) {
            // probably a vid.ly iframe
            features += ',width=' + iframe.attr('width');
            features += ',height=' + iframe.attr('height');
        } else if (player_wrapper.length) {
            // probably a live even using jwplayer
            features += ',height=' + player_wrapper.css('height');
            features += ',width=' + player_wrapper.css('width');
        } else {
            console.warn('No iframe, so hard to guess the width and height of popup');
            // some sensible defaults
            features += ',width=640,height=360';
        }

        popup = window.open(video_url, video_url, features);
        if (popup === null) {
            $('.tearout .problem')
            .text('Unable to make a pop-up Window. Perhaps ' +
                  'you need to unblock pop-up blockers for this site.'
            ).fadeIn(400);
        } else {
            // safe and useful if opened before under the same name
            popup.focus();

            // in case it previously didn't work
            $('.tearout .problem').hide();

            $('.tearout a.open').hide();
            $('.tearout a.restore').fadeIn(400);
            if (iframe.length) {
                iframe_clone = iframe.detach();
            } else {
                player_wrapper = player_wrapper.detach();
            }

            if (placeholder === null) {
                placeholder = $('<div>')
                    .addClass('tearout-placeholder');
                if (iframe.length) {
                    placeholder.css('width', iframe.attr('width'));
                    placeholder.css('height', iframe.attr('height'));
                } else if (player_wrapper.length) {
                    placeholder.css('width', player_wrapper.css('width'));
                    placeholder.css('height', player_wrapper.css('height'));
                } else {
                    placeholder.css('width', 640).css('height', 360);
                }
                // and insert a restore link in it
                $('<a>')
                    .addClass('restore')
                    .attr('title', "Close the pop-up window and restore this page")
                    .text("Close the pop-up and restore video here")
                    .appendTo(placeholder);

                placeholder.on('click', 'a.restore', function(event) {
                    placeholder = placeholder.detach();
                    if (iframe.length) {
                        iframe_clone.insertBefore($('.tearout'));
                    } else {
                        player_wrapper.insertBefore($('.tearout'));
                    }

                    $('.tearout a.open').show();
                    if (popup !== null) {
                        popup.close();
                    }
                });
            }
            placeholder.insertBefore($('.tearout'));
        }
    });

});
<commit_msg>small typo<commit_after>$(function() {
    var iframe_clone = null;
    var popup = null;
    var placeholder = null;

    $('.tearout').on('mouseover', 'a.open', function(event) {
        if (!$('.tearout .problem:visible').length) {
            $('.tearout .warning-about-time').fadeIn(100);
        }
    }).on('mouseout', 'a.open', function(event) {
        $('.tearout .warning-about-time').fadeOut(300);
    });

    $('.tearout').on('click', 'a.open', function(event) {
        event.preventDefault();
        var iframe = $('.entry-content iframe');
        var player_wrapper = $('.entry-content #player_wrapper');

        var video_url = location.href + 'video/?embedded=false&autoplay=true';
        var video_name = '_blank';
        var features = 'menubar=no,location=no,resizable=no,scrollbars=no,status=no';
        if (iframe.length) {
            // probably a vid.ly iframe
            features += ',width=' + iframe.attr('width');
            features += ',height=' + iframe.attr('height');
        } else if (player_wrapper.length) {
            // probably a live event using jwplayer
            features += ',height=' + player_wrapper.css('height');
            features += ',width=' + player_wrapper.css('width');
        } else {
            console.warn('No iframe, so hard to guess the width and height of popup');
            // some sensible defaults
            features += ',width=640,height=360';
        }

        popup = window.open(video_url, video_url, features);
        if (popup === null) {
            $('.tearout .problem')
            .text('Unable to make a pop-up Window. Perhaps ' +
                  'you need to unblock pop-up blockers for this site.'
            ).fadeIn(400);
        } else {
            // safe and useful if opened before under the same name
            popup.focus();

            // in case it previously didn't work
            $('.tearout .problem').hide();

            $('.tearout a.open').hide();
            $('.tearout a.restore').fadeIn(400);
            if (iframe.length) {
                iframe_clone = iframe.detach();
            } else {
                player_wrapper = player_wrapper.detach();
            }

            if (placeholder === null) {
                placeholder = $('<div>')
                    .addClass('tearout-placeholder');
                if (iframe.length) {
                    placeholder.css('width', iframe.attr('width'));
                    placeholder.css('height', iframe.attr('height'));
                } else if (player_wrapper.length) {
                    placeholder.css('width', player_wrapper.css('width'));
                    placeholder.css('height', player_wrapper.css('height'));
                } else {
                    placeholder.css('width', 640).css('height', 360);
                }
                // and insert a restore link in it
                $('<a>')
                    .addClass('restore')
                    .attr('title', "Close the pop-up window and restore this page")
                    .text("Close the pop-up and restore video here")
                    .appendTo(placeholder);

                placeholder.on('click', 'a.restore', function(event) {
                    placeholder = placeholder.detach();
                    if (iframe.length) {
                        iframe_clone.insertBefore($('.tearout'));
                    } else {
                        player_wrapper.insertBefore($('.tearout'));
                    }

                    $('.tearout a.open').show();
                    if (popup !== null) {
                        popup.close();
                    }
                });
            }
            placeholder.insertBefore($('.tearout'));
        }
    });

});
<|endoftext|>


<commit_before>'use strict';

var Node = require('../node');
var debug = require('../../util/debug')('analysis:georeference-street-address');

var TYPE = 'georeference-street-address';
var PARAMS = {
    source: Node.PARAM.NODE(Node.GEOMETRY.ANY),
    street_address_column: Node.PARAM.NULLABLE(Node.PARAM.STRING()),
    street_address_template: Node.PARAM.NULLABLE(Node.PARAM.STRING()),
    city: Node.PARAM.NULLABLE(Node.PARAM.STRING()),
    city_column: Node.PARAM.NULLABLE(Node.PARAM.STRING()),
    state: Node.PARAM.NULLABLE(Node.PARAM.STRING()),
    state_column: Node.PARAM.NULLABLE(Node.PARAM.STRING()),
    country: Node.PARAM.NULLABLE(Node.PARAM.STRING()),
    country_column: Node.PARAM.NULLABLE(Node.PARAM.STRING())
};

var GeoreferenceStreetAddress = Node.create(TYPE, PARAMS, { cache: true,
    beforeCreate: function() {
        if (this.street_address_column === null && this.street_address_template === null) {
            throw new Error('Either `street_address_column` or `street_address_template` params must be provided');
        }
    }
});

module.exports = GeoreferenceStreetAddress;

GeoreferenceStreetAddress.prototype.sql = function() {
    var sql = queryTemplate({
        source: this.source.getQuery(),
        columns: this.source.getColumns(true).join(', '),
        street_column: this.getStreetAddressColumnParam(),
        params: this.getGeocoderParams().join(', ')
    });

    debug(sql);

    return sql;
};

GeoreferenceStreetAddress.prototype.getGeocoderParams = function () {
    var geocoderParams = [
        this.getStreetAddressColumnParam(),
        this.getFunctionParam('city'),
        this.getFunctionParam('state'),
        this.getFunctionParam('country')
    ];

    return geocoderParams;
};

var COLUMNS_TEMPLATE_REGEX = /\{\{([^\}]*)\}\}/g;
GeoreferenceStreetAddress.prototype.getStreetAddressColumnParam = function() {
    if (this.street_address_column) {
        return this.getFunctionParam('street_address');
    }

    var columns = [];
    var result = this.street_address_template.replace(COLUMNS_TEMPLATE_REGEX, function(s, column) {
        columns.push(column.trim());
        return '%s';
    });

    if (columns.length === 0) {
        return '$tpl$' + this.street_address_template + '$tpl$';
    }

    return 'format($tpl$'+result+'$tpl$, ' + columns.join(', ') + ')';
};

GeoreferenceStreetAddress.prototype.getFunctionParam = function (name) {
    if (this[name + '_column']) {
        return this[name + '_column'];
    }

    if (this[name]) {
        return '\'' + this[name] + '\'';
    }

    return 'NULL';
};

var queryTemplate = Node.template([
    'WITH geocoding_data as (',
    '   SELECT ',
    '      json_build_object(\'id\', cartodb_id, \'address\', {{=it.street_column}}) as data',
    '   FROM ({{=it.source}}) AS _camshaft_georeference_street_address_analysis',
    ')',
    'SELECT',
    '   {{=it.columns}}, ',
    '   _y.the_geom, st_transform(st_setsrid(_y.the_geom, 4326), 3857) as the_geom_webmercator, _y.metadata ',
    'FROM',
    '   ({{=it.source}}) _x',
    '   LEFT JOIN',
    '   (SELECT (cdb_dataservices_client.cdb_bulk_geocode_street_point(jsonb_agg(data))).* FROM geocoding_data) _y',
    '   USING (cartodb_id) '
].join('\n'));
<commit_msg>Bulk geocoding provided by dataservices api<commit_after>'use strict';

var Node = require('../node');
var debug = require('../../util/debug')('analysis:georeference-street-address');

var TYPE = 'georeference-street-address';
var PARAMS = {
    source: Node.PARAM.NODE(Node.GEOMETRY.ANY),
    street_address_column: Node.PARAM.NULLABLE(Node.PARAM.STRING()),
    street_address_template: Node.PARAM.NULLABLE(Node.PARAM.STRING()),
    city: Node.PARAM.NULLABLE(Node.PARAM.STRING()),
    city_column: Node.PARAM.NULLABLE(Node.PARAM.STRING()),
    state: Node.PARAM.NULLABLE(Node.PARAM.STRING()),
    state_column: Node.PARAM.NULLABLE(Node.PARAM.STRING()),
    country: Node.PARAM.NULLABLE(Node.PARAM.STRING()),
    country_column: Node.PARAM.NULLABLE(Node.PARAM.STRING())
};

var GeoreferenceStreetAddress = Node.create(TYPE, PARAMS, { cache: true,
    beforeCreate: function() {
        if (this.street_address_column === null && this.street_address_template === null) {
            throw new Error('Either `street_address_column` or `street_address_template` params must be provided');
        }
    }
});

module.exports = GeoreferenceStreetAddress;

GeoreferenceStreetAddress.prototype.sql = function() {
    var sql = queryTemplate({
        source: this.source.getQuery(),
        columns: this.source.getColumns(true).join(', '),
        street_column: this.getStreetAddressColumnParam(),
        params: this.getGeocoderParams().join(', ')
    });

    debug(sql);

    return sql;
};

GeoreferenceStreetAddress.prototype.getGeocoderParams = function () {
    var geocoderParams = [
        this.getStreetAddressColumnParam(),
        this.getFunctionParam('city'),
        this.getFunctionParam('state'),
        this.getFunctionParam('country')
    ];

    return geocoderParams;
};

var COLUMNS_TEMPLATE_REGEX = /\{\{([^\}]*)\}\}/g;
GeoreferenceStreetAddress.prototype.getStreetAddressColumnParam = function() {
    if (this.street_address_column) {
        return this.getFunctionParam('street_address');
    }

    var columns = [];
    var result = this.street_address_template.replace(COLUMNS_TEMPLATE_REGEX, function(s, column) {
        columns.push(column.trim());
        return '%s';
    });

    if (columns.length === 0) {
        return '$tpl$' + this.street_address_template + '$tpl$';
    }

    return 'format($tpl$'+result+'$tpl$, ' + columns.join(', ') + ')';
};

GeoreferenceStreetAddress.prototype.getFunctionParam = function (name) {
    if (this[name + '_column']) {
        return this[name + '_column'];
    }

    if (this[name]) {
        return '\'' + this[name] + '\'';
    }

    return 'NULL';
};

var queryTemplate = Node.template([
    'SELECT',
    '   {{=it.columns}}, ',
    '   _y.the_geom, st_transform(st_setsrid(_y.the_geom, 4326), 3857) as the_geom_webmercator, _y.metadata ',
    'FROM',
    '   ({{=it.source}}) _x',
    '   LEFT JOIN',
    '   (SELECT * from ' +
    '       cdb_dataservices_client.cdb_bulk_geocode_street_point(\'select * from ({{=it.source}}) __x\', \'{{=it.street_column}}\')) _y',
    '   USING (cartodb_id) '
].join('\n'));
<|endoftext|>


<commit_before>import test from 'tape'
import axios from 'axios'
import bodyParser from 'body-parser'
import Express from 'express'
import fs from 'fs'
import path from 'path'
import promiseFinally from 'promise.prototype.finally'
import rimraf from 'rimraf'

import { API_REPOS } from '../../../../../share/constants/api'
import reposRouter from './repos'
import config from '../../../../../../config.json'

promiseFinally.shim()

const REPO_ROOT = config.env[process.env.NODE_ENV].REPO_ROOT

let app
let PORT
test.test('setup', t => {
  app = new Express()
    .use(bodyParser.json())
    .use(reposRouter)
    .listen(0)
  PORT = app.address().port
  t.end()
})

test(`POST ${
  API_REPOS.LOGIN_USERS
} should return 201 when specified name repository does not exist`, t => {
  axios
    .post(`http://localhost:${PORT}${API_REPOS.LOGIN_USERS}`, {
      name: 'repo2',
      owner: 'DUMMY',
      authenticity_token: 'TRUE'
    })
    .then(res => {
      t.is(res.status, 201)
      t.is(fs.existsSync(path.join(REPO_ROOT, 'DUMMY', 'repo2')), true)
    })
    .catch(err => {
      console.error(err)
      t.fail(err.toString())
    })
    .finally(() => {
      rimraf.sync(path.join(REPO_ROOT, 'DUMMY'))
      t.end()
    })
})

test(`POST ${
  API_REPOS.LOGIN_USERS
} should return 409 when specified name repository already exists`, t => {
  axios
    .post(`http://localhost:${PORT}${API_REPOS.LOGIN_USERS}`, {
      name: 'repo1',
      owner: 'user1',
      authenticity_token: 'TRUE'
    })
    .then(res => {
      t.fail(res.toString())
    })
    .catch(err => {
      t.is(err.response.status, 409)
    })
    .finally(t.end)
})

test(`GET ${
  API_REPOS.PUBLIC
} should return list of all public repositories`, t => {
  axios
    .get(`http://localhost:${PORT}${API_REPOS.PUBLIC}`)
    .then(res => {
      const result = res.data.filter(r => r.name !== 'repo2')
      // console.log(require('util').inspect(result, false, null))
      t.deepEqual(result, [
        {
          owner: { login: 'user1' },
          name: 'repo1',
          full_name: 'user1/repo1'
        }
      ])
    })
    .catch(err => {
      console.error(err)
      t.fail(err.toString())
    })
    .finally(t.end)
})

test(`GET ${
  API_REPOS.USERS
} should return list of all specified user's repositories`, t => {
  axios
    .get(`http://localhost:${PORT}/api/v1/users/user1/repos`)
    .then(res => {
      const result = res.data.filter(r => r.name !== 'repo2')
      // console.log(require('util').inspect(result, false, null))
      t.deepEqual(result, [
        {
          owner: { login: 'user1' },
          name: 'repo1',
          full_name: 'user1/repo1'
        }
      ])
    })
    .catch(err => {
      console.error(err)
      t.fail(err.toString())
    })
    .finally(t.end)
})

test(`GET ${
  API_REPOS.USERS
} from users which have no repository should return empty list`, t => {
  axios
    .get(`http://localhost:${PORT}/api/v1/users/no_exists_user/repos`)
    .then(res => {
      // console.log(require('util').inspect(res.data, false, null))
      t.deepEqual(res.data, [])
    })
    .catch(err => {
      console.error(err)
      t.fail(err.toString())
    })
    .finally(t.end)
})

test.test('teardown', t => {
  app.close()
  t.end()
})
<commit_msg>Add types<commit_after>// @flow

import test from 'tape'
import axios from 'axios'
import bodyParser from 'body-parser'
import Express from 'express'
import fs from 'fs'
import path from 'path'
import rimraf from 'rimraf'

import { API_REPOS } from '../../../../../share/constants/api'
import reposRouter from './repos'
import config from '../../../../../../config.json'

const REPO_ROOT = config.env[process.env.NODE_ENV].REPO_ROOT

let app
let PORT
test.test('setup', t => {
  app = Express()
    .use(bodyParser.json())
    .use(reposRouter)
    .listen(0)
  PORT = app.address().port
  t.end()
})

test(`POST ${
  API_REPOS.LOGIN_USERS
} should return 201 when specified name repository does not exist`, t => {
  axios
    .post(`http://localhost:${PORT}${API_REPOS.LOGIN_USERS}`, {
      name: 'repo2',
      owner: 'DUMMY',
      authenticity_token: 'TRUE'
    })
    .then(res => {
      t.is(res.status, 201)
      t.is(fs.existsSync(path.join(REPO_ROOT, 'DUMMY', 'repo2')), true)
    })
    .catch(err => {
      console.error(err)
      t.fail(err.toString())
    })
    .then(() => {
      rimraf.sync(path.join(REPO_ROOT, 'DUMMY'))
      t.end()
    })
})

test(`POST ${
  API_REPOS.LOGIN_USERS
} should return 409 when specified name repository already exists`, t => {
  axios
    .post(`http://localhost:${PORT}${API_REPOS.LOGIN_USERS}`, {
      name: 'repo1',
      owner: 'user1',
      authenticity_token: 'TRUE'
    })
    .then(res => {
      t.fail(res.toString())
    })
    .catch(err => {
      t.is(err.response.status, 409)
    })
    .then(t.end)
})

test(`GET ${
  API_REPOS.PUBLIC
} should return list of all public repositories`, t => {
  axios
    .get(`http://localhost:${PORT}${API_REPOS.PUBLIC}`)
    .then(res => {
      const result = res.data.filter(r => r.name !== 'repo2')
      // console.log(require('util').inspect(result, false, null))
      t.deepEqual(result, [
        {
          owner: { login: 'user1' },
          name: 'repo1',
          full_name: 'user1/repo1'
        }
      ])
    })
    .catch(err => {
      console.error(err)
      t.fail(err.toString())
    })
    .then(t.end)
})

test(`GET ${
  API_REPOS.USERS
} should return list of all specified user's repositories`, t => {
  axios
    .get(`http://localhost:${PORT}/api/v1/users/user1/repos`)
    .then(res => {
      const result = res.data.filter(r => r.name !== 'repo2')
      // console.log(require('util').inspect(result, false, null))
      t.deepEqual(result, [
        {
          owner: { login: 'user1' },
          name: 'repo1',
          full_name: 'user1/repo1'
        }
      ])
    })
    .catch(err => {
      console.error(err)
      t.fail(err.toString())
    })
    .then(t.end)
})

test(`GET ${
  API_REPOS.USERS
} from users which have no repository should return empty list`, t => {
  axios
    .get(`http://localhost:${PORT}/api/v1/users/no_exists_user/repos`)
    .then(res => {
      // console.log(require('util').inspect(res.data, false, null))
      t.deepEqual(res.data, [])
    })
    .catch(err => {
      console.error(err)
      t.fail(err.toString())
    })
    .then(t.end)
})

test.test('teardown', t => {
  app.close()
  t.end()
})
<|endoftext|>


<commit_before>var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000 );

var renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
var cubeGeo = new THREE.BoxGeometry( 1, 1, 1 );
var silvMat = new THREE.MeshBasicMaterial({color:0xC0C0C0, wireframe:true});
var cubeMesh = new THREE.Mesh(cubeGeo,silvMat);
scene.add(cubeMesh);

const alien  = class{
  constructor(c,x,z){
    this.mat = new THREE.MeshBasicMaterial({color:c, wireframe:false});
    this.geo = new THREE.BoxGeometry( 1, 1, 1 );
    this.mesh = new THREE.Mesh(this.geo,this.mat);
    scene.add(this.mesh);
    this.mesh.position.x = x;
    this.mesh.position.z = z;
  }
  move(x,z){
    this.mesh.position.x += x;
    this.mesh.position.z += z;
  }
};

camera.position.z = 5;
camera.position.y = 5;
//camera.rotation.x = -Math.PI/4;
document.addEventListener('keyup', keyUp, false);
document.addEventListener('keydown', keyDown, false);
function keyUp(event) {
key[event.which || event.keyCode] = false;
}
function keyDown(event) {
key[event.which || event.keyCode] = true;
//console.log(event.which);
}
var rotation = 0;
var key = {
check: () => {
  if(key[65]) { //a
    cubeMesh.position.x -= 0.05;
    //console.log("left");
  }

  if(key[87]) { //w
    cubeMesh.position.z -= 0.05;
    //console.log("up");
  }

  if(key[68]) { //d
    cubeMesh.position.x += 0.05;
    //console.log("right");
  }

  if(key[83]) { //s
    cubeMesh.position.z += 0.05;
    //console.log("down");
  }
  if(key[69]){
    cubeMesh.position.y += 0.05;
  }
  if(key[81]){
    cubeMesh.position.y -= 0.05;
  }
  if(key[37]){
    rotation += 0.7;
    if(rotation>360){
      rotation = 0;
    }
  }
  if(key[39]){
    rotation -= 0.7;
    if(rotation<0){
      rotation = 360;
    }
  }
}
}
camera.position.z = 5*Math.cos((rotation*Math.PI)/180);
camera.position.x = 5*Math.sin((rotation*Math.PI)/180);
camera.rotation.x = 0;
camera.rotation.y = (rotation*Math.PI)/180;
camera.rotation.x = -Math.PI/4;
function tick(){
  /*cubeMesh.position.x += 0.01;
  cubeMesh.position.z += 0.01;*/
  key.check();

  //camera.rotation.y = 0;
  /*THE CAMERA CURRENTLY DOESNT WORK
  camera.position.z = 5*Math.cos((rotation*Math.PI)/180);
  camera.position.x = 5*Math.sin((rotation*Math.PI)/180);
  camera.rotation.x = 0;
 camera.rotation.y = (rotation*Math.PI)/180;
 camera.rotation.x = -Math.PI/4;
*/
  //this needs to be fixed
/*  camera.rotation.x = (rotation*Math.PI)/180;
  camera.rotation.z = -(rotation*Math.PI)/180;*/
  //console.log('tick');
  renderer.render( scene, camera );
}
var interval = setInterval(tick,30);
<commit_msg>Changed formatting and added kill method for alien class<commit_after>var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000 );

var renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
var cubeGeo = new THREE.BoxGeometry( 1, 1, 1 );
camera.position.z = 5;
camera.position.y = 5;
//camera.rotation.x = -Math.PI/4;
document.addEventListener('keyup', keyUp, false);
document.addEventListener('keydown', keyDown, false);
function keyUp(event) {
  key[event.which || event.keyCode] = false;
}
function keyDown(event) {
  key[event.which || event.keyCode] = true;
//console.log(event.which);
}
var rotation = 0;
var key = {
check: () => {
  if(key[65]) { //a
    cubeMesh.position.x -= 0.05;
    //console.log("left");
  }

  if(key[87]) { //w
    cubeMesh.position.z -= 0.05;
    //console.log("up");
  }

  if(key[68]) { //d
    cubeMesh.position.x += 0.05;
    //console.log("right");
  }

  if(key[83]) { //s
    cubeMesh.position.z += 0.05;
    //console.log("down");
  }
  if(key[69]){
    cubeMesh.position.y += 0.05;
  }
  if(key[81]){
    cubeMesh.position.y -= 0.05;
  }
  if(key[37]){
    rotation += 0.7;
    if(rotation>360){
      rotation = 0;
    }
  }
  if(key[39]){
    rotation -= 0.7;
    if(rotation<0){
      rotation = 360;
    }
  }
}
}
//the following is unnesasary, as it was previously used for camera rotating, but wasn't workings
camera.position.z = 5*Math.cos((rotation*Math.PI)/180);
camera.position.x = 5*Math.sin((rotation*Math.PI)/180);
camera.rotation.x = 0;
camera.rotation.y = (rotation*Math.PI)/180;
camera.rotation.x = -Math.PI/4;

const alien  = class{
  constructor(c,x,z){
    this.mat = new THREE.MeshBasicMaterial({color:c, wireframe:false});
    this.mesh = new THREE.Mesh(cubeGeo,this.mat);
    scene.add(this.mesh);
    this.mesh.position.x = x;
    this.mesh.position.z = z;
  }
  move(x,z){
    this.mesh.position.x += x;
    this.mesh.position.z += z;
  }
  kill(){
    scene.remove(this.mesh);
  }
};

function tick(){
  /*cubeMesh.position.x += 0.01;
  cubeMesh.position.z += 0.01;*/
  key.check();

  //camera.rotation.y = 0;
  /*THE CAMERA CURRENTLY DOESNT WORK
  camera.position.z = 5*Math.cos((rotation*Math.PI)/180);
  camera.position.x = 5*Math.sin((rotation*Math.PI)/180);
  camera.rotation.x = 0;
 camera.rotation.y = (rotation*Math.PI)/180;
 camera.rotation.x = -Math.PI/4;
*/
  //this needs to be fixed
/*  camera.rotation.x = (rotation*Math.PI)/180;
  camera.rotation.z = -(rotation*Math.PI)/180;*/
  //console.log('tick');
  renderer.render( scene, camera );
}
var interval = setInterval(tick,30);
<|endoftext|>


<commit_before>/*
 * moleculer
 * Copyright (c) 2018 MoleculerJS (https://github.com/moleculerjs/moleculer)
 * MIT Licensed
 */

"use strict";

const Promise = require("bluebird");
const BaseCacher = require("./base");
const _ = require('lodash')
/**
 * Cacher factory for Redis
 *
 * @class RedisCacher
 */
class RedisCacher extends BaseCacher {

	/**
	 * Creates an instance of RedisCacher.
	 *
	 * @param {object} opts
	 *
	 * @memberof RedisCacher
	 */
	constructor(opts) {
		if (typeof opts === "string")
			opts = { redis: opts };

		super(opts);
	}

	/**
	 * Initialize cacher. Connect to Redis server
	 *
	 * @param {any} broker
	 *
	 * @memberof RedisCacher
	 */
	init(broker) {
		super.init(broker);
		let Redis, Redlock;
		try {
			Redis = require("ioredis");
		} catch (err) {
			/* istanbul ignore next */
			this.broker.fatal("The 'ioredis' package is missing. Please install it with 'npm install ioredis --save' command.", err, true);
		}
		/**
		 * ioredis client instance
		 * @memberof RedisCacher
		 */
		if (this.opts.cluster) {
			if (!this.opts.clusterConnectionDetails) {
				throw new Error('No connection details defined for cluster')
			}

			this.logger.info("Setting Redis.Cluster Cacher");

			this.client = new Redis.Cluster(this.opts.clusterConnectionDetails, this.opts.clusterOptions);
		} else {
			this.logger.info("Setting Redis Cacher");

			this.client = new Redis(this.opts.redis);
		}

		this.client.on("connect", () => {
			/* istanbul ignore next */
			this.logger.info("Redis cacher connected.");
		});

		this.client.on("error", (err) => {
			/* istanbul ignore next */
			this.logger.error(err);
		});
		try {
			Redlock = require('redlock');
		} catch (err) {
			/* istanbul ignore next */
			this.logger.warn("The 'redlock' package is missing. If you want to enable cache lock, please install it with 'npm install redlock --save' command.");
		}
		if (Redlock) {
			let redlockClients = (this.opts.redlock ? this.opts.redlock.clients : null) || [this.client]
			/**
			 * redlock client instance
			 * @memberof RedisCacher
			 */
			this.redlock = new Redlock(
				redlockClients,
				_.omit(this.opts.redlock, ['clients'])
			);
			// Non-blocking redlock client, used for tryLock()
			this.redlockNonBlocking = new Redlock(
				redlockClients,
				{
					retryCount: 0
				}
			)
		}
		if (this.opts.monitor) {
			/* istanbul ignore next */
			this.client.monitor((err, monitor) => {
				this.logger.debug("Redis cacher entering monitoring mode...");
				monitor.on("monitor", (time, args/*, source, database*/) => {
					this.logger.debug(args);
				});
			});
		}

		this.logger.debug("Redis Cacher created. Prefix: " + this.prefix);
	}

	/**
	 * Close Redis client connection
	 *
	 * @memberof RedisCacher
	 */
	close() {
		return this.client.quit();
	}

	/**
	 * Get data from cache by key
	 *
	 * @param {any} key
	 * @returns {Promise}
	 *
	 * @memberof Cacher
	 */
	get(key) {
		this.logger.debug(`GET ${key}`);
		return this.client.get(this.prefix + key).then((data) => {
			if (data) {
				this.logger.debug(`FOUND ${key}`);
				try {
					return JSON.parse(data);
				} catch (err) {
					this.logger.error("Redis result parse error.", err, data);
				}
			}
			return null;
		});
	}

	/**
	 * Save data to cache by key
	 *
	 * @param {String} key
	 * @param {any} data JSON object
	 * @param {Number} ttl Optional Time-to-Live
	 * @returns {Promise}
	 *
	 * @memberof Cacher
	 */
	set(key, data, ttl) {
		data = JSON.stringify(data);
		this.logger.debug(`SET ${key}`);

		if (ttl == null)
			ttl = this.opts.ttl;

		if (ttl) {
			return this.client.setex(this.prefix + key, ttl, data);
		} else {
			return this.client.set(this.prefix + key, data);
		}
	}

	/**
	 * Delete a key from cache
	 *
	 * @param {string|Array<string>} deleteTargets
	 * @returns {Promise}
	 *
	 * @memberof Cacher
	 */
	del(deleteTargets) {
		deleteTargets = Array.isArray(deleteTargets) ? deleteTargets : [deleteTargets];
		const keysToDelete = deleteTargets.map(key => this.prefix + key);
		this.logger.debug(`DELETE ${keysToDelete}`);
		return this.client.del(keysToDelete).catch(err => {
			this.logger.error(`Redis 'del' error. Key: ${keysToDelete}`, err);
			throw err;
		});
	}

	/**
	 * Clean cache. Remove every key by prefix
	 *        http://stackoverflow.com/questions/4006324/how-to-atomically-delete-keys-matching-a-pattern-using-redis
	 * alternative solution:
	 *        https://github.com/cayasso/cacheman-redis/blob/master/lib/index.js#L125
	 * @param {String|Array<String>} match Match string for SCAN. Default is "*"
	 * @returns {Promise}
	 *
	 * @memberof Cacher
	 */
	clean(match = "*") {
		const cleaningPatterns = Array.isArray(match) ? match : [match];
		const normalizedPatterns = cleaningPatterns.map(match => this.prefix + match.replace(/\*\*/g, "*"));
		this.logger.debug(`CLEAN ${match}`);
		return this._sequentialPromises(normalizedPatterns)
			.catch((err) => {
				this.logger.error(`Redis 'scanDel' error. Pattern: ${err.pattern}`, err);
				throw err;
			});

	}

	/**
	 * Get data and ttl from cache by key.
	 *
	 * @param {string|Array<string>} key
	 * @returns {Promise}
	 *
	 * @memberof RedisCacher
	 */

	getWithTTL(key) {
		return this.client.pipeline().get(this.prefix + key).ttl(this.prefix + key).exec().then((res) => {
			let [err0, data] = res[0]
			let [err1, ttl] = res[1]
			if(err0){
				return Promise.reject(err0)
			}
			if(err1){
				return Promise.reject(err1)
			}
			if (data) {
				this.logger.debug(`FOUND ${key}`);
				try {
					data = JSON.parse(data);
				} catch (err) {
					this.logger.error("Redis result parse error.", err, data);
					data = null
				}
			}
			return { data, ttl }
		});
	}

	/**
	 * Acquire a lock
	 *
	 * @param {string|Array<string>} key
	 * @param {Number} ttl Optional Time-to-Live
	 * @returns {Promise}
	 *
	 * @memberof RedisCacher
	 */
	lock(key, ttl=15000) {
		key = this.prefix + key + "-lock"
		return this.redlock.lock(key, ttl).then(lock=>{
			return ()=>lock.unlock()
		})
	}

	/**
	 * Try to acquire a lock
	 *
	 * @param {string|Array<string>} key
	 * @param {Number} ttl Optional Time-to-Live
	 * @returns {Promise}
	 *
	 * @memberof RedisCacher
	 */
	tryLock(key, ttl=15000) {
		key = this.prefix + key + "-lock"
		return this.redlockNonBlocking.lock(key, ttl).then(lock=>{
			return ()=>lock.unlock()
		})
	}

	_sequentialPromises(elements) {
		return elements.reduce((chain, element) => {
			return chain.then(() => this._scanDel(element));
		}, Promise.resolve());
	}

	_scanDel(pattern) {
		return new Promise((resolve, reject) => {
			const stream = this.client.scanStream({
				match: pattern,
				count: 100
			});
			stream.on("data", (keys = []) => {
				if (!keys.length) {
					return;
				}

				stream.pause();
				this.client.del(keys)
					.then(() => {
						stream.resume();
					})
					.catch((err) => {
						err.pattern = pattern;
						return reject(err);
					});
			});
			stream.on("end", () => {
				resolve();
			});
		});
	}
}

module.exports = RedisCacher;
<commit_msg>not getting if not ready<commit_after>/*
 * moleculer
 * Copyright (c) 2018 MoleculerJS (https://github.com/moleculerjs/moleculer)
 * MIT Licensed
 */

"use strict";

const Promise = require("bluebird");
const BaseCacher = require("./base");
const _ = require('lodash')
/**
 * Cacher factory for Redis
 *
 * @class RedisCacher
 */
class RedisCacher extends BaseCacher {

	/**
	 * Creates an instance of RedisCacher.
	 *
	 * @param {object} opts
	 *
	 * @memberof RedisCacher
	 */
	constructor(opts) {
		if (typeof opts === "string")
			opts = { redis: opts };

		super(opts);
	}

	/**
	 * Initialize cacher. Connect to Redis server
	 *
	 * @param {any} broker
	 *
	 * @memberof RedisCacher
	 */
	init(broker) {
		super.init(broker);
		let Redis, Redlock;
		try {
			Redis = require("ioredis");
		} catch (err) {
			/* istanbul ignore next */
			this.broker.fatal("The 'ioredis' package is missing. Please install it with 'npm install ioredis --save' command.", err, true);
		}
		/**
		 * ioredis client instance
		 * @memberof RedisCacher
		 */
		if (this.opts.cluster) {
			if (!this.opts.clusterConnectionDetails) {
				throw new Error('No connection details defined for cluster')
			}

			this.logger.info("Setting Redis.Cluster Cacher");

			this.client = new Redis.Cluster(this.opts.clusterConnectionDetails, this.opts.clusterOptions);
		} else {
			this.logger.info("Setting Redis Cacher");

			this.client = new Redis(this.opts.redis);
		}

		this.client.on("connect", () => {
			/* istanbul ignore next */
			this.logger.info("Redis cacher connected.");
		});

		this.client.on("error", (err) => {
			/* istanbul ignore next */
			this.logger.error(err);
		});
		try {
			Redlock = require('redlock');
		} catch (err) {
			/* istanbul ignore next */
			this.logger.warn("The 'redlock' package is missing. If you want to enable cache lock, please install it with 'npm install redlock --save' command.");
		}
		if (Redlock) {
			let redlockClients = (this.opts.redlock ? this.opts.redlock.clients : null) || [this.client]
			/**
			 * redlock client instance
			 * @memberof RedisCacher
			 */
			this.redlock = new Redlock(
				redlockClients,
				_.omit(this.opts.redlock, ['clients'])
			);
			// Non-blocking redlock client, used for tryLock()
			this.redlockNonBlocking = new Redlock(
				redlockClients,
				{
					retryCount: 0
				}
			)
		}
		if (this.opts.monitor) {
			/* istanbul ignore next */
			this.client.monitor((err, monitor) => {
				this.logger.debug("Redis cacher entering monitoring mode...");
				monitor.on("monitor", (time, args/*, source, database*/) => {
					this.logger.debug(args);
				});
			});
		}

		this.logger.debug("Redis Cacher created. Prefix: " + this.prefix);
	}

	/**
	 * Close Redis client connection
	 *
	 * @memberof RedisCacher
	 */
	close() {
		return this.client.quit();
	}

	/**
	 * Get data from cache by key
	 *
	 * @param {any} key
	 * @returns {Promise}
	 *
	 * @memberof Cacher
	 */
	get(key) {
		if (!this.client || this.client.status !== 'ready') {
			this.logger.info('Could not get from redis cacher at the moment')

			return Promise.resolve();
		}
		this.logger.debug(`GET ${key}`);
		return this.client.get(this.prefix + key).then((data) => {
			if (data) {
				this.logger.debug(`FOUND ${key}`);
				try {
					return JSON.parse(data);
				} catch (err) {
					this.logger.error("Redis result parse error.", err, data);
				}
			}
			return null;
		});
	}

	/**
	 * Save data to cache by key
	 *
	 * @param {String} key
	 * @param {any} data JSON object
	 * @param {Number} ttl Optional Time-to-Live
	 * @returns {Promise}
	 *
	 * @memberof Cacher
	 */
	set(key, data, ttl) {
		data = JSON.stringify(data);
		this.logger.debug(`SET ${key}`);

		if (ttl == null)
			ttl = this.opts.ttl;

		if (ttl) {
			return this.client.setex(this.prefix + key, ttl, data);
		} else {
			return this.client.set(this.prefix + key, data);
		}
	}

	/**
	 * Delete a key from cache
	 *
	 * @param {string|Array<string>} deleteTargets
	 * @returns {Promise}
	 *
	 * @memberof Cacher
	 */
	del(deleteTargets) {
		deleteTargets = Array.isArray(deleteTargets) ? deleteTargets : [deleteTargets];
		const keysToDelete = deleteTargets.map(key => this.prefix + key);
		this.logger.debug(`DELETE ${keysToDelete}`);
		return this.client.del(keysToDelete).catch(err => {
			this.logger.error(`Redis 'del' error. Key: ${keysToDelete}`, err);
			throw err;
		});
	}

	/**
	 * Clean cache. Remove every key by prefix
	 *        http://stackoverflow.com/questions/4006324/how-to-atomically-delete-keys-matching-a-pattern-using-redis
	 * alternative solution:
	 *        https://github.com/cayasso/cacheman-redis/blob/master/lib/index.js#L125
	 * @param {String|Array<String>} match Match string for SCAN. Default is "*"
	 * @returns {Promise}
	 *
	 * @memberof Cacher
	 */
	clean(match = "*") {
		const cleaningPatterns = Array.isArray(match) ? match : [match];
		const normalizedPatterns = cleaningPatterns.map(match => this.prefix + match.replace(/\*\*/g, "*"));
		this.logger.debug(`CLEAN ${match}`);
		return this._sequentialPromises(normalizedPatterns)
			.catch((err) => {
				this.logger.error(`Redis 'scanDel' error. Pattern: ${err.pattern}`, err);
				throw err;
			});

	}

	/**
	 * Get data and ttl from cache by key.
	 *
	 * @param {string|Array<string>} key
	 * @returns {Promise}
	 *
	 * @memberof RedisCacher
	 */

	getWithTTL(key) {
		return this.client.pipeline().get(this.prefix + key).ttl(this.prefix + key).exec().then((res) => {
			let [err0, data] = res[0]
			let [err1, ttl] = res[1]
			if(err0){
				return Promise.reject(err0)
			}
			if(err1){
				return Promise.reject(err1)
			}
			if (data) {
				this.logger.debug(`FOUND ${key}`);
				try {
					data = JSON.parse(data);
				} catch (err) {
					this.logger.error("Redis result parse error.", err, data);
					data = null
				}
			}
			return { data, ttl }
		});
	}

	/**
	 * Acquire a lock
	 *
	 * @param {string|Array<string>} key
	 * @param {Number} ttl Optional Time-to-Live
	 * @returns {Promise}
	 *
	 * @memberof RedisCacher
	 */
	lock(key, ttl=15000) {
		key = this.prefix + key + "-lock"
		return this.redlock.lock(key, ttl).then(lock=>{
			return ()=>lock.unlock()
		})
	}

	/**
	 * Try to acquire a lock
	 *
	 * @param {string|Array<string>} key
	 * @param {Number} ttl Optional Time-to-Live
	 * @returns {Promise}
	 *
	 * @memberof RedisCacher
	 */
	tryLock(key, ttl=15000) {
		key = this.prefix + key + "-lock"
		return this.redlockNonBlocking.lock(key, ttl).then(lock=>{
			return ()=>lock.unlock()
		})
	}

	_sequentialPromises(elements) {
		return elements.reduce((chain, element) => {
			return chain.then(() => this._scanDel(element));
		}, Promise.resolve());
	}

	_scanDel(pattern) {
		return new Promise((resolve, reject) => {
			const stream = this.client.scanStream({
				match: pattern,
				count: 100
			});
			stream.on("data", (keys = []) => {
				if (!keys.length) {
					return;
				}

				stream.pause();
				this.client.del(keys)
					.then(() => {
						stream.resume();
					})
					.catch((err) => {
						err.pattern = pattern;
						return reject(err);
					});
			});
			stream.on("end", () => {
				resolve();
			});
		});
	}
}

module.exports = RedisCacher;
<|endoftext|>


<commit_before>import React, { Component } from 'react'
import ReactModal from 'react-modal';
import assign from 'object-assign'

export default class Modal extends Component {
  constructor(props){
    super(props);
    this.style = {
      content : {
        top                   : '50%',
        left                  : '50%',
        right                 : 'auto',
        bottom                : 'auto',
        marginRight           : '-50%',
        transform             : 'translate(-50%, -50%)'
      },
      overlay: {
        zIndex                : '10010'
      }
    };
  }

  componentWillMount() {
    ReactModal.setAppElement('body');
  }

  componentWillReceiveProps(nextProps){
    if(nextProps.style){
      if(nextProps.style.content){
        this.style.content = assign(this.style.content, nextProps.style.content);
      }

      if(nextProps.style.overlay){
        this.style.overlay = assign(this.style.overlay, nextProps.style.overlay);
      }
    }
  }

  render() {
    return (
      <ReactModal
        isOpen={this.props.isOpen}
        contentLabel={this.props.contentLabel}
        style={this.style}
        closeTimeoutMS={this.props.closeTimeoutMS}
        onRequestClose={this.props.onRequestClose}
        onAfterOpen={this.props.onAfterOpen}
        parentSelector={this.props.parentSelector}
      >
        {this.props.children}
      </ReactModal>
    )
  }
}
<commit_msg>propsにstyleが指定されている場合はデフォルトスタイルにマージします<commit_after>import React, { Component } from 'react'
import ReactModal from 'react-modal';
import assign from 'object-assign'

export default class Modal extends Component {
  constructor(props){
    super(props);
    this.style = {
      content : {
        top                   : '50%',
        left                  : '50%',
        right                 : 'auto',
        bottom                : 'auto',
        marginRight           : '-50%',
        transform             : 'translate(-50%, -50%)'
      },
      overlay: {
        zIndex                : '10010'
      }
    };
    if (this.props.style){
      if(this.props.style.content){
        this.style.content = assign(this.style.content, this.props.style.content);
      }

      if(this.props.style.overlay){
        this.style.overlay = assign(this.style.overlay, this.props.style.overlay);
      }
    }
  }

  componentWillMount() {
    ReactModal.setAppElement('body');
  }

  componentWillReceiveProps(nextProps){
    if(nextProps.style){
      if(nextProps.style.content){
        this.style.content = assign(this.style.content, nextProps.style.content);
      }

      if(nextProps.style.overlay){
        this.style.overlay = assign(this.style.overlay, nextProps.style.overlay);
      }
    }
  }

  render() {
    return (
      <ReactModal
        isOpen={this.props.isOpen}
        contentLabel={this.props.contentLabel}
        style={this.style}
        closeTimeoutMS={this.props.closeTimeoutMS}
        onRequestClose={this.props.onRequestClose}
        onAfterOpen={this.props.onAfterOpen}
        parentSelector={this.props.parentSelector}
      >
        {this.props.children}
      </ReactModal>
    )
  }
}
<|endoftext|>


<commit_before>module.exports = {

};
<commit_msg>Implement user aware notifications controller<commit_after>module.exports = {

  find: function(req, res) {
    return res.badRequest('List notifications is not supported');
  },

  findOne: function(req, res) {
    return Notification.findOne({
      id: req.params.id,
    }).then(notification => {
      if (notification) {
        return Job.findOne({
          id: notification.job,
          user: req.session.passport.user
        }).then(job => {
          if (job) {
            return res.ok(notification);
          } else {
            return res.notFound();
          }
        });
      } else {
        return res.notFound();
      }
    });
  },

  create: function(req, res) {
    var body = req.body || {};
    return Job.findOne({
      id: body.job,
      user: req.session.passport.user
    }).then(job => {
      if (job) {
        return Notification.create({
          name: body.name,
          exportType: body.exportType,
          data: body.data,
          job: body.job
        }).then(notification => {
          return res.ok(notification);
        }).catch(err => {
          return res.badRequest('Invalid attributes: ' + Object.keys(err.invalidAttributes).join(', '));
        });
      } else {
        return res.badRequest('Invalid job ID ' + body.job);
      }
    });
  },

  update: function(req, res) {
    var body = req.body || {};
    return Job.findOne({
      id: body.job,
      user: req.session.passport.user
    }).then(job => {
      if (job) {
        return Notification.findOne({
          id: req.params.id
        }).then(notification => {
          if (notification) {
            notification.name = body.name;
            notification.timeout = body.exportType;
            notification.data = body.data;
            return notification.save().then(() => {
              return res.ok(notification);
            });
          } else {
            res.notFound();
          }
        }).catch(err => {
          return res.badRequest('Invalid attributes: ' + Object.keys(err.invalidAttributes).join(', '));
        });
      } else {
        return res.badRequest('Invalid job ID ' + body.job);
      }
    });
  },

  destroy: function(req, res) {
    return Notification.findOne({
      id: req.params.id
    }).then(notification => {
      if (notification) {
        Job.findOne({
          id: notification.job,
          user: req.session.passport.user
        }).then(job => {
          if (job) {
            return notification.destroy().then(() => {
              return res.ok(notification);
            });
          } else {
            return res.notFound();
          }
        });
      } else {
        return res.notFound();
      }
    });
  }

};
<|endoftext|>


<commit_before>odoo.define('pos_discount.pos_discount', function (require) {
"use strict";

var core = require('web.core');
var screens = require('point_of_sale.screens');

var _t = core._t;

var DiscountButton = screens.ActionButtonWidget.extend({
    template: 'DiscountButton',
    button_click: function(){
        var self = this;
        this.gui.show_popup('number',{
            'title': _t('Discount Percentage'),
            'value': this.pos.config.discount_pc,
            'confirm': function(val) {
                val = Math.round(Math.max(0,Math.min(100,val)));
                self.apply_discount(val);
            },
        });
    },
    apply_discount: function(pc) {
        var order    = this.pos.get_order();
        var lines    = order.get_orderlines();
        var product  = this.pos.db.get_product_by_id(this.pos.config.discount_product_id[0]);
        if (product === undefined) {
            this.gui.show_popup('error', {
                title : _t("No discount product found"),
                body  : _t("The discount product seems misconfigured. Make sure it is flagged as 'Can be Sold' and 'Available in Point of Sale'."),
            });
            return;
        }

        // Remove existing discounts
        var i = 0;
        while ( i < lines.length ) {
            if (lines[i].get_product() === product) {
                order.remove_orderline(lines[i]);
            } else {
                i++;
            }
        }

        // Add discount
        var discount = - pc / 100.0 * order.get_total_with_tax();

        if( discount < 0 ){
            order.add_product(product, { price: discount });
        }
    },
});

screens.define_action_button({
    'name': 'discount',
    'widget': DiscountButton,
    'condition': function(){
        return this.pos.config.module_pos_discount && this.pos.config.discount_product_id;
    },
});

});
<commit_msg>[FIX] pos_discount: change customer<commit_after>odoo.define('pos_discount.pos_discount', function (require) {
"use strict";

var core = require('web.core');
var screens = require('point_of_sale.screens');

var _t = core._t;

var DiscountButton = screens.ActionButtonWidget.extend({
    template: 'DiscountButton',
    button_click: function(){
        var self = this;
        this.gui.show_popup('number',{
            'title': _t('Discount Percentage'),
            'value': this.pos.config.discount_pc,
            'confirm': function(val) {
                val = Math.round(Math.max(0,Math.min(100,val)));
                self.apply_discount(val);
            },
        });
    },
    apply_discount: function(pc) {
        var order    = this.pos.get_order();
        var lines    = order.get_orderlines();
        var product  = this.pos.db.get_product_by_id(this.pos.config.discount_product_id[0]);
        if (product === undefined) {
            this.gui.show_popup('error', {
                title : _t("No discount product found"),
                body  : _t("The discount product seems misconfigured. Make sure it is flagged as 'Can be Sold' and 'Available in Point of Sale'."),
            });
            return;
        }

        // Remove existing discounts
        var i = 0;
        while ( i < lines.length ) {
            if (lines[i].get_product() === product) {
                order.remove_orderline(lines[i]);
            } else {
                i++;
            }
        }

        // Add discount
        // We add the price as manually set to avoid recomputation when changing customer.
        var discount = - pc / 100.0 * order.get_total_with_tax();

        if( discount < 0 ){
            order.add_product(product, {
                price: discount,
                extras: {
                    price_manually_set: true,
                },
            });
        }
    },
});

screens.define_action_button({
    'name': 'discount',
    'widget': DiscountButton,
    'condition': function(){
        return this.pos.config.module_pos_discount && this.pos.config.discount_product_id;
    },
});

});
<|endoftext|>


<commit_before>! function ()
{
  var opt = { fileUpload: '#show-me-the-attachment-button', buttons: ['html'] }

  opt.buttons.add = function (split)
  {
    this.push ('|'); this.push.apply (this, split.split (' ')); return this
  }
  opt.buttons
  .add ('formatting')
  .add ('bold italic underline')
  .add ('unorderedlist orderedlist')
  .add ('outdent indent')
  .add ('video image file link table')
  .add ('alignleft aligncenter alignright justify')
  .add ('horizontalrule')

  $ (function () { $ ('[koi-wysiwyg]').liveQuery (run) })

  function run ()
  {
    var app, $box, $editor, $toolBar
    var $win = $ (window), $textArea = $ (this), $form = $textArea.closest ('form')
    var iFrame, iQuery, iWindow, iDocument, iHead, iBody, iScript, iStyle, iTextArea

    $textArea.hide ().closest ('form').on ('submit', submit)

    iFrame = $ ('').insertAfter ($textArea).load (loadFrame)
    .attr ('src'          , '/wysiwyg.html')
    .attr ('width'        , '100%')
    .attr ('height'       , '100%')
    .attr ('marginheight' , '0')
    .attr ('marginheight' , '0')
    .css  ('borderWidth'  , '0')
    .css  ('borderStyle'  , 'none')

    function submit ()
    {
      $editor.find ('img').each (function ()
      {
        var $img     = $ (this)
        var src      = $img.attr ('src').split ('?')
        var path     = src [0]
        var params   = src [1]
        var deparams = params ? $.deparam (params) : {}
        if (params)
        {
          for (var dim in { width:true, height:true }) deparams [dim] = parseInt ($img.css (dim))
          $img.attr ('src', path + '?' + $.param (deparams))
        }
        else $img.attr ('style', '');
      })
      if (iTextArea.is (':hidden')) app.syncCode ()
      else app.toggle ()
      $textArea.val ($editor[0].innerHTML.replace (/(<[^\/][^>]*>)
/, function ($0, $1) { return $1 })
                                         .replace (/cursor\s*:\s*default;?/, ''))
      //$textArea.val (iTextArea.val ().replace (/(\s* \s*)+/g, ' '))
    }

    function resize_body ()
    {
      iFrame.height ($ (iBody).outerHeight () + $toolBar.outerHeight ())
    }

    var diffo

    function resize_document ()
    {
      if (diffo == null) diffo = $ (iDocument).outerHeight () - $ (iBody).outerHeight ()
      iTextArea.height (app.opts.visual ? $editor.height () : iTextArea [0].scrollHeight)
      iFrame.height ($ (iBody).outerHeight () + diffo)
    }

    function resizer ()
    {
      resize_body (); resizer = resize_document;
    }

    function resize (e)
    {
      resizer (); setTimeout (function () { resizer () })
    }

    function loadFrame ()
    {
      iWindow   = iFrame.contentWindow ()
      iDocument = iFrame.contentDocument ()

      iHead     = iDocument.getElementsByTagName ('head') [0]
      iBody     = iDocument.getElementsByTagName ('body') [0]

      iTextArea = iDocument.createElement ('textarea')
      iTextArea.value = $textArea.val ()
      iBody.appendChild (iTextArea)

      iStyle       = iDocument.createElement ('link')
      iStyle.rel   = 'stylesheet'
      iStyle.type  = 'text/css'
      iStyle.media = 'screen'
      iStyle.href  = '/assets/koi/jquery/redactor.css'
      iHead.appendChild (iStyle)

      iScript      = iDocument.createElement ('script')
      iScript.type = 'text/javascript'
      iScript.src  = '/assets/koi.js'

      // Handle Script loading
      var done = false;

      // Attach handlers for all browsers
      iScript.onload = iScript.onreadystatechange = function ()
      {
        if (! done && (! this.readyState || this.readyState == 'loaded' || this.readyState == 'complete'))
        {
          done = true
          loadScript ()

          // Handle memory leak in IE:
          iScript.onload = iScript.onreadystatechange = null
          if (iHead && iScript.parentNode) iHead.removeChild (iScript)
        }
      }

      iHead.appendChild (iScript)

      $ (iBody).css ({ padding:0, margin:0 }).on ('click keydown', resize)

      //$ (iScript).load (loadScript)
    }

    function loadScript ()
    {
      iBody = iWindow.$ (iBody)
      iTextArea = iWindow.$ (iTextArea)
      // iScript [0].onload = (load_iScript)

      app = iTextArea.redactor (opt).data ().redactor

      $box = iFrame
      $editor = app.$editor.css ({ minHeight: 300, padding:0, margin:0 })
      $toolBar = app.$toolbar

      var sushiBar = $toolBar.sushi ('css')

      sushiBar.set ({ boxSizing: 'border-box', width:'100%' })

      sushiBar.stopScrolling = function ()
      {
        var boxWidth  = $editor.outerWidth ()
        this.set ({ position:'absolute', zIndex:1, left:0, top:0, width:'100%' })
      }

      sushiBar.startScrolling = function ()
      {
        var boxTop    = $box.offset ().top
        var scrollTop = $win.scrollTop ()
        this.set ({ top: scrollTop - boxTop + 43 })
      }

      sushiBar.isScrolling = function ()
      {
        var boxTop    = $box.offset ().top
        var boxHeight = $box.height ()
        var boxBottom = boxHeight + boxTop - 44 - 32
        var scrollTop = $win.scrollTop ()
        var top       = scrollTop + $toolBar.height ()
        return boxTop < top && top < boxBottom
      }
      sushiBar.stopScrolling ()
      sushiBar.startScrolling ()

      function reposition ()
      {
        sushiBar [sushiBar.isScrolling () ? 'startScrolling' : 'stopScrolling'] ()
        setTimeout (function () { sushiBar [sushiBar.isScrolling () ? 'startScrolling' : 'stopScrolling'] () })
      }

      $ (window).ready (function (e)
      {
        resize (e); reposition (e);
        setTimeout (function () { resize (e); reposition (e); })
      })

      $ (window).on ('resize scroll', reposition)

      var __toggle = app.toggle

      app.toggle = function ()
      {
        var scrollTop = $win.scrollTop ()
        __toggle.apply (this, arguments)
        setTimeout (resize)
        $win.scrollTop (scrollTop)
      }

      app.showImage = function ()
      {
        this.saveSelection ()
        $.modal.call (this, '/admin/images/new', function (url)
        {
          this._imageSet ("", true)
        })
      }

      app.showFile = function ()
      {
        this.saveSelection()

        if ($ (this.getParentNode ()).is ('a')) this.showLink ()

        else $.modal.call (this, '/admin/documents/new', function (url)
        {
          var fileName = url.match (/[^\/]+$/).toString () || '...'
          if ($.browser.msie) this.restoreSelection()
          this.execCommand ('inserthtml', "" + fileName + "")
          if (! $.browser.msie) this.showLink ()
        })
      }

      $toolBar.before ($ ('

').css ({ height:'32px' }))
    }
  }

} ()

<commit_msg>Better HTML cleanup for Wysiwyg.<commit_after>! function ()
{
  var opt = { fileUpload: '#show-me-the-attachment-button', buttons: ['html'] }

  opt.buttons.add = function (split)
  {
    this.push ('|'); this.push.apply (this, split.split (' ')); return this
  }
  opt.buttons
  .add ('formatting')
  .add ('bold italic underline')
  .add ('unorderedlist orderedlist')
  .add ('outdent indent')
  .add ('video image file link table')
  .add ('alignleft aligncenter alignright justify')
  .add ('horizontalrule')

  $ (function () { $ ('[koi-wysiwyg]').liveQuery (run) })

  function run ()
  {
    var app, $box, $editor, $toolBar
    var $win = $ (window), $textArea = $ (this), $form = $textArea.closest ('form')
    var iFrame, iQuery, iWindow, iDocument, iHead, iBody, iScript, iStyle, iTextArea

    $textArea.hide ().closest ('form').on ('submit', submit)

    iFrame = $ ('').insertAfter ($textArea).load (loadFrame)
    .attr ('src'          , '/wysiwyg.html')
    .attr ('width'        , '100%')
    .attr ('height'       , '100%')
    .attr ('marginheight' , '0')
    .attr ('marginheight' , '0')
    .css  ('borderWidth'  , '0')
    .css  ('borderStyle'  , 'none')

    function submit ()
    {
      $editor.find ('img').each (function ()
      {
        var $img     = $ (this)
        var src      = $img.attr ('src').split ('?')
        var path     = src [0]
        var params   = src [1]
        var deparams = params ? $.deparam (params) : {}
        if (params)
        {
          for (var dim in { width:true, height:true }) deparams [dim] = parseInt ($img.css (dim))
          $img.attr ('src', path + '?' + $.param (deparams))
        }
        else $img.attr ('style', '');
      })
      if (iTextArea.is (':hidden')) app.syncCode ()
      else app.toggle ()
      $textArea.val ($editor[0].innerHTML.replace (/(<\w[^>]*>)\s*
/gi, function ($0, $1) { return $1 + ' ' })
                                         .replace (/(<\/[^>]*>)\s* /gi, function ($0, $1) { return $1 + ' ' })
                                         .replace (/
\s*<\/p>/gi, '')
                                         .replace (/cursor\s*:\s*default;?/gi, ''))
      //$textArea.val (iTextArea.val ().replace (/(\s* \s*)+/g, ' '))
    }

    function resize_body ()
    {
      iFrame.height ($ (iBody).outerHeight () + $toolBar.outerHeight ())
    }

    var diffo

    function resize_document ()
    {
      if (diffo == null) diffo = $ (iDocument).outerHeight () - $ (iBody).outerHeight ()
      iTextArea.height (app.opts.visual ? $editor.height () : iTextArea [0].scrollHeight)
      iFrame.height ($ (iBody).outerHeight () + diffo)
    }

    function resizer ()
    {
      resize_body (); resizer = resize_document;
    }

    function resize (e)
    {
      resizer (); setTimeout (function () { resizer () })
    }

    function loadFrame ()
    {
      iWindow   = iFrame.contentWindow ()
      iDocument = iFrame.contentDocument ()

      iHead     = iDocument.getElementsByTagName ('head') [0]
      iBody     = iDocument.getElementsByTagName ('body') [0]

      iTextArea = iDocument.createElement ('textarea')
      iTextArea.value = $textArea.val ()
      iBody.appendChild (iTextArea)

      iStyle       = iDocument.createElement ('link')
      iStyle.rel   = 'stylesheet'
      iStyle.type  = 'text/css'
      iStyle.media = 'screen'
      iStyle.href  = '/assets/koi/jquery/redactor.css'
      iHead.appendChild (iStyle)

      iScript      = iDocument.createElement ('script')
      iScript.type = 'text/javascript'
      iScript.src  = '/assets/koi.js'

      // Handle Script loading
      var done = false;

      // Attach handlers for all browsers
      iScript.onload = iScript.onreadystatechange = function ()
      {
        if (! done && (! this.readyState || this.readyState == 'loaded' || this.readyState == 'complete'))
        {
          done = true
          loadScript ()

          // Handle memory leak in IE:
          iScript.onload = iScript.onreadystatechange = null
          if (iHead && iScript.parentNode) iHead.removeChild (iScript)
        }
      }

      iHead.appendChild (iScript)

      $ (iBody).css ({ padding:0, margin:0 }).on ('click keydown', resize)

      //$ (iScript).load (loadScript)
    }

    function loadScript ()
    {
      iBody = iWindow.$ (iBody)
      iTextArea = iWindow.$ (iTextArea)
      // iScript [0].onload = (load_iScript)

      app = iTextArea.redactor (opt).data ().redactor

      $box = iFrame
      $editor = app.$editor.css ({ minHeight: 300, padding:0, margin:0 })
      $toolBar = app.$toolbar

      var sushiBar = $toolBar.sushi ('css')

      sushiBar.set ({ boxSizing: 'border-box', width:'100%' })

      sushiBar.stopScrolling = function ()
      {
        var boxWidth  = $editor.outerWidth ()
        this.set ({ position:'absolute', zIndex:1, left:0, top:0, width:'100%' })
      }

      sushiBar.startScrolling = function ()
      {
        var boxTop    = $box.offset ().top
        var scrollTop = $win.scrollTop ()
        this.set ({ top: scrollTop - boxTop + 43 })
      }

      sushiBar.isScrolling = function ()
      {
        var boxTop    = $box.offset ().top
        var boxHeight = $box.height ()
        var boxBottom = boxHeight + boxTop - 44 - 32
        var scrollTop = $win.scrollTop ()
        var top       = scrollTop + $toolBar.height ()
        return boxTop < top && top < boxBottom
      }
      sushiBar.stopScrolling ()
      sushiBar.startScrolling ()

      function reposition ()
      {
        sushiBar [sushiBar.isScrolling () ? 'startScrolling' : 'stopScrolling'] ()
        setTimeout (function () { sushiBar [sushiBar.isScrolling () ? 'startScrolling' : 'stopScrolling'] () })
      }

      $ (window).ready (function (e)
      {
        resize (e); reposition (e);
        setTimeout (function () { resize (e); reposition (e); })
      })

      $ (window).on ('resize scroll', reposition)

      var __toggle = app.toggle

      app.toggle = function ()
      {
        var scrollTop = $win.scrollTop ()
        __toggle.apply (this, arguments)
        setTimeout (resize)
        $win.scrollTop (scrollTop)
      }

      app.showImage = function ()
      {
        this.saveSelection ()
        $.modal.call (this, '/admin/images/new', function (url)
        {
          this._imageSet ("", true)
        })
      }

      app.showFile = function ()
      {
        this.saveSelection()

        if ($ (this.getParentNode ()).is ('a')) this.showLink ()

        else $.modal.call (this, '/admin/documents/new', function (url)
        {
          var fileName = url.match (/[^\/]+$/).toString () || '...'
          if ($.browser.msie) this.restoreSelection()
          this.execCommand ('inserthtml', "" + fileName + "")
          if (! $.browser.msie) this.showLink ()
        })
      }

      $toolBar.before ($ ('

').css ({ height:'32px' }))
    }
  }

} ()

<|endoftext|>