<commit_before>// Generated on <%= (new Date).toISOString().split('T')[0] %> using <%= pkg.name %> <%= pkg.version %>
'use strict';

// Directory reference:
//   css: <%= cssDir %><% if (cssPre) { %>
//   <%= cssPre %>: <%= cssPreDir %><% } %>
//   javascript: <%= jsDir %><% if (jsPre) { %>
//   <%= jsPre %>: <%= jsPreDir %><% } %>
//   images: <%= imgDir %>
//   fonts: <%= fontsDir %>

module.exports = function (grunt) {
  // Show elapsed time after tasks run
  require('time-grunt')(grunt);
  // Load all Grunt tasks
  require('load-grunt-tasks')(grunt);

  grunt.initConfig({
    // Configurable paths
    yeoman: {
      app: 'app',
      dist: 'dist'
    },
    watch: {<% if (cssPre === 'sass' || cssPre === 'compass' ) { %>
      <%= cssPre %>: {
        files: ['<%%= yeoman.app %>/<%= cssPreDir %>/**/*.{scss,sass}'],
        tasks: ['<%= cssPre %>:server'<% if (autoPre) { %>, 'autoprefixer:dist'<% } %>]
      },<% } %><% if (autoPre) { %>
      autoprefixer: {
        files: ['<%%= yeoman.app %>/<%= cssDir %>/**/*.css'],
        tasks: ['copy:stageCss', 'autoprefixer:dist']
      },<% } %><% if (jsPre === 'coffeescript') { %>
      coffee: {
        files: ['<%%= yeoman.app %>/<%= jsPreDir %>/**/*.coffee'],
        tasks: ['coffee:dist']
      },
      coffeeTest: {
        files: ['test/spec/**/*.coffee'],
        tasks: ['coffee:test']
      },<% } %>
      jekyll: {
        files: [
          '<%%= yeoman.app %>/**/*.{html,yml,md,mkd,markdown}',
          '!<%%= yeoman.app %>/_bower_components/**/*'
        ],
        tasks: ['jekyll:server']
      }
    },
    browserSync: {
      server: {
        bsFiles: {
          src: [
            '.jekyll/**/*.html',
            '.tmp/css/**/*.css',
            '{.tmp,<%%= yeoman.app %>}/<%= js %>/**/*.js',
            '{<%%= yeoman.app %>}/_bower_components/**/*.js',
            '<%%= yeoman.app %>/img/**/*.{gif,jpg,jpeg,png,svg,webp}'
          ]
        },
        options: {
          server: {
            baseDir: [
              ".jekyll",
              ".tmp",
              "<%%= yeoman.app %>"
            ]
          },
          watchTask: true
        }
      },
      dist: {
        options: {
          server: {
            baseDir: "<%%= yeoman.dist %>"
          }
        }
      },
      test: {
        bsFiles: {
          src: [
            '.jekyll/**/*.html',
            '.tmp/css/**/*.css',
            '{.tmp,<%%= yeoman.app %>}/<%= js %>/**/*.js',
            '{<%%= yeoman.app %>}/_bower_components/**/*.js',
            '<%%= yeoman.app %>/img/**/*.{gif,jpg,jpeg,png,svg,webp}'
          ]
        },
        options: {
          server: {
            baseDir: [
              ".jekyll",
              ".tmp",
              "<%%= yeoman.app %>"
            ]
          },
          watchTask: true
        }
      }
    },
    clean: {
      dist: {
        files: [{
          dot: true,
          src: [
            '<%%= yeoman.dist %>/*',
            // Running Jekyll also cleans the target directory.  Exclude any
            // non-standard `keep_files` here (e.g., the generated files
            // directory from Jekyll Picture Tag).
            '!<%%= yeoman.dist %>/.git*'
          ]
        }]
      },
      server: [
        '.tmp',
        '.jekyll'
      ]
    },<% if (cssPre === 'sass') { %>
    sass: {
      options: {
        bundleExec: true,
        debugInfo: false,
        lineNumbers: false,
        loadPath: 'app/_bower_components'
      },
      dist: {
        files: [{
          expand: true,
          cwd: '<%%= yeoman.app %>/<%= cssPreDir %>',
          src: '**/*.{scss,sass}',
          dest: '.tmp/<%= cssDir %>',
          ext: '.css'
        }]
      },
      server: {
        options: {
          debugInfo: true,
          lineNumbers: true
        },
        files: [{
          expand: true,
          cwd: '<%%= yeoman.app %>/<%= cssPreDir %>',
          src: '**/*.{scss,sass}',
          dest: '.tmp/<%= cssDir %>',
          ext: '.css'
        }]
      }
    },<% } %><% if (cssPre === 'compass') { %>
    compass: {
      options: {
        // If you're using global Sass gems, require them here.
        // require: ['singularity', 'jacket'],
        bundleExec: true,
        sassDir: '<%%= yeoman.app %>/<%= cssPreDir %>',
        cssDir: '.tmp/<%= cssDir %>',
        imagesDir: '<%%= yeoman.app %>/<%= imgDir %>',
        javascriptsDir: '<%%= yeoman.app %>/<%= jsDir %>',
        relativeAssets: false,
        httpImagesPath: '/<%= imgDir %>',
        httpGeneratedImagesPath: '/<%= imgDir %>/generated',
        outputStyle: 'expanded',
        raw: 'extensions_dir = "<%%= yeoman.app %>/_bower_components"\n'
      },
      dist: {
        options: {
          generatedImagesDir: '<%%= yeoman.dist %>/<%= imgDir %>/generated'
        }
      },
      server: {
        options: {
          debugInfo: true,
          generatedImagesDir: '.tmp/<%= imgDir %>/generated'
        }
      }
    },<% } %><% if (autoPre) { %>
    autoprefixer: {
      options: {
        browsers: ['last 2 versions']
      },
      dist: {
        expand: true,
        cwd: '.tmp',
        src: '**/{<%= cssDir %>,concat}/*.css',
        dest: '.tmp'
      }
    },<% } %><% if (jsPre === 'coffeescript') { %>
    coffee: {
      dist: {
        files: [{
          expand: true,
          cwd: '<%%= yeoman.app %>/<%= jsPreDir %>',
          src: '**/*.coffee',
          dest: '.tmp/<%= jsDir %>',
          ext: '.js'
        }]
      },
      test: {
        files: [{
          expand: true,
          cwd: 'test/spec',
          src: '**/*.coffee',
          dest: '.tmp/spec',
          ext: '.js'
        }]
      }
    },<% } %>
    jekyll: {
      options: {
        bundleExec: true,
        config: '_config.yml,_config.build.yml',
        src: '<%%= yeoman.app %>'
      },
      dist: {
        options: {
          dest: '<%%= yeoman.dist %>',
        }
      },
      server: {
        options: {
          config: '_config.yml',
          dest: '.jekyll'
        }
      },
      check: {
        options: {
          doctor: true
        }
      }
    },
    useminPrepare: {
      options: {
        dest: '<%%= yeoman.dist %>'
      },
      html: '<%%= yeoman.dist %>/index.html'
    },
    usemin: {
      options: {
        assetsDirs: '<%%= yeoman.dist %>',
      },
      html: ['<%%= yeoman.dist %>/**/*.html'],
      css: ['<%%= yeoman.dist %>/<%= cssDir %>/**/*.css']
    },
    htmlmin: {
      dist: {
        options: {
          collapseWhitespace: true,
          collapseBooleanAttributes: true,
          removeAttributeQuotes: true,
          removeRedundantAttributes: true
        },
        files: [{
          expand: true,
          cwd: '<%%= yeoman.dist %>',
          src: '**/*.html',
          dest: '<%%= yeoman.dist %>'
        }]
      }
    },
    // Usemin adds files to concat
    concat: {},
    // Usemin adds files to uglify
    uglify: {},
    // Usemin adds files to cssmin
    cssmin: {
      dist: {
        options: {
          check: 'gzip'
        }
      }
    },
    imagemin: {
      dist: {
        options: {
          progressive: true
        },
        files: [{
          expand: true,
          cwd: '<%%= yeoman.dist %>',
          src: '**/*.{jpg,jpeg,png}',
          dest: '<%%= yeoman.dist %>'
        }]
      }
    },
    svgmin: {
      dist: {
        files: [{
          expand: true,
          cwd: '<%%= yeoman.dist %>',
          src: '**/*.svg',
          dest: '<%%= yeoman.dist %>'
        }]
      }
    },
    copy: {
      dist: {
        files: [{
          expand: true,
          dot: true,
          cwd: '<%%= yeoman.app %>',
          src: [
            // Jekyll processes and moves HTML and text files.
            // Usemin moves CSS and javascript inside of Usemin blocks.
            // Copy moves asset files and directories.
            '<%= imgDir %>/**/*',
            '<%= fontsDir %>/**/*',
            // Like Jekyll, exclude files & folders prefixed with an underscore.
            '!**/_*{,/**}'<% if (h5bpJs) { %>,<% } %>
            // Explicitly add any files your site needs for distribution here.
            <% if (!h5bpJs) { %>//<% } %>'_bower_components/jquery/jquery.min.js',
            <% if (!h5bpJs) { %>//<% } %>'favicon.ico',
            <% if (!h5bpJs) { %>//<% } %>'apple-touch*.png'
          ],
          dest: '<%%= yeoman.dist %>'
        }]
      }<% if (autoPre) { %>,
      // Copy CSS into .tmp directory for Autoprefixer processing
      stageCss: {
        files: [{
          expand: true,
          dot: true,
          cwd: '<%%= yeoman.app %>/<%= cssDir %>',
          src: '**/*.css',
          dest: '.tmp/<%= cssDir %>'
        }]
      }<% } %>
    },
    filerev: {
      options: {
        length: 4
      },
      dist: {
        files: [{
          src: [
            '<%%= yeoman.dist %>/<%= jsDir %>/**/*.js',
            '<%%= yeoman.dist %>/<%= cssDir %>/**/*.css',
            '<%%= yeoman.dist %>/<%= imgDir %>/**/*.{gif,jpg,jpeg,png,svg,webp}',
            '<%%= yeoman.dist %>/<%= fontsDir %>/**/*.{eot*,otf,svg,ttf,woff}'
          ]
        }]
      }
    },<% if (deploy) { %>
    buildcontrol: {
      dist: {
        options: {
          remote: '<%= deployRemote %>',
          branch: '<%= deployBranch %>',
          commit: true,
          push: true
        }
      }
    },<% } %><% if (jsPre === 'coffeescript') { %>
    coffeelint: {
      options: {
        'max_line_length': {
          'level': 'ignore'
        }
      },
      check: ['<%%= yeoman.app %>/<%= jsPreDir %>/*.coffee']
    },<% } %>
    jshint: {
      options: {
        jshintrc: '.jshintrc',
        reporter: require('jshint-stylish')
      },
      all: [
        'Gruntfile.js',
        '<%%= yeoman.app %>/<%= jsDir %>/**/*.js',
        'test/spec/**/*.js'
      ]
    },
    csslint: {
      options: {
        csslintrc: '.csslintrc'
      },
      check: {
        src: [
          '<%%= yeoman.app %>/<%= cssDir %>/**/*.css'
        ]
      }
    },
    concurrent: {
      server: [<% if (cssPre === 'sass') { %>
        'sass:server',<% } %><% if (cssPre === 'compass') { %>
        'compass:server',<% } %><% if (jsPre === 'coffeescript') { %>
        'coffee:dist',<% } %><% if (autoPre) { %>
        'copy:stageCss',<% } %>
        'jekyll:server'
      ],
      dist: [<% if (cssPre === 'sass') { %>
        'sass:dist',<% } %><% if (cssPre === 'compass') { %>
        'compass:dist',<% } %><% if (jsPre === 'coffeescript') { %>
        'coffee:dist',<% } %>
        'copy:dist'
      ]
    }
  });

  // Define Tasks
  grunt.registerTask('serve', function (target) {
    if (target === 'dist') {
      return grunt.task.run(['build', 'browserSync:dist']);
    }

    grunt.task.run([
      'clean:server',
      'concurrent:server',<% if (autoPre) { %>
      'autoprefixer:dist',<% } %>
      'browserSync:server',
      'watch'
    ]);
  });

  grunt.registerTask('server', function () {
    grunt.log.warn('The `server` task has been deprecated. Use `grunt serve` to start a server.');
    grunt.task.run(['serve']);
  });

  // No real tests yet. Add your own.
  grunt.registerTask('test', [
  //   'clean:server',
  //   'concurrent:test',
  //   'browserSync:test'
  ]);

  grunt.registerTask('check', [
    'clean:server',
    'jekyll:check',<% if (cssPre === 'sass') { %>
    'sass:server',<% } %><% if (cssPre === 'compass') { %>
    'compass:server',<% } %><% if (jsPre === 'coffeescript') { %>
    'coffeelint:check',
    'coffee:dist',<% } %>
    'jshint:all',
    'csslint:check'
  ]);

  grunt.registerTask('build', [
    'clean',
    // Jekyll cleans files from the target directory, so must run first
    'jekyll:dist',
    'concurrent:dist',
    'useminPrepare',
    'concat',<% if (autoPre) { %>
    'autoprefixer:dist',<% } %>
    'cssmin',
    'uglify',
    'imagemin',
    'svgmin',
    'filerev',
    'usemin',
    'htmlmin'
    ]);<% if (deploy) { %>

  grunt.registerTask('deploy', [
    'check',
    'test',
    'build',
    'buildcontrol'
    ]);<% } %>

  grunt.registerTask('default', [
    'check',
    'test',
    'build'
  ]);
};
<commit_msg>js => jsDir<commit_after>// Generated on <%= (new Date).toISOString().split('T')[0] %> using <%= pkg.name %> <%= pkg.version %>
'use strict';

// Directory reference:
//   css: <%= cssDir %><% if (cssPre) { %>
//   <%= cssPre %>: <%= cssPreDir %><% } %>
//   javascript: <%= jsDir %><% if (jsPre) { %>
//   <%= jsPre %>: <%= jsPreDir %><% } %>
//   images: <%= imgDir %>
//   fonts: <%= fontsDir %>

module.exports = function (grunt) {
  // Show elapsed time after tasks run
  require('time-grunt')(grunt);
  // Load all Grunt tasks
  require('load-grunt-tasks')(grunt);

  grunt.initConfig({
    // Configurable paths
    yeoman: {
      app: 'app',
      dist: 'dist'
    },
    watch: {<% if (cssPre === 'sass' || cssPre === 'compass' ) { %>
      <%= cssPre %>: {
        files: ['<%%= yeoman.app %>/<%= cssPreDir %>/**/*.{scss,sass}'],
        tasks: ['<%= cssPre %>:server'<% if (autoPre) { %>, 'autoprefixer:dist'<% } %>]
      },<% } %><% if (autoPre) { %>
      autoprefixer: {
        files: ['<%%= yeoman.app %>/<%= cssDir %>/**/*.css'],
        tasks: ['copy:stageCss', 'autoprefixer:dist']
      },<% } %><% if (jsPre === 'coffeescript') { %>
      coffee: {
        files: ['<%%= yeoman.app %>/<%= jsPreDir %>/**/*.coffee'],
        tasks: ['coffee:dist']
      },
      coffeeTest: {
        files: ['test/spec/**/*.coffee'],
        tasks: ['coffee:test']
      },<% } %>
      jekyll: {
        files: [
          '<%%= yeoman.app %>/**/*.{html,yml,md,mkd,markdown}',
          '!<%%= yeoman.app %>/_bower_components/**/*'
        ],
        tasks: ['jekyll:server']
      }
    },
    browserSync: {
      server: {
        bsFiles: {
          src: [
            '.jekyll/**/*.html',
            '.tmp/css/**/*.css',
            '{.tmp,<%%= yeoman.app %>}/<%= jsDir %>/**/*.js',
            '{<%%= yeoman.app %>}/_bower_components/**/*.js',
            '<%%= yeoman.app %>/img/**/*.{gif,jpg,jpeg,png,svg,webp}'
          ]
        },
        options: {
          server: {
            baseDir: [
              ".jekyll",
              ".tmp",
              "<%%= yeoman.app %>"
            ]
          },
          watchTask: true
        }
      },
      dist: {
        options: {
          server: {
            baseDir: "<%%= yeoman.dist %>"
          }
        }
      },
      test: {
        bsFiles: {
          src: [
            '.jekyll/**/*.html',
            '.tmp/css/**/*.css',
            '{.tmp,<%%= yeoman.app %>}/<%= jsDir %>/**/*.js',
            '{<%%= yeoman.app %>}/_bower_components/**/*.js',
            '<%%= yeoman.app %>/img/**/*.{gif,jpg,jpeg,png,svg,webp}'
          ]
        },
        options: {
          server: {
            baseDir: [
              ".jekyll",
              ".tmp",
              "<%%= yeoman.app %>"
            ]
          },
          watchTask: true
        }
      }
    },
    clean: {
      dist: {
        files: [{
          dot: true,
          src: [
            '<%%= yeoman.dist %>/*',
            // Running Jekyll also cleans the target directory.  Exclude any
            // non-standard `keep_files` here (e.g., the generated files
            // directory from Jekyll Picture Tag).
            '!<%%= yeoman.dist %>/.git*'
          ]
        }]
      },
      server: [
        '.tmp',
        '.jekyll'
      ]
    },<% if (cssPre === 'sass') { %>
    sass: {
      options: {
        bundleExec: true,
        debugInfo: false,
        lineNumbers: false,
        loadPath: 'app/_bower_components'
      },
      dist: {
        files: [{
          expand: true,
          cwd: '<%%= yeoman.app %>/<%= cssPreDir %>',
          src: '**/*.{scss,sass}',
          dest: '.tmp/<%= cssDir %>',
          ext: '.css'
        }]
      },
      server: {
        options: {
          debugInfo: true,
          lineNumbers: true
        },
        files: [{
          expand: true,
          cwd: '<%%= yeoman.app %>/<%= cssPreDir %>',
          src: '**/*.{scss,sass}',
          dest: '.tmp/<%= cssDir %>',
          ext: '.css'
        }]
      }
    },<% } %><% if (cssPre === 'compass') { %>
    compass: {
      options: {
        // If you're using global Sass gems, require them here.
        // require: ['singularity', 'jacket'],
        bundleExec: true,
        sassDir: '<%%= yeoman.app %>/<%= cssPreDir %>',
        cssDir: '.tmp/<%= cssDir %>',
        imagesDir: '<%%= yeoman.app %>/<%= imgDir %>',
        javascriptsDir: '<%%= yeoman.app %>/<%= jsDir %>',
        relativeAssets: false,
        httpImagesPath: '/<%= imgDir %>',
        httpGeneratedImagesPath: '/<%= imgDir %>/generated',
        outputStyle: 'expanded',
        raw: 'extensions_dir = "<%%= yeoman.app %>/_bower_components"\n'
      },
      dist: {
        options: {
          generatedImagesDir: '<%%= yeoman.dist %>/<%= imgDir %>/generated'
        }
      },
      server: {
        options: {
          debugInfo: true,
          generatedImagesDir: '.tmp/<%= imgDir %>/generated'
        }
      }
    },<% } %><% if (autoPre) { %>
    autoprefixer: {
      options: {
        browsers: ['last 2 versions']
      },
      dist: {
        expand: true,
        cwd: '.tmp',
        src: '**/{<%= cssDir %>,concat}/*.css',
        dest: '.tmp'
      }
    },<% } %><% if (jsPre === 'coffeescript') { %>
    coffee: {
      dist: {
        files: [{
          expand: true,
          cwd: '<%%= yeoman.app %>/<%= jsPreDir %>',
          src: '**/*.coffee',
          dest: '.tmp/<%= jsDir %>',
          ext: '.js'
        }]
      },
      test: {
        files: [{
          expand: true,
          cwd: 'test/spec',
          src: '**/*.coffee',
          dest: '.tmp/spec',
          ext: '.js'
        }]
      }
    },<% } %>
    jekyll: {
      options: {
        bundleExec: true,
        config: '_config.yml,_config.build.yml',
        src: '<%%= yeoman.app %>'
      },
      dist: {
        options: {
          dest: '<%%= yeoman.dist %>',
        }
      },
      server: {
        options: {
          config: '_config.yml',
          dest: '.jekyll'
        }
      },
      check: {
        options: {
          doctor: true
        }
      }
    },
    useminPrepare: {
      options: {
        dest: '<%%= yeoman.dist %>'
      },
      html: '<%%= yeoman.dist %>/index.html'
    },
    usemin: {
      options: {
        assetsDirs: '<%%= yeoman.dist %>',
      },
      html: ['<%%= yeoman.dist %>/**/*.html'],
      css: ['<%%= yeoman.dist %>/<%= cssDir %>/**/*.css']
    },
    htmlmin: {
      dist: {
        options: {
          collapseWhitespace: true,
          collapseBooleanAttributes: true,
          removeAttributeQuotes: true,
          removeRedundantAttributes: true
        },
        files: [{
          expand: true,
          cwd: '<%%= yeoman.dist %>',
          src: '**/*.html',
          dest: '<%%= yeoman.dist %>'
        }]
      }
    },
    // Usemin adds files to concat
    concat: {},
    // Usemin adds files to uglify
    uglify: {},
    // Usemin adds files to cssmin
    cssmin: {
      dist: {
        options: {
          check: 'gzip'
        }
      }
    },
    imagemin: {
      dist: {
        options: {
          progressive: true
        },
        files: [{
          expand: true,
          cwd: '<%%= yeoman.dist %>',
          src: '**/*.{jpg,jpeg,png}',
          dest: '<%%= yeoman.dist %>'
        }]
      }
    },
    svgmin: {
      dist: {
        files: [{
          expand: true,
          cwd: '<%%= yeoman.dist %>',
          src: '**/*.svg',
          dest: '<%%= yeoman.dist %>'
        }]
      }
    },
    copy: {
      dist: {
        files: [{
          expand: true,
          dot: true,
          cwd: '<%%= yeoman.app %>',
          src: [
            // Jekyll processes and moves HTML and text files.
            // Usemin moves CSS and javascript inside of Usemin blocks.
            // Copy moves asset files and directories.
            '<%= imgDir %>/**/*',
            '<%= fontsDir %>/**/*',
            // Like Jekyll, exclude files & folders prefixed with an underscore.
            '!**/_*{,/**}'<% if (h5bpJs) { %>,<% } %>
            // Explicitly add any files your site needs for distribution here.
            <% if (!h5bpJs) { %>//<% } %>'_bower_components/jquery/jquery.min.js',
            <% if (!h5bpJs) { %>//<% } %>'favicon.ico',
            <% if (!h5bpJs) { %>//<% } %>'apple-touch*.png'
          ],
          dest: '<%%= yeoman.dist %>'
        }]
      }<% if (autoPre) { %>,
      // Copy CSS into .tmp directory for Autoprefixer processing
      stageCss: {
        files: [{
          expand: true,
          dot: true,
          cwd: '<%%= yeoman.app %>/<%= cssDir %>',
          src: '**/*.css',
          dest: '.tmp/<%= cssDir %>'
        }]
      }<% } %>
    },
    filerev: {
      options: {
        length: 4
      },
      dist: {
        files: [{
          src: [
            '<%%= yeoman.dist %>/<%= jsDir %>/**/*.js',
            '<%%= yeoman.dist %>/<%= cssDir %>/**/*.css',
            '<%%= yeoman.dist %>/<%= imgDir %>/**/*.{gif,jpg,jpeg,png,svg,webp}',
            '<%%= yeoman.dist %>/<%= fontsDir %>/**/*.{eot*,otf,svg,ttf,woff}'
          ]
        }]
      }
    },<% if (deploy) { %>
    buildcontrol: {
      dist: {
        options: {
          remote: '<%= deployRemote %>',
          branch: '<%= deployBranch %>',
          commit: true,
          push: true
        }
      }
    },<% } %><% if (jsPre === 'coffeescript') { %>
    coffeelint: {
      options: {
        'max_line_length': {
          'level': 'ignore'
        }
      },
      check: ['<%%= yeoman.app %>/<%= jsPreDir %>/*.coffee']
    },<% } %>
    jshint: {
      options: {
        jshintrc: '.jshintrc',
        reporter: require('jshint-stylish')
      },
      all: [
        'Gruntfile.js',
        '<%%= yeoman.app %>/<%= jsDir %>/**/*.js',
        'test/spec/**/*.js'
      ]
    },
    csslint: {
      options: {
        csslintrc: '.csslintrc'
      },
      check: {
        src: [
          '<%%= yeoman.app %>/<%= cssDir %>/**/*.css'
        ]
      }
    },
    concurrent: {
      server: [<% if (cssPre === 'sass') { %>
        'sass:server',<% } %><% if (cssPre === 'compass') { %>
        'compass:server',<% } %><% if (jsPre === 'coffeescript') { %>
        'coffee:dist',<% } %><% if (autoPre) { %>
        'copy:stageCss',<% } %>
        'jekyll:server'
      ],
      dist: [<% if (cssPre === 'sass') { %>
        'sass:dist',<% } %><% if (cssPre === 'compass') { %>
        'compass:dist',<% } %><% if (jsPre === 'coffeescript') { %>
        'coffee:dist',<% } %>
        'copy:dist'
      ]
    }
  });

  // Define Tasks
  grunt.registerTask('serve', function (target) {
    if (target === 'dist') {
      return grunt.task.run(['build', 'browserSync:dist']);
    }

    grunt.task.run([
      'clean:server',
      'concurrent:server',<% if (autoPre) { %>
      'autoprefixer:dist',<% } %>
      'browserSync:server',
      'watch'
    ]);
  });

  grunt.registerTask('server', function () {
    grunt.log.warn('The `server` task has been deprecated. Use `grunt serve` to start a server.');
    grunt.task.run(['serve']);
  });

  // No real tests yet. Add your own.
  grunt.registerTask('test', [
  //   'clean:server',
  //   'concurrent:test',
  //   'browserSync:test'
  ]);

  grunt.registerTask('check', [
    'clean:server',
    'jekyll:check',<% if (cssPre === 'sass') { %>
    'sass:server',<% } %><% if (cssPre === 'compass') { %>
    'compass:server',<% } %><% if (jsPre === 'coffeescript') { %>
    'coffeelint:check',
    'coffee:dist',<% } %>
    'jshint:all',
    'csslint:check'
  ]);

  grunt.registerTask('build', [
    'clean',
    // Jekyll cleans files from the target directory, so must run first
    'jekyll:dist',
    'concurrent:dist',
    'useminPrepare',
    'concat',<% if (autoPre) { %>
    'autoprefixer:dist',<% } %>
    'cssmin',
    'uglify',
    'imagemin',
    'svgmin',
    'filerev',
    'usemin',
    'htmlmin'
    ]);<% if (deploy) { %>

  grunt.registerTask('deploy', [
    'check',
    'test',
    'build',
    'buildcontrol'
    ]);<% } %>

  grunt.registerTask('default', [
    'check',
    'test',
    'build'
  ]);
};
<|endoftext|>


<commit_before>'use strict';

module.exports = function (grunt) {
  // Project configuration.
  grunt.initConfig({
    // Metadata.
    pkg: grunt.file.readJSON('package.json'),
    banner: '/*! <%%= pkg.name %> - v<%%= pkg.version %> - ' +
      '<%%= grunt.template.today("yyyy-mm-dd") %>\n' +
      '<%%= pkg.homepage ? "* " + pkg.homepage + "\\n" : "" %>' +
      '* Copyright (c) <%%= grunt.template.today("yyyy") %> <%%= pkg.author.name %>;' +
      ' Licensed <%%= _.pluck(pkg.licenses, "type").join(", ") %> */\n',
    // Task configuration.
    clean: {
      files: ['dist']
    },
    concat: {
      options: {
        banner: '<%%= banner %>',
        stripBanners: true
      },
      dist: {
        src: ['bower_components/requirejs/require.js', '<%%= concat.dist.dest %>'],
        dest: 'dist/require.js'
      }
    },
    uglify: {
      options: {
        banner: '<%%= banner %>'
      },
      dist: {
        src: '<%%= concat.dist.dest %>',
        dest: 'dist/require.min.js'
      }
    },
    jasmine: {
      test: {
        src: ['app/**/*.js', '!app/config.js'],
        options: {
          specs: 'test/*Spec.js',
          helpers: 'test/*Helper.js',
          keepRunner: true,
          template: require('grunt-template-jasmine-requirejs'),
          templateOptions: {
            requireConfigFile: 'app/config.js',
            requireConfig: {
              baseUrl: 'app/'
            }
          }
        }
      }
    },
    jshint: {
      gruntfile: {
        options: {
          jshintrc: '.jshintrc'
        },
        src: 'Gruntfile.js'
      },
      app: {
        options: {
          jshintrc: 'app/.jshintrc'
        },
        src: ['app/**/*.js']
      },
      test: {
        options: {
          jshintrc: 'test/.jshintrc'
        },
        src: ['test/**/*.js']
      }
    },
    watch: {
      gruntfile: {
        files: '<%%= jshint.gruntfile.src %>',
        tasks: ['jshint:gruntfile']
      },
      src: {
        files: '<%%= jshint.src.src %>',
        tasks: ['jshint:src', 'jasmine']
      },
      test: {
        files: '<%%= jshint.test.src %>',
        tasks: ['jshint:test', 'jasmine']
      },
    },
    requirejs: {
      compile: {
        options: {
          name: 'config',
          mainConfigFile: 'app/config.js',
          out: '<%%= concat.dist.dest %>',
          optimize: 'none'
        }
      }
    },
    connect: {
      development: {
        options: {
          keepalive: true
        }
      },
      production: {
        options: {
          keepalive: true,
          port: 8000,
          middleware: function (connect, options) {
            return [
              // rewrite requirejs to the compiled version
              function (req, res, next) {
                if (req.url === '/bower_components/requirejs/require.js') {
                  req.url = '/dist/require.min.js';
                }
                next();
              },
              connect.static(options.base),

            ];
          }
        }
      }
    }
  });

  // These plugins provide necessary tasks.
  grunt.loadNpmTasks('grunt-contrib-clean');
  grunt.loadNpmTasks('grunt-contrib-concat');
  grunt.loadNpmTasks('grunt-contrib-uglify');
  grunt.loadNpmTasks('grunt-contrib-jasmine');
  grunt.loadNpmTasks('grunt-contrib-jshint');
  grunt.loadNpmTasks('grunt-contrib-watch');
  grunt.loadNpmTasks('grunt-contrib-requirejs');
  grunt.loadNpmTasks('grunt-contrib-connect');

  // Default task.
  grunt.registerTask('default', ['jshint', 'jasmine', 'clean', 'requirejs', 'concat', 'uglify']);
  grunt.registerTask('preview', ['connect:development']);
  grunt.registerTask('preview-live', ['default', 'connect:production']);
  grunt.registerTask('test', ['jasmine']);

};
<commit_msg>Remove Jasmine plugin 'keepRunning' option<commit_after>'use strict';

module.exports = function (grunt) {
  // Project configuration.
  grunt.initConfig({
    // Metadata.
    pkg: grunt.file.readJSON('package.json'),
    banner: '/*! <%%= pkg.name %> - v<%%= pkg.version %> - ' +
      '<%%= grunt.template.today("yyyy-mm-dd") %>\n' +
      '<%%= pkg.homepage ? "* " + pkg.homepage + "\\n" : "" %>' +
      '* Copyright (c) <%%= grunt.template.today("yyyy") %> <%%= pkg.author.name %>;' +
      ' Licensed <%%= _.pluck(pkg.licenses, "type").join(", ") %> */\n',
    // Task configuration.
    clean: {
      files: ['dist']
    },
    concat: {
      options: {
        banner: '<%%= banner %>',
        stripBanners: true
      },
      dist: {
        src: ['bower_components/requirejs/require.js', '<%%= concat.dist.dest %>'],
        dest: 'dist/require.js'
      }
    },
    uglify: {
      options: {
        banner: '<%%= banner %>'
      },
      dist: {
        src: '<%%= concat.dist.dest %>',
        dest: 'dist/require.min.js'
      }
    },
    jasmine: {
      test: {
        src: ['app/**/*.js', '!app/config.js'],
        options: {
          specs: 'test/*Spec.js',
          helpers: 'test/*Helper.js',
          template: require('grunt-template-jasmine-requirejs'),
          templateOptions: {
            requireConfigFile: 'app/config.js',
            requireConfig: {
              baseUrl: 'app/'
            }
          }
        }
      }
    },
    jshint: {
      gruntfile: {
        options: {
          jshintrc: '.jshintrc'
        },
        src: 'Gruntfile.js'
      },
      app: {
        options: {
          jshintrc: 'app/.jshintrc'
        },
        src: ['app/**/*.js']
      },
      test: {
        options: {
          jshintrc: 'test/.jshintrc'
        },
        src: ['test/**/*.js']
      }
    },
    watch: {
      gruntfile: {
        files: 'Gruntfile.js',
        tasks: ['jshint:gruntfile']
      },
      src: {
        files: ['app/**/*.js'],
        tasks: ['jshint:src', 'jasmine']
      },
      test: {
        files: ['test/**/*.js'],
        tasks: ['jshint:test', 'jasmine']
      },
    },
    requirejs: {
      compile: {
        options: {
          name: 'config',
          mainConfigFile: 'app/config.js',
          out: '<%%= concat.dist.dest %>',
          optimize: 'none'
        }
      }
    },
    connect: {
      development: {
        options: {
          keepalive: true
        }
      },
      production: {
        options: {
          keepalive: true,
          port: 8000,
          middleware: function (connect, options) {
            return [
              // rewrite requirejs to the compiled version
              function (req, res, next) {
                if (req.url === '/bower_components/requirejs/require.js') {
                  req.url = '/dist/require.min.js';
                }
                next();
              },
              connect.static(options.base),

            ];
          }
        }
      }
    }
  });

  // These plugins provide necessary tasks.
  grunt.loadNpmTasks('grunt-contrib-clean');
  grunt.loadNpmTasks('grunt-contrib-concat');
  grunt.loadNpmTasks('grunt-contrib-uglify');
  grunt.loadNpmTasks('grunt-contrib-jasmine');
  grunt.loadNpmTasks('grunt-contrib-jshint');
  grunt.loadNpmTasks('grunt-contrib-watch');
  grunt.loadNpmTasks('grunt-contrib-requirejs');
  grunt.loadNpmTasks('grunt-contrib-connect');

  // Default task.
  grunt.registerTask('default', ['jshint', 'jasmine', 'clean', 'requirejs', 'concat', 'uglify']);
  grunt.registerTask('preview', ['connect:development']);
  grunt.registerTask('preview-live', ['default', 'connect:production']);
  grunt.registerTask('test', ['jasmine']);

};
<|endoftext|>


<commit_before>var gulp = require('gulp'),
    gutil = require('gulp-util'),
    path = require('path'),
    argv = require('yargs').alias('p', 'port').argv;

var devServer = {
  port: argv.port || Math.round(31337 + Math.random() * 1000),
  livereload: 35000 + Math.round((Math.random() * 1000)),
  root: './dist'
};

var paths = {
  scripts: ['src/**/*.js'],
  markup: ['src/*.html'],
  styles: { paths: [ path.join(__dirname, 'src/styles') ] }
};

gulp.task('default', ['build', 'startStaticServer', 'watchChanges']);
gulp.task('build', ['makeDist', 'runBrowserify', 'copyDist', 'compileLess']);

gulp.task('runBrowserify', runBrowserify);
gulp.task('compileLess', compileLess);
gulp.task('makeDist', makeDist);
gulp.task('copyDist', copyDist);
gulp.task('watchChanges', watchChanges);
gulp.task('startStaticServer', startStaticServer);

function runBrowserify() {
  var fs = require('fs');

  var bundle = require('browserify')()
    .add('./src/scripts/index.js')
    .bundle()
    .on('error', function (err) {
        gutil.log(gutil.colors.red('Failed to browserify'), gutil.colors.yellow(err.message));
    });
  bundle.pipe(fs.createWriteStream(path.join(__dirname + '/dist/bundle.js')));
}

function compileLess() {
  var less = require('gulp-less')(paths.styles);
  less.on('error', function (err) {
    gutil.log(gutil.colors.red('Failed to compile less: '), gutil.colors.yellow(err.message));
  });

	gulp.src('src/styles/style.less')
		.pipe(less)
		.pipe(gulp.dest('dist/styles'));
}

function makeDist() {
  var fs = require('fs');
  if (!fs.existsSync('./dist')) {
    fs.mkdirSync('./dist');
  }
}

function copyDist() {
  var concat = require('gulp-concat');

  gulp.src('./src/index.html')
      .pipe(gulp.dest('./dist'));

  gulp.src('./node_modules/angular/lib/angular.min.js')
      .pipe(concat('external.min.js'))
      .pipe(gulp.dest('./dist'));

  gulp.src('./node_modules/twitter-bootstrap-3.0.0/fonts/*')
      .pipe(gulp.dest('./dist/fonts/'));
}

function watchChanges() {
  gulp.watch(paths.scripts, ['runBrowserify']);
  gulp.watch('src/styles/*.less', ['compileLess']);
  gulp.watch(paths.markup, ['copyDist']);
  gulp.watch('dist/**').on('change', notifyLivereload);
}

var lr;
function startStaticServer() {
  var express = require('express');
  var app = express();
  app.use(require('connect-livereload')({port: devServer.livereload }));
  app.use(express.static(devServer.root));
  app.listen(devServer.port, function () {
    gutil.log("opened server on http://127.0.0.1:" + devServer.port);
  });

  lr = require('tiny-lr')();
  lr.listen(devServer.livereload);
}

function notifyLivereload(event) {
  var fileName = require('path').relative(devServer.root, event.path);
  lr.changed({ body: { files: [fileName] } });
}
<commit_msg>Added option to pass hostname<commit_after>var gulp = require('gulp'),
    gutil = require('gulp-util'),
    path = require('path'),
    argv = require('yargs')
       .alias('p', 'port')
       .alias('s', 'server')
       .argv;

var devServer = {
  port: argv.port || Math.round(31337 + Math.random() * 1000),
  server: argv.server || '0.0.0.0',
  livereload: 35000 + Math.round((Math.random() * 1000)),
  root: './dist'
};

var paths = {
  scripts: ['src/**/*.js'],
  markup: ['src/*.html'],
  styles: { paths: [ path.join(__dirname, 'src/styles') ] }
};

gulp.task('default', ['build', 'startStaticServer', 'watchChanges']);
gulp.task('build', ['makeDist', 'runBrowserify', 'copyDist', 'compileLess']);

gulp.task('runBrowserify', runBrowserify);
gulp.task('compileLess', compileLess);
gulp.task('makeDist', makeDist);
gulp.task('copyDist', copyDist);
gulp.task('watchChanges', watchChanges);
gulp.task('startStaticServer', startStaticServer);

function runBrowserify() {
  var fs = require('fs');

  var bundle = require('browserify')()
    .add('./src/scripts/index.js')
    .bundle()
    .on('error', function (err) {
        gutil.log(gutil.colors.red('Failed to browserify'), gutil.colors.yellow(err.message));
    });
  bundle.pipe(fs.createWriteStream(path.join(__dirname + '/dist/bundle.js')));
}

function compileLess() {
  var less = require('gulp-less')(paths.styles);
  less.on('error', function (err) {
    gutil.log(gutil.colors.red('Failed to compile less: '), gutil.colors.yellow(err.message));
  });

	gulp.src('src/styles/style.less')
		.pipe(less)
		.pipe(gulp.dest('dist/styles'));
}

function makeDist() {
  var fs = require('fs');
  if (!fs.existsSync('./dist')) {
    fs.mkdirSync('./dist');
  }
}

function copyDist() {
  var concat = require('gulp-concat');

  gulp.src('./src/index.html')
      .pipe(gulp.dest('./dist'));

  gulp.src('./node_modules/angular/lib/angular.min.js')
      .pipe(concat('external.min.js'))
      .pipe(gulp.dest('./dist'));

  gulp.src('./node_modules/twitter-bootstrap-3.0.0/fonts/*')
      .pipe(gulp.dest('./dist/fonts/'));
}

function watchChanges() {
  gulp.watch(paths.scripts, ['runBrowserify']);
  gulp.watch('src/styles/*.less', ['compileLess']);
  gulp.watch(paths.markup, ['copyDist']);
  gulp.watch('dist/**').on('change', notifyLivereload);
}

var lr;
function startStaticServer() {
  var express = require('express');
  var app = express();
  app.use(require('connect-livereload')({port: devServer.livereload }));
  app.use(express.static(devServer.root));
  app.listen(devServer.port, devServer.server, function () {
    gutil.log("opened server on http://" + devServer.server + ":" + devServer.port);
  });

  lr = require('tiny-lr')();
  lr.listen(devServer.livereload);
}

function notifyLivereload(event) {
  var fileName = require('path').relative(devServer.root, event.path);
  lr.changed({ body: { files: [fileName] } });
}
<|endoftext|>


<commit_before>/**
 *  Zero-Width Unicode Character Steganography
 *  Copyright (c) 2015 Kei Misawa
 *  This software is released under the MIT License.
 *  http://opensource.org/licenses/mit-license.php
 */
(function(){
    var chars = [];
    var radix = 0;
    var codelength = 0;
    /**
      Set characters of coded hidden text(zero width characters)
      args: array of characters
      return: null
     */
    var setUseChars = function(newchars){
        if(newchars.length >= 2){
            chars = newchars;
            radix = chars.length;
            codelength = Math.ceil(Math.log2(65536) / Math.log2(radix));
        }
        return null;
    };
    /**
      Encoder
      args: original text, hidden text
      return: unicode text with steganography
     */
    var encodeSteganography = function(text1, text2){
        var encode_to_zerowidth_characters = (function(str1){
            var result = [];
            var base = '0'.repeat(codelength);

            for(var i = 0; i < str1.length; i++){
                var c = str1.charCodeAt(i);
                var d = c.toString(radix);

                result[i] = (base + d).substr(-codelength);
            }

            var r = result.join('');

            for(var i = 0; i < radix; i++){
                r = r.replace(new RegExp(i, 'g'), chars[i]);
            }

            return r;
        });
        var combine_shuffle_string = (function(str1, str2){
            var result = [];
            var c1 = str1.split(/([\u0000-\u002F\u003A-\u0040\u005b-\u0060\u007b-\u007f])|([\u0030-\u0039]+)|([\u0041-\u005a\u0061-\u007a]+)|([\u0080-\u00FF]+)|([\u0100-\u017F]+)|([\u0180-\u024F]+)|([\u0250-\u02AF]+)|([\u02B0-\u02FF]+)|([\u0300-\u036F]+)|([\u0370-\u03FF]+)|([\u0400-\u04FF]+)|([\u0500-\u052F]+)|([\u0530-\u058F]+)|([\u0590-\u05FF]+)|([\u0600-\u06FF]+)|([\u0700-\u074F]+)|([\u0750-\u077F]+)|([\u0780-\u07BF]+)|([\u07C0-\u07FF]+)|([\u0800-\u083F]+)|([\u0840-\u085F]+)|([\u08A0-\u08FF]+)|([\u0900-\u097F]+)|([\u0980-\u09FF]+)|([\u0A00-\u0A7F]+)|([\u0A80-\u0AFF]+)|([\u0B00-\u0B7F]+)|([\u0B80-\u0BFF]+)|([\u0C00-\u0C7F]+)|([\u0C80-\u0CFF]+)|([\u0D00-\u0D7F]+)|([\u0D80-\u0DFF]+)|([\u0E00-\u0E7F]+)|([\u0E80-\u0EFF]+)|([\u0F00-\u0FFF]+)|([\u1000-\u109F]+)|([\u10A0-\u10FF]+)|([\u1100-\u11FF]+)|([\u1200-\u137F]+)|([\u1380-\u139F]+)|([\u13A0-\u13FF]+)|([\u1400-\u167F]+)|([\u1680-\u169F]+)|([\u16A0-\u16FF]+)|([\u1700-\u171F]+)|([\u1720-\u173F]+)|([\u1740-\u175F]+)|([\u1760-\u177F]+)|([\u1780-\u17FF]+)|([\u1800-\u18AF]+)|([\u18B0-\u18FF]+)|([\u1900-\u194F]+)|([\u1950-\u197F]+)|([\u1980-\u19DF]+)|([\u19E0-\u19FF]+)|([\u1A00-\u1A1F]+)|([\u1A20-\u1AAF]+)|([\u1AB0-\u1AFF]+)|([\u1B00-\u1B7F]+)|([\u1B80-\u1BBF]+)|([\u1BC0-\u1BFF]+)|([\u1C00-\u1C4F]+)|([\u1C50-\u1C7F]+)|([\u1CC0-\u1CCF]+)|([\u1CD0-\u1CFF]+)|([\u1D00-\u1D7F]+)|([\u1D80-\u1DBF]+)|([\u1DC0-\u1DFF]+)|([\u1E00-\u1EFF]+)|([\u1F00-\u1FFF]+)|([\u2000-\u206F]+)|([\u2070-\u209F]+)|([\u20A0-\u20CF]+)|([\u20D0-\u20FF]+)|([\u2100-\u214F]+)|([\u2150-\u218F]+)|([\u2190-\u21FF]+)|([\u2200-\u22FF]+)|([\u2300-\u23FF]+)|([\u2400-\u243F]+)|([\u2440-\u245F]+)|([\u2460-\u24FF]+)|([\u2500-\u257F]+)|([\u2580-\u259F]+)|([\u25A0-\u25FF]+)|([\u2600-\u26FF]+)|([\u2700-\u27BF]+)|([\u27C0-\u27EF]+)|([\u27F0-\u27FF]+)|([\u2800-\u28FF]+)|([\u2900-\u297F]+)|([\u2980-\u29FF]+)|([\u2A00-\u2AFF]+)|([\u2B00-\u2BFF]+)|([\u2C00-\u2C5F]+)|([\u2C60-\u2C7F]+)|([\u2C80-\u2CFF]+)|([\u2D00-\u2D2F]+)|([\u2D30-\u2D7F]+)|([\u2D80-\u2DDF]+)|([\u2DE0-\u2DFF]+)|([\u2E00-\u2E7F]+)|([\u2E80-\u2EFF]+)|([\u2F00-\u2FDF]+)|([\u2FF0-\u2FFF]+)|([\u3000-\u303F]+)|([\u3040-\u309F]+)|([\u30A0-\u30FF]+)|([\u3100-\u312F]+)|([\u3130-\u318F]+)|([\u3190-\u319F]+)|([\u31A0-\u31BF]+)|([\u31C0-\u31EF]+)|([\u31F0-\u31FF]+)|([\u3200-\u32FF]+)|([\u3300-\u33FF]+)|([\u3400-\u4DBF]+)|([\u4DC0-\u4DFF]+)|([\u4E00-\u9FFF]+)|([\uA000-\uA48F]+)|([\uA490-\uA4CF]+)|([\uA4D0-\uA4FF]+)|([\uA500-\uA63F]+)|([\uA640-\uA69F]+)|([\uA6A0-\uA6FF]+)|([\uA700-\uA71F]+)|([\uA720-\uA7FF]+)|([\uA800-\uA82F]+)|([\uA830-\uA83F]+)|([\uA840-\uA87F]+)|([\uA880-\uA8DF]+)|([\uA8E0-\uA8FF]+)|([\uA900-\uA92F]+)|([\uA930-\uA95F]+)|([\uA960-\uA97F]+)|([\uA980-\uA9DF]+)|([\uA9E0-\uA9FF]+)|([\uAA00-\uAA5F]+)|([\uAA60-\uAA7F]+)|([\uAA80-\uAADF]+)|([\uAAE0-\uAAFF]+)|([\uAB00-\uAB2F]+)|([\uAB30-\uAB6F]+)|([\uAB70-\uABBF]+)|([\uABC0-\uABFF]+)|([\uAC00-\uD7AF]+)|([\uD7B0-\uD7FF]+)|([\uD800-\uDFFF]+)|([\uE000-\uF8FF]+)|([\uF900-\uFAFF]+)|([\uFB00-\uFB4F]+)|([\uFB50-\uFDFF]+)|([\uFE00-\uFE0F]+)|([\uFE10-\uFE1F]+)|([\uFE20-\uFE2F]+)|([\uFE30-\uFE4F]+)|([\uFE50-\uFE6F]+)|([\uFE70-\uFEFF]+)|([\uFF00-\uFFEF]+)|([\uFFF0-\uFFFF]+)/g);
            var c2 = str2.split(new RegExp('(.{' + codelength + '})', 'g'));
            var ratio = c1.length / (c1.length + c2.length);

            while((c1.length > 0) && (c2.length > 0)){
                if(Math.random() <= ratio){
                    result.push(c1.shift());
                }else{
                    result.push(c2.shift());
                }
            }
            result = result.concat(c1).concat(c2);

            return result.join('');
        });
        return combine_shuffle_string(text1, encode_to_zerowidth_characters(text2));
    };

    /**
      Decoder
      args: unicode text with steganography
      return: array of [original text, hidden text]
     */
    var decodeSteganography = function(text1){
        var split_zerowidth_characters = (function(str1){
        	var result = [];
        	result[0] = str1.replace(new RegExp('[' + chars.join('') + ']', 'g'), '');
        	result[1] = str1.replace(new RegExp('[^' + chars.join('') + ']', 'g'), '');

        	return result;
        });
        var decode_from_zero_width_characters = (function(str1){
            var r = str1;
            for(var i = 0; i < radix; i++){
                r = r.replace(new RegExp(chars[i], 'g'), i);
            }
            var result = [];
            for(var i = 0; i < r.length; i += codelength){
                result.push(String.fromCodePoint(Number.parseInt(r.substr(i, codelength), radix)));
            }

            return result.join('');
        });

        var result = split_zerowidth_characters(text1);
        result[1] = decode_from_zero_width_characters(result[1]);
        return result;
    };

    setUseChars(['\u200b', '\u200c', '\u200d', '\u202c']);

    window.unicodeSteganographer = {
        encodeSteganography: encodeSteganography,
        decodeSteganography: decodeSteganography,
        setUseChars: setUseChars
    };

    return null;
})();
<commit_msg>update<commit_after>/**
 *  Zero-Width Unicode Character Steganography
 *  Copyright (c) 2015 Kei Misawa
 *  This software is released under the MIT License.
 *  http://opensource.org/licenses/mit-license.php
 */
(function(){
    var chars = [];
    var radix = 0;
    var codelength = 0;
    /**
      Set characters of coded hidden text(zero width characters)
      args: string of zero width characters
      return: null
     */
    var setUseChars = function(newchars){
        if(newchars.length >= 2){
            chars = newchars.split('');
            radix = chars.length;
            codelength = Math.ceil(Math.log2(65536) / Math.log2(radix));
        }
        return null;
    };
    /**
      Encoder
      args: original text, hidden text
      return: unicode text with steganography
     */
    var encodeSteganography = function(text1, text2){
        var encode_to_zerowidth_characters = (function(str1){
            var result = [];
            var base = '0'.repeat(codelength);

            for(var i = 0; i < str1.length; i++){
                var c = str1.charCodeAt(i);
                var d = c.toString(radix);

                result[i] = (base + d).substr(-codelength);
            }

            var r = result.join('');

            for(var i = 0; i < radix; i++){
                r = r.replace(new RegExp(i, 'g'), chars[i]);
            }

            return r;
        });
        var combine_shuffle_string = (function(str1, str2){
            var result = [];
            var c1 = str1.split(/([\u0000-\u002F\u003A-\u0040\u005b-\u0060\u007b-\u007f])|([\u0030-\u0039]+)|([\u0041-\u005a\u0061-\u007a]+)|([\u0080-\u00FF]+)|([\u0100-\u017F]+)|([\u0180-\u024F]+)|([\u0250-\u02AF]+)|([\u02B0-\u02FF]+)|([\u0300-\u036F]+)|([\u0370-\u03FF]+)|([\u0400-\u04FF]+)|([\u0500-\u052F]+)|([\u0530-\u058F]+)|([\u0590-\u05FF]+)|([\u0600-\u06FF]+)|([\u0700-\u074F]+)|([\u0750-\u077F]+)|([\u0780-\u07BF]+)|([\u07C0-\u07FF]+)|([\u0800-\u083F]+)|([\u0840-\u085F]+)|([\u08A0-\u08FF]+)|([\u0900-\u097F]+)|([\u0980-\u09FF]+)|([\u0A00-\u0A7F]+)|([\u0A80-\u0AFF]+)|([\u0B00-\u0B7F]+)|([\u0B80-\u0BFF]+)|([\u0C00-\u0C7F]+)|([\u0C80-\u0CFF]+)|([\u0D00-\u0D7F]+)|([\u0D80-\u0DFF]+)|([\u0E00-\u0E7F]+)|([\u0E80-\u0EFF]+)|([\u0F00-\u0FFF]+)|([\u1000-\u109F]+)|([\u10A0-\u10FF]+)|([\u1100-\u11FF]+)|([\u1200-\u137F]+)|([\u1380-\u139F]+)|([\u13A0-\u13FF]+)|([\u1400-\u167F]+)|([\u1680-\u169F]+)|([\u16A0-\u16FF]+)|([\u1700-\u171F]+)|([\u1720-\u173F]+)|([\u1740-\u175F]+)|([\u1760-\u177F]+)|([\u1780-\u17FF]+)|([\u1800-\u18AF]+)|([\u18B0-\u18FF]+)|([\u1900-\u194F]+)|([\u1950-\u197F]+)|([\u1980-\u19DF]+)|([\u19E0-\u19FF]+)|([\u1A00-\u1A1F]+)|([\u1A20-\u1AAF]+)|([\u1AB0-\u1AFF]+)|([\u1B00-\u1B7F]+)|([\u1B80-\u1BBF]+)|([\u1BC0-\u1BFF]+)|([\u1C00-\u1C4F]+)|([\u1C50-\u1C7F]+)|([\u1CC0-\u1CCF]+)|([\u1CD0-\u1CFF]+)|([\u1D00-\u1D7F]+)|([\u1D80-\u1DBF]+)|([\u1DC0-\u1DFF]+)|([\u1E00-\u1EFF]+)|([\u1F00-\u1FFF]+)|([\u2000-\u206F]+)|([\u2070-\u209F]+)|([\u20A0-\u20CF]+)|([\u20D0-\u20FF]+)|([\u2100-\u214F]+)|([\u2150-\u218F]+)|([\u2190-\u21FF]+)|([\u2200-\u22FF]+)|([\u2300-\u23FF]+)|([\u2400-\u243F]+)|([\u2440-\u245F]+)|([\u2460-\u24FF]+)|([\u2500-\u257F]+)|([\u2580-\u259F]+)|([\u25A0-\u25FF]+)|([\u2600-\u26FF]+)|([\u2700-\u27BF]+)|([\u27C0-\u27EF]+)|([\u27F0-\u27FF]+)|([\u2800-\u28FF]+)|([\u2900-\u297F]+)|([\u2980-\u29FF]+)|([\u2A00-\u2AFF]+)|([\u2B00-\u2BFF]+)|([\u2C00-\u2C5F]+)|([\u2C60-\u2C7F]+)|([\u2C80-\u2CFF]+)|([\u2D00-\u2D2F]+)|([\u2D30-\u2D7F]+)|([\u2D80-\u2DDF]+)|([\u2DE0-\u2DFF]+)|([\u2E00-\u2E7F]+)|([\u2E80-\u2EFF]+)|([\u2F00-\u2FDF]+)|([\u2FF0-\u2FFF]+)|([\u3000-\u303F]+)|([\u3040-\u309F]+)|([\u30A0-\u30FF]+)|([\u3100-\u312F]+)|([\u3130-\u318F]+)|([\u3190-\u319F]+)|([\u31A0-\u31BF]+)|([\u31C0-\u31EF]+)|([\u31F0-\u31FF]+)|([\u3200-\u32FF]+)|([\u3300-\u33FF]+)|([\u3400-\u4DBF]+)|([\u4DC0-\u4DFF]+)|([\u4E00-\u9FFF]+)|([\uA000-\uA48F]+)|([\uA490-\uA4CF]+)|([\uA4D0-\uA4FF]+)|([\uA500-\uA63F]+)|([\uA640-\uA69F]+)|([\uA6A0-\uA6FF]+)|([\uA700-\uA71F]+)|([\uA720-\uA7FF]+)|([\uA800-\uA82F]+)|([\uA830-\uA83F]+)|([\uA840-\uA87F]+)|([\uA880-\uA8DF]+)|([\uA8E0-\uA8FF]+)|([\uA900-\uA92F]+)|([\uA930-\uA95F]+)|([\uA960-\uA97F]+)|([\uA980-\uA9DF]+)|([\uA9E0-\uA9FF]+)|([\uAA00-\uAA5F]+)|([\uAA60-\uAA7F]+)|([\uAA80-\uAADF]+)|([\uAAE0-\uAAFF]+)|([\uAB00-\uAB2F]+)|([\uAB30-\uAB6F]+)|([\uAB70-\uABBF]+)|([\uABC0-\uABFF]+)|([\uAC00-\uD7AF]+)|([\uD7B0-\uD7FF]+)|([\uD800-\uDFFF]+)|([\uE000-\uF8FF]+)|([\uF900-\uFAFF]+)|([\uFB00-\uFB4F]+)|([\uFB50-\uFDFF]+)|([\uFE00-\uFE0F]+)|([\uFE10-\uFE1F]+)|([\uFE20-\uFE2F]+)|([\uFE30-\uFE4F]+)|([\uFE50-\uFE6F]+)|([\uFE70-\uFEFF]+)|([\uFF00-\uFFEF]+)|([\uFFF0-\uFFFF]+)/g);
            var c2 = str2.split(new RegExp('(.{' + codelength + '})', 'g'));
            var ratio = c1.length / (c1.length + c2.length);

            while((c1.length > 0) && (c2.length > 0)){
                if(Math.random() <= ratio){
                    result.push(c1.shift());
                }else{
                    result.push(c2.shift());
                }
            }
            result = result.concat(c1).concat(c2);

            return result.join('');
        });
        return combine_shuffle_string(text1, encode_to_zerowidth_characters(text2));
    };

    /**
      Decoder
      args: unicode text with steganography
      return: array of [original text, hidden text]
     */
    var decodeSteganography = function(text1){
        var split_zerowidth_characters = (function(str1){
        	var result = [];
        	result[0] = str1.replace(new RegExp('[' + chars.join('') + ']', 'g'), '');
        	result[1] = str1.replace(new RegExp('[^' + chars.join('') + ']', 'g'), '');

        	return result;
        });
        var decode_from_zero_width_characters = (function(str1){
            var r = str1;
            for(var i = 0; i < radix; i++){
                r = r.replace(new RegExp(chars[i], 'g'), i);
            }
            var result = [];
            for(var i = 0; i < r.length; i += codelength){
                result.push(String.fromCodePoint(Number.parseInt(r.substr(i, codelength), radix)));
            }

            return result.join('');
        });

        var result = split_zerowidth_characters(text1);
        result[1] = decode_from_zero_width_characters(result[1]);
        return result;
    };

    setUseChars('\u200b\u200c\u200d\u202c');

    window.unicodeSteganographer = {
        encodeSteganography: encodeSteganography,
        decodeSteganography: decodeSteganography,
        setUseChars: setUseChars
    };

    return null;
})();
<|endoftext|>


<commit_before>/**
 *@class app2
 *@description
 *@time 2014-11-25 13:16
 *@author StarZou
 **/

var App = angular.module('App', ['ngAnimate']);

App.run(['$rootScope', function ($rootScope) {
    $rootScope.title = 'Angular 实践2';
    $rootScope.words = 'hello world!';
}]);

App.controller('AppCtrl', ['$scope', function ($scope) {
    /**
     * 监听作用域事件
     */
    $scope.$on('eventTriggered', function (event) {
        console.log('AppCtrl', event);
    });
}]);

App.controller('MainCtrl', ['$scope', function ($scope) {
    $scope.$on('eventTriggered', function (event) {
        console.log('MainCtrl', event);
    });

    /**
     * 向上传播
     */
    $scope.emit = function () {
        $scope.$emit('eventTriggered', {date: Date.now()});
    };

    /**
     * 向下传播
     */
    $scope.broadcast = function () {
        $scope.$parent.$broadcast('eventTriggered', {date: Date.now()});
    };
}]);

App.controller('AnimateCtrl', ['$scope', '$animate', function ($scope, $animate) {

}]);

App.controller('PrincipleCtrl', ['$scope', function ($scope) {

}]);

App.directive('sayHello', [function () {
    return {
        restrict: 'A',
        replace : true,
        scope   : true,
        template: '

',
        link    : function postLink(scope, element, attrs) {
            scope.word = scope.$eval(attrs.sayHello);
        }
    };
}]);<commit_msg>angular 研究<commit_after>/**
 *@class app2
 *@description
 *@time 2014-11-25 13:16
 *@author StarZou
 **/

var App = angular.module('App', ['ngAnimate']);

App.run(['$rootScope', function ($rootScope) {
    $rootScope.title = 'Angular 实践2';
    $rootScope.words = 'hello world!';
}]);

App.controller('AppCtrl', ['$scope', function ($scope) {
    /**
     * 监听作用域事件
     */
    $scope.$on('eventTriggered', function (event) {
        console.log('AppCtrl', event);
    });
}]);

App.controller('MainCtrl', ['$scope', function ($scope) {
    $scope.$on('eventTriggered', function (event) {
        console.log('MainCtrl', event);
    });

    /**
     * 向上传播
     */
    $scope.emit = function () {
        $scope.$emit('eventTriggered', {date: Date.now()});
    };

    /**
     * 向下传播
     */
    $scope.broadcast = function () {
        $scope.$parent.$broadcast('eventTriggered', {date: Date.now()});
    };
}]);

App.controller('AnimateCtrl', ['$scope', '$animate', function ($scope, $animate) {

}]);

App.controller('PrincipleCtrl', ['$scope', function ($scope) {
    $scope.$watch('user.name', function (newVal, oldVal, scope) {
        console.log(arguments);
    });
}]);

App.directive('sayHello', [function () {
    return {
        restrict: 'A',
        replace : true,
        scope   : true,
        template: '

',
        link    : function postLink(scope, element, attrs) {
            scope.word = scope.$eval(attrs.sayHello);
        }
    };
}]);<|endoftext|>


<commit_before>var webpack = require('webpack');

module.exports = {
  entry: './src/main.js',
  output: {
    path: './dist/',
    publicPath: 'dist/',
    filename: 'bundle.js'
  },
  resolve: {
    extensions: ['', '.js', '.vue']
  },
  module: {
    loaders: [
      {
        test: /\.vue$/,
        loader: 'vue'
      },
      {
        test: /\.js/,
        exclude: /node_modules|dist/,
        loader: 'babel'
      },
      {
        test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
        loader: 'url',
        query: {
          limit: 10000
        }
      }
    ]
  }
};

if (process.env.NODE_ENV === 'production') {
  module.exports.plugins = [
    new webpack.DefinePlugin({
      'process.env': {
        NODE_ENV: '"production"'
      }
    }),
    new webpack.optimize.UglifyJsPlugin({
      compress: {
        warnings: false
      }
    }),
    new webpack.optimize.OccurenceOrderPlugin()
  ];
} else {
  module.exports.devtool = '#source-map';
}
<commit_msg>Add json/html/font load support<commit_after>var webpack = require('webpack');

module.exports = {
  entry: './src/main.js',
  output: {
    path: './dist/',
    publicPath: 'dist/',
    filename: 'bundle.js'
  },
  resolve: {
    extensions: ['', '.js', '.vue']
  },
  module: {
    loaders: [
      {
        test: /\.vue$/,
        loader: 'vue'
      },
      {
        test: /\.js/,
        exclude: /node_modules|dist/,
        loader: 'babel'
      },
      {
        test: /\.json$/,
        loader: 'json'
      },
      {
        test: /\.html$/,
        loader: 'vue-html'
      },
      {
        test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
        loader: 'url',
        query: {
          limit: 10000
        }
      },
      {
        test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
        loader: 'url',
        query: {
          limit: 10000
        }
      }
    ]
  }
};

if (process.env.NODE_ENV === 'production') {
  module.exports.plugins = [
    new webpack.DefinePlugin({
      'process.env': {
        NODE_ENV: '"production"'
      }
    }),
    new webpack.optimize.UglifyJsPlugin({
      compress: {
        warnings: false
      }
    }),
    new webpack.optimize.OccurenceOrderPlugin()
  ];
} else {
  module.exports.devtool = '#source-map';
}
<|endoftext|>


<commit_before>var ConfigSelectView = Ember.Select.extend({
	classNames: ['config-select'],
	optionLabelPath: 'content.title',
	optionValuePath: 'content.value',
	contentBinding: 'config.options',
	elementInserted: false,
	bindingPath: function(){
		var path = this.get('config.path');
		return 'targetModel.' + path;
	}.property('config.path'),
	valueChanged: function(){
		if (!this.get('elementInserted')) return;
		var path = this.get('config.path');
		var target = this.get('targetModel');
		target.set(path, this.get('value'));
	}.observes('selection'),
	updateCurrentValue: function() {
		var that = this;
		var current = that.get(that.get('bindingPath'));
		that.set('value', current);
	},
	didInsertElement: function(){
		var that = this;
		this.updateCurrentValue();
		that.addObserver(that.get('bindingPath'), this.updateCurrentValue);

		Em.run.next(this, function(){
			this.set('elementInserted', true);
		});
	},
	willDestroyElement: function(){
		this.removeObserver(this.get('bindingPath'), this.updateCurrentValue);
	},
});

export default ConfigSelectView;<commit_msg>add disabled ability to ConfigSelect<commit_after>var ConfigSelectView = Ember.Select.extend({
	classNames: ['config-select'],
	optionLabelPath: 'content.title',
	optionValuePath: 'content.value',
	contentBinding: 'config.options',
	attributeBindings: ['disabled'],
	elementInserted: false,
	bindingPath: function(){
		var path = this.get('config.path');
		return 'targetModel.' + path;
	}.property('config.path'),
	disablePath: function(){
		var path = this.get('config.disable.path');
		return 'targetModel.' + path;
	}.property('config.disable.path'),
	valueChanged: function(){
		if (!this.get('elementInserted')) return;
		var path = this.get('config.path');
		var target = this.get('targetModel');
		target.set(path, this.get('value'));
	}.observes('selection'),
	updateCurrentValue: function(){
		var that = this;
		var current = that.get(that.get('bindingPath'));
		that.set('value', current);
	},

	updateDisableValue: function(){
		var current = this.get(this.get('disablePath'));
		var value = this.get('config.disable.value');
		this.set('disabled', current === value);
	},

	didInsertElement: function(){
		var that = this;
		this.updateCurrentValue();
		that.addObserver(that.get('bindingPath'), this.updateCurrentValue);

		if (this.get('config.disable')) {
			this.updateDisableValue();
			this.addObserver(this.get('disablePath'), this.updateDisableValue);
		}

		Em.run.next(this, function(){
			this.set('elementInserted', true);
		});
	},
	willDestroyElement: function(){
		this.removeObserver(this.get('bindingPath'), this.updateCurrentValue);
		this.removeObserver(this.get('disablePath'), this.updateDisableValue);
	},
});

export default ConfigSelectView;<|endoftext|>


<commit_before>/*
 * Consume: http://$FQDN:$PORT/um/lib/wes
 *
 * Wait events from backend using "long pooling".
 * The request is pending until something is there.
 * Thus:
 * >
 * > App.um.wes(status)
 * >
 * will not response until *next* event from backend
 *
 *
 * @status is current user status from backend:
 * App.User.id: 'onlidev@127.0.0.1 BcORk11VGsInZtzrLHD0LtYy'
 *   user status:^^^^   |         |
 *      user auth id:^^^|         |
 *            IP address:^^^^^^^^^|
 *                 `req.sessionID`:^^^^^^^^^^^^^^^^^^^^^^^^
 *
 * used in e.g. Chat to make this user bold
 *
 * If there is no pending `res` in session,
 * then user status is set `offline` ('appbar-user-offl')
 *
 * backend errors: w.res.statusCode = 501// "Not Implemented" + JSON
 *
 **/

App.um.wes = (
function create_backend_wait_events(conn){
var defaults
    /* channel#2: receive events from backend, send user status */
    conn.suspendEvents(false)// `this` fires own signal in callback()
    conn.url = App.backendURL + '/um/lib/wes'
    conn.timeout = App.cfg.modules.userman.extjs.wes.timeout || (1 << 22)// ~ hour
    conn.defer = null
    defaults = {
    // `wes` has only one polling `res` per `req.session`,
    // but to send new status second `req` is firing
        autoAbort: false,
        callback: backend_events
    }
    console.log('init: ' + App.User.id)
    req('onli')// setup user status by 'appbar-user-onli'

    return req// return function to act manually e.g: `App.um.wes(status)`

    function req(opts){
    var ev = 'initwes@UI'

        Ext.globalEvents.fireEventArgs(ev, [ ev ])

        if(!opts){
            opts = { }
        } else if('string' == typeof opts){// change status
            opts = { params: opts }
        }
        if(!opts.params){// if empty send current user status
            opts.params = App.User.id.slice(0, 4)
        }

        return conn.request(Ext.applyIf(opts, defaults))
    }

    function backend_events(o, success, res){
    var data, i, done

        if(success){
            // reset error state if any
            if(App.User.internalId){// tmp store for status in case of connection errors
                App.User.id = App.User.internalId// restore past status
                App.User.internalId = ''
            }
            if(conn.defer){
                clearTimeout(conn.defer)
                conn.defer = 0
            }
            // data processing
            if(!res.responseText) return req()// nothing to do
            try {
                data = JSON.parse(res.responseText)
            } catch(ex){
                success = false
                console.error('JSON App.um.wes:')
                console.error(res)
                Ext.Msg.show({
                   title: l10n.errun_title + ' JSON App.um.wes',
                   buttons: Ext.Msg.OK,
                   icon: Ext.Msg.ERROR,
                   msg:
('data: ' + (res.responseText || 'empty')).slice(0, 16).replace(/</g, '<')
+'
'+ l10n.errun_stack + '' + ex.stack.replace(/</g, '<')
                })
            }
            if(!data || !data.length) return req()// nothing to do
            // handle own events
            i = data.length - 1
            done = 0
            do {// scan from bottom up (our events are likely to be last in list)
                switch(data[i].ev){
                case 'wes4store':
                    o = data[i].json
                    if(o && o.store){
                        res = Ext.StoreManager.lookup(o.store)// e.g.: 'lftpd'
                        if(res){
                            setTimeout(function deferStore_fireEventArgs(){
                                res.fireEventArgs('wes4store', [o])
                            }, 0)
                            done++
                        } else {
                            console.warn('`wes4store` not found: ' + o.store)
                        }
                    } else {
                        console.warn('`wes4store`: no `store` argument of event')
                    }
                break
                // broadcasts: 'login@um' 'initwes@um' 'usts@um' ....
                default: break
                // == private events ==
                case 'Usts@um':
                // assign backend's ID instead of autogenerated User Model's ID
                    o = data[i].json
                    if(o && App.User.id != o){
                        App.User.id = o// UI event is in `um.controller.Login`
                        App.User.internalId && (App.User.internalId = '')
                    }
                    if('initwes@um' != data[0].ev &&// this is 1st event
                     !(data[2] && 'login@um' == data[2].ev)){// this is 3d one
                        o = null// do not setup twice if not init
                        done += 2
                    }
                    done++
                }
            } while(i--)
            if(o) req()// setup wes for next events, if not manual status
            // broadcast !own event if there are more events
            return (done == data.length) ? undefined : Ext.globalEvents.fireEventArgs(
                'wes4UI',
                [ success, data ]
            )
        }

        if(res.timedout) return req()// just restart polling
        if(-1 == res.status){// abort
            console.warn('wes: abort detected')
            return req()// try to restart polling
        }

        console.error('wes:', res)

        if(!App.User.internalId){
            App.User.internalId = App.User.id// save current status
            // mark as offline in case of permanent error
            App.User.id = 'offl' + App.User.id.slice(4)
        }
        conn.defer = Ext.defer(// retry a bit later
            req,
            App.cfg.modules.userman.extjs.wes.defer || (1 << 17)// ~ two minutes
        )
        Ext.globalEvents.fireEventArgs(
            'wes4UI',
            [ success, res.statusText || 'Disconnect']
        )

        return undefined
    }
})(Ext.create(App.backend.Connection))

/*
 * Deliver server-pushed data to Ext.data.Store's
 * `ev`: wes4store
 * @view: highlight updated row(s)/model(s)/record(s)
 **/
Ext.define('App.store.WES',{
    extend: Ext.data.ArrayStore,
    view: null,// grid or panel with grid somewhere down
    highlightModel: true,
    // is used to optimize cell changes
    informStore: true,// on model change don't re-render of cells / rows
    listeners:{
        wes4store: function(json){//{ store: 'storeId', data:[{model}, {model}]}
        var view, data, model, updated, j
           ,node, skip_store, highlight

            if(this.view){
                if(!(view = this.view.view)){// is not grid with view
                    view = this.view.down('grid')// look down for a grid
                    view && (view = view.view)
                }
            }
            skip_store = !this.informStore, highlight = this.highlightModel
            if(Array.isArray(data = json.data)){
                for(j = 0; j < data.length; ++j){
                    if((model = this.getById(data[j].id))){
                        skip_store && (model.editing = true)
                        if((updated = model.set(data[j]))){
                            if(view) node = Ext.fly(// if grid view is available
                                view.getNode(view.getRowId(model))
                            )
                            // inform interested parties, go in if event is OK
                            if(model.fireEventArgs('datachanged',[model, updated, node])){
                                 highlight && node && node.highlight('#77FF77',{
                                    attr: 'backgroundColor',
                                    duration: 512
                                })
                            }
                        }
                        skip_store && (model.editing = false)
                    }
                }
                data && data.length && this.fireEventArgs('datachanged')
            }
        }
    }
})
<commit_msg>wes: noop whitespace change<commit_after>/*
 * Consume: http://$FQDN:$PORT/um/lib/wes
 *
 * Wait events from backend using "long pooling".
 * The request is pending until something is there.
 * Thus:
 * >
 * > App.um.wes(status)
 * >
 * will not response until *next* event from backend
 *
 *
 * @status is current user status from backend:
 * App.User.id: 'onlidev@127.0.0.1 BcORk11VGsInZtzrLHD0LtYy'
 *   user status:^^^^   |         |
 *      user auth id:^^^|         |
 *            IP address:^^^^^^^^^|
 *                 `req.sessionID`:^^^^^^^^^^^^^^^^^^^^^^^^
 *
 * used in e.g. Chat to make this user bold
 *
 * If there is no pending `res` in session,
 * then user status is set `offline` ('appbar-user-offl')
 *
 * backend errors: w.res.statusCode = 501// "Not Implemented" + JSON
 *
 **/

App.um.wes = (
function create_backend_wait_events(conn){
var defaults
    /* channel#2: receive events from backend, send user status */
    conn.suspendEvents(false)// `this` fires own signal in callback()
    conn.url = App.backendURL + '/um/lib/wes'
    conn.timeout = App.cfg.modules.userman.extjs.wes.timeout || (1 << 22)// ~ hour
    conn.defer = null
    defaults = {
    // `wes` has only one polling `res` per `req.session`,
    // but to send new status second `req` is firing
        autoAbort: false,
        callback: backend_events
    }
    console.log('init: ' + App.User.id)
    req('onli')// setup user status by 'appbar-user-onli'

    return req// return function to act manually e.g: `App.um.wes(status)`

    function req(opts){
    var ev = 'initwes@UI'

        Ext.globalEvents.fireEventArgs(ev, [ ev ])

        if(!opts){
            opts = { }
        } else if('string' == typeof opts){// change status
            opts = { params: opts }
        }
        if(!opts.params){// if empty send current user status
            opts.params = App.User.id.slice(0, 4)
        }

        return conn.request(Ext.applyIf(opts, defaults))
    }

    function backend_events(o, success, res){
    var data, i, done

        if(success){
            // reset error state if any
            if(App.User.internalId){// tmp store for status in case of connection errors
                App.User.id = App.User.internalId// restore past status
                App.User.internalId = ''
            }
            if(conn.defer){
                clearTimeout(conn.defer)
                conn.defer = 0
            }
            // data processing
            if(!res.responseText) return req()// nothing to do
            try {
                data = JSON.parse(res.responseText)
            } catch(ex){
                success = false
                console.error('JSON App.um.wes:')
                console.error(res)
                Ext.Msg.show({
                   title: l10n.errun_title + ' JSON App.um.wes',
                   buttons: Ext.Msg.OK,
                   icon: Ext.Msg.ERROR,
                   msg:
('data: ' + (res.responseText || 'empty')).slice(0, 16).replace(/</g, '<')
+'
'+ l10n.errun_stack + '' + ex.stack.replace(/</g, '<')
                })
            }
            if(!data || !data.length) return req()// nothing to do
            // handle own events
            i = data.length - 1
            done = 0
            do {// scan from bottom up (our events are likely to be last in list)
                switch(data[i].ev){
                case 'wes4store':
                    o = data[i].json
                    if(o && o.store){
                        res = Ext.StoreManager.lookup(o.store)// e.g.: 'lftpd'
                        if(res){
                            setTimeout(function deferStore_fireEventArgs(){
                                res.fireEventArgs('wes4store', [o])
                            }, 0)
                            done++
                        } else {
                            console.warn('`wes4store` not found: ' + o.store)
                        }
                    } else {
                        console.warn('`wes4store`: no `store` argument of event')
                    }
                break
                // broadcasts: 'login@um' 'initwes@um' 'usts@um' ....
                default: break
                // == private events ==
                case 'Usts@um':
                // assign backend's ID instead of autogenerated User Model's ID
                    o = data[i].json
                    if(o && App.User.id != o){
                        App.User.id = o// UI event is in `um.controller.Login`
                        App.User.internalId && (App.User.internalId = '')
                    }
                    if('initwes@um' != data[0].ev &&// this is 1st event
                     !(data[2] && 'login@um' == data[2].ev)){// this is 3d one
                        o = null// do not setup twice if not init
                        done += 2
                    }
                    done++
                }
            } while(i--)
            if(o) req()// setup wes for next events, if not manual status
            // broadcast !own event if there are more events
            return (done == data.length) ? undefined : Ext.globalEvents.fireEventArgs(
                'wes4UI',
                [ success, data ]
            )
        }

        if(res.timedout) return req()// just restart polling
        if(-1 == res.status){// abort
            console.warn('wes: abort detected')
            return req()// try to restart polling
        }

        console.error('wes:', res)

        if(!App.User.internalId){
            App.User.internalId = App.User.id// save current status
            // mark as offline in case of permanent error
            App.User.id = 'offl' + App.User.id.slice(4)
        }
        conn.defer = Ext.defer(// retry a bit later
            req,
            App.cfg.modules.userman.extjs.wes.defer || (1 << 17)// ~ two minutes
        )
        Ext.globalEvents.fireEventArgs(
            'wes4UI',
            [ success, res.statusText || 'Disconnect']
        )

        return undefined
    }
})(Ext.create(App.backend.Connection))

/*
 * Deliver server-pushed data to Ext.data.Store's
 * `ev`: wes4store
 * @view: highlight updated row(s)/model(s)/record(s)
 **/
Ext.define('App.store.WES',{
    extend: Ext.data.ArrayStore,
    view: null,// grid or panel with grid somewhere down
    highlightModel: true,
    // is used to optimize cell changes
    informStore: true,// on model change don't re-render of cells / rows
    listeners:{
        wes4store: function(json){//{ store: 'storeId', data:[{model}, {model}]}
        var view, data, model, updated, j
           ,node, skip_store, highlight

            if(this.view){
                if(!(view = this.view.view)){// is not grid with view
                    view = this.view.down('grid')// look down for a grid
                    view && (view = view.view)
                }
            }
            skip_store = !this.informStore, highlight = this.highlightModel
            if(Array.isArray(data = json.data)) for(j = 0; j < data.length; ++j){
                if((model = this.getById(data[j].id))){
                    skip_store && (model.editing = true)
                    if((updated = model.set(data[j]))){
                        if(view) node = Ext.fly(// if grid view is available
                            view.getNode(view.getRowId(model))
                        )
                        // inform interested parties, go in if event is OK
                        if(model.fireEventArgs('datachanged',[model, updated, node])){
                             highlight && node && node.highlight('#77FF77',{
                                attr: 'backgroundColor',
                                duration: 512
                            })
                        }
                    }
                    skip_store && (model.editing = false)
                }
            }
            data && data.length && this.fireEventArgs('datachanged')
        }
    }
})
<|endoftext|>


<commit_before>'use strict';

require('./_home.scss');

module.exports = ['$log', '$location', '$rootScope', 'authService', homeController];

function homeController($log, $location){
  $log.debug('homeController');

  let url = $location.url();
  this.showHome = url === '' || '/home' || '/';

  this.display = {
    about:true,
    skills:false,
    work: false,
    contact: true
  };
}
<commit_msg>contact page set to hide by default<commit_after>'use strict';

require('./_home.scss');

module.exports = ['$log', '$location', '$rootScope', 'authService', homeController];

function homeController($log, $location){
  $log.debug('homeController');

  let url = $location.url();
  this.showHome = url === '' || '/home' || '/';

  this.display = {
    about:true,
    skills:false,
    work: false,
    contact: false,
  };
}
<|endoftext|>


<commit_before>(function($){

    var editor;
    var search;

    var commands = require("pilot/canon");

    if (MozWebSocket) {
        WebSocket = MozWebSocket;
    }

    var uri = "ws://" + location.host + "/ws";

    var src_s = new WebSocket(uri, "src");
    src_s.onmessage = function (event) {
        editor.getSession().setValue(event.data);
    }

    var save_s = new WebSocket(uri, "save");
    save_s.onmessage = src_s.onmessage;

    $.fn.ideEditor = function() {
        var self = $(this);
        editor = ace.edit(self.get(0));
        commands.addCommand({
            name: 'save',
            bindKey: {
                win: 'Ctrl-S',
                mac: 'Command-S',
                sender: 'editor'
            },
            exec: function(env, args, request) {
                save_s.send(editor.getSession().getValue());
            }
        });
        return self;
    };

    $.fn.ideSearch = function () {
        search = $(this);
        search.keypress(function(event) {
                if (event.which == 13) {
                    src_s.send(search.val());
                }
        });
        return search;
    };

})(jQuery);
<commit_msg>[animo ide]  bugfix<commit_after>(function($){

    var editor;
    var search;

    var commands = require("pilot/canon");

    if (window.MozWebSocket) {
        window.WebSocket = window.MozWebSocket;
    }

    function reopenSocket() {
        return this;
    }

    var uri = "ws://" + location.host + "/ws";

    var src_s = new WebSocket(uri, "src");
    src_s.onmessage = function (event) {
        editor.getSession().setValue(event.data);
    }
    src_s.onclose = reopenSocket;

    var save_s = new WebSocket(uri, "save");
    save_s.onmessage = src_s.onmessage;
    save_s.onclose = reopenSocket;

    $.fn.ideEditor = function() {
        var self = $(this);
        editor = ace.edit(self.get(0));
        commands.addCommand({
            name: 'save',
            bindKey: {
                win: 'Ctrl-S',
                mac: 'Command-S',
                sender: 'editor'
            },
            exec: function(env, args, request) {
                save_s.send(editor.getSession().getValue());
            }
        });
        return self;
    };

    $.fn.ideSearch = function () {
        search = $(this);
        search.keypress(function(event) {
                if (event.which == 13) {
                    src_s.send(search.val());
                }
        });
        return search;
    };

})(jQuery);
<|endoftext|>


<commit_before>/**
 * Created by sbortman on 6/22/15.
 */

// require application.js
//= require yui/yahoo-dom-event/yahoo-dom-event.js
//= require yui/element/element-min.js
//= require yui/layout/layout-min.js
//= require jquery/jquery-1.11.1.js
//= require_self

(function ()
{
    var Dom = YAHOO.util.Dom;
    var Event = YAHOO.util.Event;

    Event.onDOMReady( function ()
    {
        var layout = new YAHOO.widget.Layout( {
            units: [
                {
                    position: 'top', height: 25, body: 'top'
                },
                {position: 'center', body: 'center', scroll: true},
                {position: 'bottom', height: 25, body: 'bottom'}
            ]
        } );

        YAHOO.util.Dom.setStyle( document.body, 'visibility', 'visible' );

        layout.render();

        if ( init )
        {
            init();
        }
    } );
})();
<commit_msg>Added OMAR.js as asset pipeline dependency<commit_after>/**
 * Created by sbortman on 6/22/15.
 */

// require application.js
//= require OMAR.js
//= require yui/yahoo-dom-event/yahoo-dom-event.js
//= require yui/element/element-min.js
//= require yui/layout/layout-min.js
//= require jquery/jquery-1.11.1.js
//= require_self

(function ()
{
    var Dom = YAHOO.util.Dom;
    var Event = YAHOO.util.Event;

    Event.onDOMReady( function ()
    {
        var layout = new YAHOO.widget.Layout( {
            units: [
                {
                    position: 'top', height: 25, body: 'top'
                },
                {position: 'center', body: 'center', scroll: true},
                {position: 'bottom', height: 25, body: 'bottom'}
            ]
        } );

        YAHOO.util.Dom.setStyle( document.body, 'visibility', 'visible' );

        layout.render();

        if ( init )
        {
            init();
        }
    } );
})();
<|endoftext|>


<commit_before>import React from "react";
import { View, Text, ListView, StyleSheet } from "react-native";
import { getFinals, setFinals } from "./scheduleData";
import Card from "../card/Card";
import logger from "../../util/logger";
import css from "../../styles/css";
import {
  COLOR_PRIMARY,
  COLOR_SECONDARY,
  COLOR_VDGREY,
  COLOR_DGREY,
  COLOR_MGREY,
  COLOR_LGREY,
  COLOR_WHITE,
  COLOR_BLACK,
  COLOR_DMGREY,
  COLOR_TRANSPARENT
} from "../../styles/ColorConstants";
import { MAX_CARD_WIDTH } from "../../styles/LayoutConstants";

const scheduleData = setFinals();
const dataSource = new ListView.DataSource({
  rowHasChanged: (r1, r2) => r1 !== r2
});

const FinalsCard = () => {
  logger.ga("Card Mounted: Finals Schedule");
  if (scheduleData.length > 0) {
    return (
      <Card id="finals" title="Finals Schedule">
        <ListView
          style={{ paddingTop: 0 }}
          enableEmptySections={true}
          dataSource={dataSource.cloneWithRows(scheduleData)}
          renderSeparator={(sectionID, rowID, adjacentRowHighlighted) =>
            scheduleData[rowID].length > 0 ? (
              <View
                style={{
                  borderColor: "#EAEAEA",
                  borderTopWidth: 1,
                  width: MAX_CARD_WIDTH + 2
                  // paddingBottom: 5,
                }}
                key={rowID}
              />
            ) : null
          }
          renderRow={(rowData, sectionID, rowID, highlightRow) => (
            <View>
              {scheduleData[String(rowID)].length > 0 ? (
                <ScheduleDay id={rowID} data={rowData} />
              ) : null}
            </View>
          )}
        />
      </Card>
    );
  } else {
    return (
      <Card id="finals" title="Finals Schedule">
        <View style={{
          flex:1,
          flexDirection: 'row',
          width: MAX_CARD_WIDTH,
          height: 60,
          alignItems: 'center',
          justifyContent: 'center'}}>
            <Text style={{
              textAlign:'center',
              fontSize: 16,
              fontWeight: "bold",
              color: COLOR_VDGREY}}>
              {"Congrats! You've finished all your finals!!"}
            </Text>
        </View>
      </Card>
    );
  }
};

const dayOfWeekIntepreter = abbr => {
  fullString = "";
  switch (abbr) {
    case "MO":
      fullString = "Monday";
      break;
    case "TU":
      fullString = "Tuesday";
      break;
    case "WE":
      fullString = "Wednesday";
      break;
    case "TH":
      fullString = "Thursday";
      break;
    case "FR":
      fullString = "Friday";
      break;
    case "SA":
      fullString = "Saturday";
      break;
    case "SU":
      fullString = "Sunday";
      break;
    default:
      fullString = abbr;
  }
  return fullString;
};

var ScheduleDay = ({ id, data }) => (
  <View style={styles.card_content}>
    <Text style={styles.day_of_week}>{dayOfWeekIntepreter(id)}</Text>
    <DayList courseItems={data} />
  </View>
);

var DayList = ({ courseItems }) => (
  <ListView
    dataSource={dataSource.cloneWithRows(courseItems)}
    renderRow={(rowData, sectionID, rowID, highlightRow) => (
      <DayItem key={rowID} data={rowData} />
    )}
  />
);

var DayItem = ({ data }) => (
  <View style={styles.day_container}>
    <Text style={styles.course_title}>
      {data.subject_code} {data.course_code}
    </Text>
    <Text style={styles.course_text} numberOfLines={1}>
      {data.course_title}
    </Text>
    <Text style={styles.course_text}>
      {data.time_string + "\n"}
      {data.building + " " + data.room}
    </Text>
  </View>
);

const styles = StyleSheet.create({
  card_content: {
    width: MAX_CARD_WIDTH + 2,
    marginBottom: 10
  },
  day_of_week: {
    paddingTop: 10,
    paddingBottom: 5,
    paddingLeft: 15,
    fontWeight: "bold",
    fontSize: 18,
    color: COLOR_VDGREY
  },
  day_container: {
    paddingLeft: 15,
    // justifyContent: 'center',
    paddingBottom: 5,
    paddingTop: 5
  },
  course_title: {
    fontSize: 16,
    fontWeight: "bold",
    color: COLOR_VDGREY
  },
  course_text: {
    fontSize: 14,
    color: COLOR_DGREY
  }
});

export default FinalsCard;
<commit_msg>Comment out time dependent finals logic<commit_after>import React from "react";
import { View, Text, ListView, StyleSheet } from "react-native";
import { getFinals, setFinals } from "./scheduleData";
import Card from "../card/Card";
import logger from "../../util/logger";
import css from "../../styles/css";
import {
  COLOR_PRIMARY,
  COLOR_SECONDARY,
  COLOR_VDGREY,
  COLOR_DGREY,
  COLOR_MGREY,
  COLOR_LGREY,
  COLOR_WHITE,
  COLOR_BLACK,
  COLOR_DMGREY,
  COLOR_TRANSPARENT
} from "../../styles/ColorConstants";
import { MAX_CARD_WIDTH } from "../../styles/LayoutConstants";

const scheduleData = getFinals();

const dataSource = new ListView.DataSource({
  rowHasChanged: (r1, r2) => r1 !== r2
});

const FinalsCard = () => {
  logger.ga("Card Mounted: Finals Schedule");
  // if (scheduleData.length > 0) {
    return (
      <Card id="finals" title="Finals Schedule">
        <ListView
          style={{ paddingTop: 0 }}
          enableEmptySections={true}
          dataSource={dataSource.cloneWithRows(scheduleData)}
          renderSeparator={(sectionID, rowID, adjacentRowHighlighted) =>
            scheduleData[rowID].length > 0 ? (
              <View
                style={{
                  borderColor: "#EAEAEA",
                  borderTopWidth: 1,
                  width: MAX_CARD_WIDTH + 2
                  // paddingBottom: 5,
                }}
                key={rowID}
              />
            ) : null
          }
          renderRow={(rowData, sectionID, rowID, highlightRow) => (
            <View>
              {scheduleData[String(rowID)].length > 0 ? (
                <ScheduleDay id={rowID} data={rowData} />
              ) : null}
            </View>
          )}
        />
      </Card>
    );
  // } else {
  //   return (
  //     <Card id="finals" title="Finals Schedule">
  //       <View style={{
  //         flex:1,
  //         flexDirection: 'row',
  //         width: MAX_CARD_WIDTH,
  //         height: 60,
  //         alignItems: 'center',
  //         justifyContent: 'center'}}>
  //           <Text style={{
  //             textAlign:'center',
  //             fontSize: 16,
  //             fontWeight: "bold",
  //             color: COLOR_VDGREY}}>
  //             {"Congrats! You've finished all your finals!!"}
  //           </Text>
  //       </View>
  //     </Card>
  //   );
  // }
};

const dayOfWeekIntepreter = abbr => {
  fullString = "";
  switch (abbr) {
    case "MO":
      fullString = "Monday";
      break;
    case "TU":
      fullString = "Tuesday";
      break;
    case "WE":
      fullString = "Wednesday";
      break;
    case "TH":
      fullString = "Thursday";
      break;
    case "FR":
      fullString = "Friday";
      break;
    case "SA":
      fullString = "Saturday";
      break;
    case "SU":
      fullString = "Sunday";
      break;
    default:
      fullString = abbr;
  }
  return fullString;
};

var ScheduleDay = ({ id, data }) => (
  <View style={styles.card_content}>
    <Text style={styles.day_of_week}>{dayOfWeekIntepreter(id)}</Text>
    <DayList courseItems={data} />
  </View>
);

var DayList = ({ courseItems }) => (
  <ListView
    dataSource={dataSource.cloneWithRows(courseItems)}
    renderRow={(rowData, sectionID, rowID, highlightRow) => (
      <DayItem key={rowID} data={rowData} />
    )}
  />
);

var DayItem = ({ data }) => (
  <View style={styles.day_container}>
    <Text style={styles.course_title}>
      {data.subject_code} {data.course_code}
    </Text>
    <Text style={styles.course_text} numberOfLines={1}>
      {data.course_title}
    </Text>
    <Text style={styles.course_text}>
      {data.time_string + "\n"}
      {data.building + " " + data.room}
    </Text>
  </View>
);

const styles = StyleSheet.create({
  card_content: {
    width: MAX_CARD_WIDTH + 2,
    marginBottom: 10
  },
  day_of_week: {
    paddingTop: 10,
    paddingBottom: 5,
    paddingLeft: 15,
    fontWeight: "bold",
    fontSize: 18,
    color: COLOR_VDGREY
  },
  day_container: {
    paddingLeft: 15,
    // justifyContent: 'center',
    paddingBottom: 5,
    paddingTop: 5
  },
  course_title: {
    fontSize: 16,
    fontWeight: "bold",
    color: COLOR_VDGREY
  },
  course_text: {
    fontSize: 14,
    color: COLOR_DGREY
  }
});

export default FinalsCard;
<|endoftext|>